>_ DevTrendsfr

Langue

Accueil

Langages

Sections

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embarqué Sécurité
Python

Comment entraîner des modèles multimodaux lourds sans une ménagerie de scripts

Gemini_Generated_Image_s42giss42giss42g

Si vous avez déjà essayé de fine-tuner un modèle multimodal fraîchement sorti comme Qwen2.5-VL ou de réaliser un préentraînement d'un générateur vidéo basé sur la diffusion, vous vous souvenez probablement de ce sentiment de désespoir. Dans un dépôt, l'entraînement plante à cause de conflits de versions entre PyTorch et FlashAttention. Dans un autre, l'auteur a écrit un pipeline de données personnalisé qui charge 500 Go d'images directement en RAM. Dans un troisième, FSDP se fige complètement à la deuxième étape d'optimisation.

Chaque nouvelle architecture apporte son propre script d'entraînement, ses propres astuces pour économiser la mémoire, et ses propres contournements pour le parallélisme. L'équipe du laboratoire EvolvingLMMs-Lab a décidé de rassembler toute cette expérience dispersée en un seul endroit. C'est ainsi qu'est né le dépôt lmms-engine.

C'est un moteur modulaire pour l'entraînement évolutif de modèles multimodaux. Il gère le travail ingrat de l'entraînement distribué, du groupement de séquences et des optimisations de kernels de bas niveau, vous laissant avec juste une configuration et des données.

Ce qu'il contient et à qui c'est destiné

Le framework a été développé principalement pour les chercheurs et les ingénieurs ML travaillant avec des réseaux multimodaux volumineux. Alors que les LLMs textuels ordinaires peuvent être fine-tunés confortablement avec des outils comme Axolotl ou LLaMA-Factory, les images, l'audio et la vidéo sont une autre histoire.

Les entrées multimodales créent des longueurs de contexte massives. Une seule image haute résolution ou quelques secondes de vidéo se transforment facilement en dizaines de milliers de tokens visuels. À ce stade, le Data Parallel standard atteint rapidement les limites de mémoire GPU.

Le moteur résout ce problème grâce à une combinaison de techniques de parallélisme modernes et d'optimisations au niveau GPU. La liste des modèles supportés est impressionnante :

  • Modèles Vision-Langage : Qwen2.5-VL, Qwen3-VL, Qwen3-VL MoE, LLaVA-OneVision
  • MoE multimodal avec support audio et vidéo : Qwen2.5-Omni, Qwen3-Omni MoE, Aero
  • Architectures génératives et par diffusion : WanVideo (1.3B et 14B paramètres), SiT (Scalable Interpolant Transformers), dLLM
  • Systèmes universels de compréhension et génération d'images : BAGEL

Quatre solutions d'ingénierie sous le capot

Les créateurs du projet ont clairement été inspirés par l'idée de minimalisme : le code est écrit de manière compacte, sans magie abstraite inutile, en PyTorch pur avec des intégrations pour les bibliothèques de pointe.

1. FSDP2 et Parallélisme de Séquence Ulysses

Pour distribuer les poids, le moteur s'appuie sur la nouvelle implémentation du Fully Sharded Data Parallel v2 (FSDP2) basée sur DTensor. Contrairement à l'ancien FSDP, la deuxième version se compose beaucoup plus proprement avec d'autres types de parallélisme.

Quand 10 000+ tokens visuels arrivent dans le contexte, la mémoire GPU s'épuise instantanément. C'est là qu'intervient le Parallélisme de Séquence Ulysses (USP). Il divise la séquence de tokens entre plusieurs GPU au sein d'un même nœud. Dans la configuration, cela se règle avec une seule ligne :

trainer_args:
  sp_ulysses_degree: 2

2. Groupement de Séquences Sans Padding Inutile

Un mal de tête classique dans l'entraînement multimodal est la tailles variables des images et des textes dans un même batch. Si vous complétez les échantillons courts avec des tokens de padding, le GPU passe jusqu'à la moitié du temps sur des calculs zéro inutiles.

