VLM-R1 : entraîner un VLM par renforcement, avec GRPO et des récompenses de format
Solve Visual Understanding with Reinforced VLMs
En bref
- De quoi s’agit-il ?
- VLM-R1 applique le schéma R1 (GRPO, récompenses vérifiables) à la compréhension visuelle, principalement sur la détection d'expressions référentielles et la détection ouverte. Le dépôt est un cadre d'entraînement, pas une bibliothèque prête à l'emploi.
- À qui s’adresse-t-il ?
- À adopter si vous disposez déjà d'un pipeline d'entraînement distribué et d'un jeu de données au format JSONL avec des réponses vérifiables, et que vous voulez comparer GRPO à un SFT sur des données hors domaine. À éviter si vous cherchez une API d'inférence : le dépôt est un cadre d'entraînement, et le support d'un nouveau VLM passe par l'écriture d'un module dédié.
- Puis-je l’utiliser commercialement ?
- Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 71 jours.
- En quel langage est-il écrit ?
- Principalement Python, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème visé : la généralisation hors domaine en détection visuelle
Le point de départ est un constat sur l'affinage supervisé. Le README décrit une comparaison entre SFT et R1 sur la tâche de Referring Expression Comprehension (REC), avec Qwen2.5-VL comme modèle de base. Sur les données de test du domaine d'entraînement, les deux approches évoluent peu entre 100 et 600 étapes. Sur des données hors domaine, la performance du modèle SFT se dégrade légèrement à mesure que les étapes augmentent, tandis que le modèle entraîné par renforcement transfère sa capacité de raisonnement. C'est cet écart que le projet cherche à exploiter. Le public visé est donc étroit : des équipes qui entraînent des VLM pour la localisation d'objets ou de régions, et qui ont déjà constaté que le SFT ne tient pas sur des distributions différentes. VLM-R1 ne prétend pas améliorer l'inférence d'un modèle figé, ni fournir un service. C'est un cadre d'entraînement, avec des scripts et des modules de modèles, pas une bibliothèque que l'on appelle depuis une application.
GRPO, récompenses vérifiables et le paramètre is_reward_customized_from_vlm_module
Le mécanisme central est GRPO, l'algorithme d'optimisation par renforcement popularisé par DeepSeek-R1. L'idée sous-jacente est qu'une réponse peut être notée sans modèle de récompense appris : pour la détection, la sortie est une boîte englobante, donc une correspondance géométrique avec la vérité terrain suffit à produire un signal. Le README mentionne trois récompenses ajoutées le 2025-04-03 pour la tâche de détection ouverte (OVD) : odLength, weighted_sum et cosine, avec un renvoi vers grpo_jsonl.py pour l'implémentation. La mise à jour du 2025-04-16 introduit un paramètre de configuration, is_reward_customized_from_vlm_module. Quand il vaut true, la logique de récompense est déléguée au module du modèle, soit QwenVL2Module, soit InternVLModule selon le VLM choisi. C'est un choix d'architecture qui a des conséquences : la fonction de récompense n'est plus centralisée dans le script d'entraînement mais dispersée dans des modules spécifiques à chaque famille de modèles. Pour ajouter un nouveau VLM, il faut donc écrire un module et y définir la récompense, ce que le dépôt documente dans assets/add_new_model.md. La REC a par ailleurs été intégrée dans grpo_jsonl.py pour unifier l'implémentation entre tâches.
Ce que contiennent réellement les scripts run_scripts
Le dépôt est organisé autour de scripts shell dans run_scripts/. Le README en liste cinq, chacun correspondant à un mode d'entraînement : run_grpo_rec.sh pour le fine-tuning complet avec GRPO, run_grpo_rec_lora.sh pour la variante LoRA, multinode_training_demo.sh pour le multi-nœuds, run_grpo_gui.sh pour l'entrée multi-images. Une option freeze_vision_modules, à passer à true dans le script, gèle les modules de vision. Le code d'entraînement lui-même vit dans src/open-r1-multimodal/src/open_r1/, avec grpo_jsonl.py comme point d'entrée et un sous-répertoire vlm_modules/ pour les adaptateurs de modèles. L'évaluation de la REC se trouve dans src/eval/test_rec_r1.py. Deux familles de VLM sont prises en charge à ce jour, QwenVL et InternVL. Le format de données attendu est du JSONL, et le README renvoie à une section For your own data pour la mise au format, y compris pour l'entrée multi-images. Aucun exemple de ligne JSONL n'apparaît dans l'extrait de README fourni : c'est la première chose à aller lire dans le dépôt avant de préparer vos données.
Le coût d'entrée : GPU, nœuds et absence de recette de démarrage rapide
Le README ne documente aucune procédure d'installation pas à pas. Il n'y a ni commande pip install, ni fichier de dépendances mentionné dans l'extrait, ni exemple minimal d'exécution locale. Le plus petit point d'entrée visible est un script shell qui lance un entraînement GRPO complet, ce qui suppose une infrastructure GPU déjà en place. Le script multinode_training_demo.sh indique que le passage à plusieurs nœuds est prévu, mais il ne s'agit que d'une démonstration. Les mises à jour d'août 2025 portent sur l'inférence sur matériel Huawei Ascend (Atlas 800T A2, Atlas 300I Duo) via vllm-ascend, puis via le framework xllm de JD, avec des chemins dédiés sous ascend_inference/. Le README annonce une réduction du TTFT de 50 % et une hausse du débit global de 127 % par rapport à vllm-ascend, chiffres attribués à cette optimisation. Ce sont des chiffres publiés par les auteurs, pas des mesures indépendantes. Pour un lecteur qui cherche à évaluer le coût matériel, la seule information fiable est que le projet suppose un entraînement distribué, et que la variante LoRA existe précisément pour réduire cette barrière.
Quand VLM-R1 n'est pas le bon outil
Trois cas de figure. D'abord, si votre tâche ne produit pas de réponse vérifiable automatiquement (une boîte englobante, une réponse mathématique courte), GRPO n'a rien à quoi s'accrocher et il faut revenir au SFT ou à un modèle de récompense appris, ce que le dépôt ne fournit pas. Ensuite, si votre besoin est d'appeler un VLM en production, le dépôt n'est pas fait pour cela : les démos Hugging Face référencées dans le README sont des vitrines, et les checkpoints publiés (VLM-R1-Qwen2.5VL-3B-OVD-0321, VLM-R1-Qwen2.5VL-3B-Math-0305) sont des poids, pas un serveur. Enfin, si vous devez supporter un VLM qui n'est ni QwenVL ni InternVL, le coût d'intégration est réel : il faut un module dans vlm_modules/ et, si la récompense est personnalisée, la logique associée. Le README signale aussi un piège méthodologique : les auteurs indiquent que des expériences SFT antérieures utilisaient une configuration de pixels incorrecte, ce qui a conduit à relancer l'étude. Un projet qui corrige publiquement ce type d'erreur est plus crédible, mais cela rappelle que comparer RL et SFT sur des données visuelles est sensible aux détails de prétraitement.
Face à open-r1-multimodal : même socle, récompense au niveau du module
Le nom même du répertoire, src/open-r1-multimodal/, indique la filiation : VLM-R1 est un dérivé du projet open-r1-multimodal, qui applique le schéma R1 aux modèles vision-langage. La différence tient à ce qui est ajouté par-dessus. open-r1-multimodal fournit le socle GRPO pour des tâches multimodales ; VLM-R1 y greffe des récompenses spécifiques à la détection (odLength, weighted_sum, cosine), un mécanisme de récompense déléguée au module du modèle via is_reward_customized_from_vlm_module, et une opération de post-redimensionnement des boîtes englobantes pour QwenVL, ajoutée le 2025-06-26 côté entraînement et côté évaluation. Ce dernier point est révélateur : la gestion des coordonnées de boîtes dans l'espace de pixels d'un VLM est un détail qui déplace les résultats, et VLM-R1 l'expose comme un correctif plutôt que comme un choix de conception. Si votre tâche est la détection ouverte ou la REC, l'écart avec le socle générique justifie de regarder VLM-R1. Si votre tâche est la description d'images ou le question-réponse visuel libre, l'apport spécifique est plus mince.
Maintenance, licence et ce qu'il faut vérifier avant de cloner
Le dépôt est actif : dernier push en juillet 2026, trois versions publiées entre mars et avril 2025 (v0.1.0, v0.2.0, v0.2.1), et un journal de mises à jour qui court jusqu'en août 2025 avec l'adaptation Ascend. La licence est Apache-2.0, ce qui autorise l'usage commercial et la modification, à condition de conserver les mentions de copyright et le fichier de licence, et d'indiquer les fichiers modifiés. Apache-2.0 contient aussi une clause de brevets. Cela dit, la licence du dépôt ne dit rien de celle des poids publiés sur Hugging Face ni de celle des données REC hébergées séparément : ce sont des artefacts distincts, à vérifier de leur côté. Sur le coût de mise à jour, le projet n'annonce pas de politique de compatibilité ascendante, et le passage de la REC dans grpo_jsonl.py lors de la mise à jour d'avril 2025 montre que l'organisation du code a déjà bougé une fois. Avant d'adopter, lisez le format JSONL attendu, vérifiez que votre VLM cible figure parmi les modules existants, et faites tourner run_grpo_rec_lora.sh sur un seul nœud pour mesurer la consommation mémoire réelle avant d'envisager le multi-nœuds.
Conclusion éditoriale
À adopter si vous disposez déjà d'un pipeline d'entraînement distribué et d'un jeu de données au format JSONL avec des réponses vérifiables, et que vous voulez comparer GRPO à un SFT sur des données hors domaine. À éviter si vous cherchez une API d'inférence : le dépôt est un cadre d'entraînement, et le support d'un nouveau VLM passe par l'écriture d'un module dédié. Avant de vous engager, vérifiez le format exact attendu par grpo_jsonl.py et testez le script LoRA sur un seul nœud pour mesurer le coût réel en mémoire.
Notes de la communauté