ADR-0172 : Labellisation des données et affinage des modèles : Label Studio et LLaMA-Factory dans le catalogue
- Statut : accepté
- Date : 2026-11-02
- Portée : catalogue du Navin Manager (
navin-manager/catalog/services/label-studio.yaml,navin-manager/catalog/services/llama-factory.yaml), registre des consoles, composants gérés - Documents liés : ADR-0101 (politique de licences), ADR-0168 (moteurs d'inférence vLLM et Ollama), ADR-0171
(installation durcie),
navin-manager/docs/fr/labeling-finetuning.md(guide)
Contexte
La plateforme sert des modèles (vLLM derrière LiteLLM) et les évalue (Opik, promptfoo, Ragas, garak), mais n'offrait ni la labellisation des données, ni la validation humaine des sorties des modèles, ni l'affinage des modèles publics et privés. Le client demande deux services, avec leur licence : Label Studio (Apache-2.0) pour la labellisation de textes, d'images, de sons et de vidéos, la validation humaine et la préparation des jeux de données ; LLaMA-Factory (Apache-2.0) pour l'affinage (SFT, LoRA, QLoRA, DPO) et la gestion des entraînements. Ils s'installent comme les autres services du catalogue : hors ligne, durcis selon l'ADR-0171, documentés en français et en anglais.
Décision
- Label Studio 1.23.2, édition Community, méthode
podman. Image officielleheartexlabs/label-studioépinglée par empreinte, deux composants comme ledocker-compose.ymldu projet :app(uwsgi) etnginx(fichiers statiques, relais vers l'application, médias). Pas de méthodepython:label-studio startdu paquet PyPI lance le serveur de développement de Django, et le paquet ne contient ni la configuration nginx ni l'entrée uwsgi de l'image. - État dans les services de la plateforme. Base PostgreSQL de la liaison
database, jamais SQLite ; médias et exports dans le compartiment S3 de la liaisons3(SeaweedFS par défaut), servis par nginx grâce àX-Accel-Redirect. Le point d'accès S3 de l'installation est le seul point d'accès interne de confiance (S3_ENDPOINT) ; la protection contre la falsification de requêtes côté serveur reste active pour les points d'accès saisis dans un projet, les imports par URL et les webhooks. - Sécurité de Label Studio. Réseau isolé du service,
--cap-drop ALL, utilisateur 1001 de l'image. Inscription sur invitation (LABEL_STUDIO_DISABLE_SIGNUP_WITHOUT_LINK), compte administrateur et clé secrète générés à l'installation et gardés dans le coffre, cookies sécurisés et origine CSRF derrière la passerelle HTTPS (public_url), télémétrie, rapports Sentry (DSN par défaut de l'image) et vérification de version coupés, fichiers locaux désactivés, autorités internes de confiance pour la base et le stockage (trusted_ca_pem). Le modereplicatedpartage la base, le compartiment et la clé : n'importe quelle réplique sert n'importe quel utilisateur, et seule la première application crée le premier compte. - LLaMA-Factory 0.9.5, méthode
podman. Pile PyTorch et CUDA de l'image officiellehiyouga/llamafactory, épinglée par empreinte. Une interface LLaMA Board (Gradio) par hôte GPU, GPU par CDI (nvidia.com/gpu), réseau isolé,--cap-drop ALL, hors ligne (HF_HUB_OFFLINE,TRANSFORMERS_OFFLINE,HF_DATASETS_OFFLINE), sans lien de partage public, sans statistiques Gradio, sans serveur MCP de Gradio, sans W&B. Modèles, jeux de données, configurations, entraînements et exports restent dans/var/lib/navin/llama-factoryde l'hôte. - Entraînements pilotés par le Manager. Commandes
download_model(cache Hugging Face, miroir interne),trainetexport(configurations YAML relues du dossierconfigs, lancées en arrière-plan avec leur journal),runs,run_log,env,gpu_status. Un paramètre n'entre jamais dans le texte d'un script : il est passé en argument, et son motif refuse les caractères du shell et les chemins. - Mise en service d'un modèle affiné. L'export fusionne l'adaptateur dans son modèle de base ; le dossier
exporté est importé dans
models/locald'un hôte vLLM (model_source: local), que LiteLLM enregistre par sa liaison. Les agents n'appellent jamais LLaMA-Factory. - Console sans authentification. LLaMA Board n'a pas d'authentification : sa console est déclarée sans authentification et avec des ressources externes (polices Google de Gradio) ; les contrôles des consoles ne l'ouvrent en production qu'à travers la passerelle authentifiante.
- Licences. Apache-2.0 pour les deux (ADR-0101). Les bibliothèques CUDA de l'image LLaMA-Factory relèvent de LEX-011 comme celles de vLLM ; les poids affinés gardent la licence de leur modèle de base (LEX-012).
Alternatives écartées
- Label Studio avec SQLite : un seul serveur, aucune réplique, état sur l'hôte, contraire à la haute disponibilité et à la sauvegarde de la plateforme.
- Stockage local des médias de Label Studio : il faudrait un volume partagé entre les hôtes ; le compartiment S3 de la plateforme le remplace.
- Entraînement multi nœud de LLaMA-Factory (torchrun entre hôtes) : NCCL demande le réseau de l'hôte et des ports dynamiques ; écarté tant que le besoin n'est pas démontré (ADR-0171).
- Méthode
pythonpour LLaMA-Factory : la pile PyTorch, CUDA, flash-attn et DeepSpeed dépend du pilote et de la version de CUDA ; l'image officielle la fige. - Label Studio Enterprise (rôles, SSO, relecture) : licence commerciale, hors de la politique de licences.
Conséquences
Le catalogue compte 51 services. Label Studio demande PostgreSQL et un stockage S3 (SeaweedFS de la plateforme par défaut). LLaMA-Factory demande un hôte GPU NVIDIA (pilote, NVIDIA Container Toolkit et spécification CDI), 16 Go de mémoire au moins et de l'espace disque pour les modèles. L'édition Community de Label Studio n'a pas de rôles : l'accès se contrôle par l'invitation et la passerelle.
Complément du 2 novembre 2026 (LLM et VLM, QLoRA, DPO) : LLaMA-Factory affine aussi les modèles de vision (Qwen3-VL,
par exemple) sur des jeux sharegpt à images ou vidéos, que Label Studio prépare comme les préférences du DPO
(comparaison Pairwise). L'image officielle n'embarque pas bitsandbytes, nécessaire à QLoRA : la commande
install_qlora installe bitsandbytes 0.50.2 (MIT), roue vérifiée par son sha256 épinglé, dans un dossier de l'hôte
monté en lecture seule dans l'interface (PYTHONPATH), depuis le dossier wheels de l'hôte ou l'index Python du
service. L'image reste celle de l'éditeur, épinglée par son empreinte : aucune image n'est reconstruite. Le paramètre
vision de vLLM déclare le VLM servi à LiteLLM (supports_vision).
Complément du 2 novembre 2026 (service par vLLM ou Ollama) : les commandes publish_to_vllm et publish_to_ollama
de LLaMA-Factory copient un export fusionné dans les poids importés de vLLM (model_source: local) ou dans le dossier
d'import d'Ollama du même hôte, sans jamais écraser un dossier ; la nouvelle commande import_safetensors d'Ollama
fait de ce dossier un modèle sur chaque instance, publié dans LiteLLM par litellm_models. Les noms sont des
arguments positionnels ou des variables d'environnement, jamais une partie d'un script, et leur motif refuse les
chemins.
Preuves
navin-manager/server/tests/test_catalog_labeling_finetuning.py, navin-manager/server/tests/test_catalog.py,
navin-manager/server/tests/test_consoles.py, navin-manager/server/tests/test_console_credentials.py,
services/control-plane/tests/test_functional_catalog_coverage.py,
services/control-plane/tests/test_platform_components.py, navin-manager/server/tests/test_catalog_inference.py.