Les auteurs ont implémenté le first-fit bin packing en combinaison avec FlashAttention use_rmpad. Les données sont groupées en longues séquences denses sans temps d'inactivité. Selon les benchmarks des auteurs, lors du fine-tuning de Qwen2.5-VL, la métrique d'efficacité de calcul (MFU) passe de 20-25% à un impressionnant 35-40%.

dataset_config:
  packing: true
  packing_strategy: first_fit
  packing_length: 32000

trainer_args:
  use_rmpad: true
  use_liger_kernel: true

3. Optimiseur Muon et Kernels Triton de Liger

Au lieu du familier AdamW, le projet propose Muon. Cet optimiseur applique l'orthogonalisation de Newton-Schulz via des kernels Triton sur des matrices de poids 2D. Il converge plus rapidement que AdamW et nécessite moins de mémoire.

Dans le même temps, le moteur peut échanger à la volée les couches standard du modèle avec des kernels fusionnés de la bibliothèque Liger Kernel de LinkedIn. CrossEntropy, RMSNorm, RoPE et SwiGLU sont fusionnés en opérations uniques, réduisant d'environ 30% la consommation de VRAM de pointe sans perte de précision.

4. Chargement en Streaming de Datasets de Téraoctets

Charger des tableaux massifs de vidéos et d'images en mémoire avant le début d'une époque est impossible. Le pipeline de données dans lmms-engine est construit au-dessus de IterableDataset. Les données sont lues en flux à partir de formats Arrow, JSONL ou Parquet, donc l'entraînement commence immédiatement sans attendre l'indexation de fichiers de taille téraoctets.

Comment le Lancement et l'Extension Fonctionnent

L'installation du projet se fait correctement via le gestionnaire de paquets uv, bien que les auteurs fournissent également une image Docker prête à l'emploi avec CUDA, FlashAttention et les dépendances pré-installées.

git clone https://github.com/EvolvingLMMs-Lab/lmms-engine.git
cd lmms-engine
uv pip install -e ".[all]"
uv pip install flash-attn --no-build-isolation
uv pip install liger-kernel

L'entraînement démarre via torchrun standard :

torchrun --nproc_per_node=8 --nnodes=1 --node_rank=0 \
  --master_addr=127.0.0.1 --master_port=12355 \
  -m lmms_engine.launch.cli config_yaml=examples/qwen3_vl/example_config.yaml

Si vous avez besoin d'ajouter votre propre format de données spécifique ou un processeur de caractéristiques personnalisé, vous n'aurez pas à réécrire les internes du trainer. Le code utilise un pattern factory avec un enregistrement via des décorateurs :

from lmms_engine.datasets import register_dataset, BaseDataset

@register_dataset("my_custom_dataset")
class MyCustomDataset(BaseDataset):
    def __init__(self, config):
        super().__init__(config)

    def __getitem__(self, idx):
        # Ваша логика чтения картинки или видео
        return item

Où le Projet Brille le Mieux

Le moteur a été développé pour des scénarios lourds spécifiques :

  1. Fine-tuning de modèles vision-langage (Qwen2.5-VL, Qwen3-VL) sur de longs documents, scans de livres et captures d'écran d'interfaces.
  2. Entraînement d'architectures sparse Mixture-of-Experts avec distribution des experts sur les GPU (Expert Parallelism).
  3. Expériences avec la diffusion pour la génération vidéo basée sur les modèles WanVideo ou SiT.
  4. Préentraînement de modèles légers à attention récurrente et linéaire (FLA / DGN).

Cela vaut-il la peine d'essayer

Si votre tâche est de modifier rapidement LoRA sur un Llama textuel, lmms-engine pourrait sembler excessif. Mais si vous avez atteint un plafond de mémoire lors de l'entraînement de réseaux multimodaux, si vous en avez marre de lier manuellement FSDP2 avec de longues séquences vidéo, ou si vous voulez extraire le maximum de FLOPS de vos clusters existants, ce moteur vous fera gagner des semaines de codage.

Le moyen le plus simple de commencer est avec les scripts prêts à l'emploi dans le dossier examples/ : ils contiennent des configurations éprouvées en combat pour la plupart des architectures modernes.

Projets similaires