Entraînement LoRA avec Unsloth
Entraînez un LoRA sur un jeu de données au format chat avec Unsloth sur un GPU local et exportez le résultat en GGUF. Le jeu de données est celui de l'utilisateur (sa production dépend du problème) ; cette compétence part de train.jsonl et val.jsonl. Le déploiement du modèle est une étape séparée : le dossier de runs que cette compétence produit (GGUF + run.json) est ce qu'une compétence de déploiement telle que ollama-model prend en entrée.
Exécutez chaque script via le lanceur, avec l'outil Bash : ${CLAUDE_SKILL_DIR}/scripts/run <script.py> [args]. La compétence n'autorise que cette commande exacte, qui s'exécute ainsi en mode automatique ; appeler un script d'une autre manière sera refusé. Si une commande du lanceur est refusée après un nouveau message de l'utilisateur, invoquez à nouveau cette compétence. Le lanceur exécute check_data.py avec n'importe quel Python 3, et preflight.py, train.py et export_gguf.py avec le Python de l'environnement Unsloth, dans le dossier parent de leur dossier --out/--run (Unsloth écrit un dossier unsloth_compiled_cache/ dans le répertoire courant). Donnez chaque chemin sous forme de chemin absolu : les commandes ne partagent pas de répertoire de travail.
Avant de commencer, déterminez
- Le dossier du jeu de données, et l'ensemble d'évaluation utilisé ultérieurement pour comparer les modèles : il ne doit pas faire partie de l'entraînement. S'il n'y en a pas, proposez de mettre de côté des exemples avant l'entraînement.
- Le(s) modèle(s) de base, sous forme de noms Unsloth 4 bits (par ex.
unsloth/Qwen2.5-Coder-3B-Instruct-bnb-4bit). Plusieurs modèles de base signifient un dossier de runs par modèle et les mêmes étapes pour chacun, l'une après l'autre (references/base-models.md). - La machine : l'entraînement nécessite un GPU CUDA et le Python de l'environnement Unsloth. Demandez à l'utilisateur le chemin de ce Python si
UNSLOTH_PYTHONn'est pas défini et que~/.config/llm-finetune/unsloth-pythonn'existe pas, puis écrivez le chemin comme première ligne de ce fichier (avec son accord) : le lanceur le lira à partir de là. - Le dossier des runs, où iront les dossiers de runs, en dehors de tout checkout git.
<runs>ci-dessous correspond à son chemin absolu.
Étapes
1. Vérifiez les données
${CLAUDE_SKILL_DIR}/scripts/run check_data.py <data> --eval <eval.jsonl>
Doit afficher ok. Il échoue en cas de lignes cassées, de conversations qui ne se terminent pas par une réponse de l'assistant, et de prompts de validation ou d'évaluation également présents dans l'entraînement, avec une réponse identique ou différente : le modèle les a vus, ils mesurent donc le rappel. La correction consiste à les retirer de la validation ou de l'évaluation (ou à corriger la façon dont les données sont divisées), jamais à modifier l'entraînement pour faire passer la vérification. Il rapporte également comment les messages système sont utilisés : aucun, un seul partagé, ou mélangé (voir references/chat-formats.md).
2. Pré-vérifiez la machine
${CLAUDE_SKILL_DIR}/scripts/run preflight.py --params-b <milliards de paramètres> --out <runs>/<run>
La mémoire GPU libre est plus importante que la mémoire totale : les jeux, un navigateur avec accélération GPU, ou un modèle encore conservé par un serveur local (ollama ps, décharger avec ollama stop <modèle>) peuvent en laisser trop peu. Si la pré-vérification liste d'autres utilisateurs du GPU, informez l'utilisateur et laissez-le décider, ne tuez pas de processus. Avec --params-b, il estime le besoin (un modèle 3B en 4 bits a culminé à 6,6 Gio avec une longueur de séquence de 1024 et une taille de lot de 4, un 7B à 8,1 Gio) et, lorsque la mémoire libre est insuffisante, affiche la paire --batch-size/--grad-accum à utiliser à la place. Il s'agit d'une estimation à partir de deux exécutions : pour d'autres tailles ou longueurs de séquence, passez --need-gib et surveillez le pic rapporté par l'exécution de test.
Si une importation échoue, l'environnement est défectueux, voir references/troubleshooting.md avant de réinstaller quoi que ce soit.
3. Exécution de test
${CLAUDE_SKILL_DIR}/scripts/run train.py --model <base> --data <data> --out <runs>/<run>-smoke --max-steps 2
Lisez la sortie, ne vérifiez pas seulement le code de sortie :
- le premier exemple tel qu'affiché : la ligne système en haut est ce que le modèle apprendra à attendre,
- les tokens qui reçoivent une perte : seulement la réponse, pas la question,
- les longueurs de tokens : un avertissement de troncature signifie qu'il faut augmenter
--max-seq-lengthou supprimer des exemples, - le tour système qu'un serveur doit envoyer, et les avertissements à son sujet. Un template de réflexion (Qwen3, Qwen3.5) place un bloc
réponse de réflexionvide devant chaque réponse entraînée : informez l'utilisateur que l'application le recevra dans les réponses et devra le supprimer.
4. Exécution complète
${CLAUDE_SKILL_DIR}/scripts/run train.py --model <base> --data <data> --out <runs>/<run>
S'exécute pendant un certain temps (minutes pour quelques milliers d'exemples sur un modèle 3B, plus longtemps pour un 7B). Lancez-la avec l'option d'arrière-plan de l'outil Bash plutôt que de garder une session ouverte (l'outil conserve la sortie dans un fichier, c'est le journal : n'ajoutez pas >, ; ou && à la commande, la pré-approbation couvre la commande du lanceur exactement comme indiqué), et vérifiez-la avec ${CLAUDE_SKILL_DIR}/scripts/run train_status.py <runs>/<run> : étape, pertes, l'étape avec la perte de validation la plus basse et le temps restant, d'après le dernier point de contrôle. Après un plantage, utilisez --resume.
Rapportez la perte d'entraînement et de validation ainsi que le pic de mémoire GPU. Une perte de validation nettement supérieure à la perte d'entraînement indique un surapprentissage : moins d'époques ou plus de données.
5. Exportation
${CLAUDE_SKILL_DIR}/scripts/run export_gguf.py --run <runs>/<run>
Prend quelques minutes pour un modèle 3B et plus de dix pour un 7B (fusion, conversion, quantification), ce qui dépasse la durée pendant laquelle l'outil Bash laisse une commande au premier plan : lancez-la en arrière-plan comme l'entraînement et attendez qu'elle se termine. Elle écrit le GGUF dans <run>/gguf/ et l'enregistre dans run.json avec sa taille et sa somme de contrôle. Elle supprime le modèle fusionné 16 bits (plusieurs Go, --keep-merged le conserve, et alors le GGUF reste dans <run>/gguf_gguf/) ainsi que le Modelfile qu'Unsloth écrit à côté du GGUF : celui-ci utilise le template standard, pas la disposition utilisée lors de l'entraînement, donc ne suivez pas l'indication d'Unsloth de faire ollama create à partir de celui-ci. Attendez-vous à un avertissement [CRITICAL] concernant le convertisseur de llama.cpp à chaque exportation ; expliquez à l'utilisateur ce qu'il signifie (references/troubleshooting.md), cela n'arrête pas l'exportation. Le dossier de runs est maintenant prêt pour le déploiement : continuez avec la compétence ollama-model, ou transmettez la section chat de run.json à ce qui sert le modèle (references/run-json.md).
6. Nettoyage (demandez d'abord)
Une fois le modèle exporté et évalué, proposez de supprimer ce qui n'est nécessaire que pour reprendre ou vérifier la configuration : <run>/checkpoints/ (pour --resume, plusieurs Go pour un modèle 7B) et le dossier <run>-smoke. Indiquez l'espace occupé par chacun et ne supprimez que ce que l'utilisateur accepte. Conservez adapter/ et run.json : ils sont petits et sont nécessaires pour une nouvelle exportation et les notes de version.
Règles
- Ne modifiez jamais le jeu de données pour améliorer l'évaluation et n'évaluez jamais sur des données d'entraînement.
- N'installez ni ne mettez à jour de paquets dans l'environnement Unsloth sans demander : sa combinaison torch/CUDA est fragile.
- Demandez avant de supprimer des dossiers de runs ou des points de contrôle.