
Les problèmes de génération de code diffèrent des problèmes courants de langage naturel - ils nécessitent de correspondre à la syntaxe exacte du langage cible, d'identifier les chemins heureux et les cas limites, de prêter attention à de nombreux petits détails dans la spécification du problème, et d'aborder d'autres questions et exigences spécifiques au code. Par conséquent, bon nombre des optimisations et des astuces qui ont fait leurs preuves dans la génération de langage naturel peuvent ne pas être efficaces pour les tâches liées au code.
Des développeurs proposent une nouvelle approche de la génération de code par les LLM, appelé AlphaCodium - un flux itératif basé sur des tests, en plusieurs étapes et orienté vers le code, qui améliore les performances des LLM sur les problèmes de code.
Ils ont testé AlphaCodium sur un ensemble de données de génération de code difficile appelé CodeContests, qui comprend des problèmes de programmation compétitifs provenant de plateformes telles que Codeforces. Le flux proposé améliore les résultats de manière cohérente et significative. Sur l'ensemble de validation, par exemple, la précision du GPT-4 (pass@5) est passée de 19 % avec une seule invite directe bien conçue à 44 % avec le flux AlphaCodium.
Ils pensent que bon nombre des principes et des meilleures pratiques acquises dans le cadre de leur travail sont largement applicables aux tâches générales de génération de code.
Voici le classement de AlphaCodium avec les scores des nouveaux modèles GPT, et Claude3 Opus. "GPT-4o" est actuellement le modèle leader sur AlphaCodium.
Installation d'AlphaCodium
1. Configurer un environnement virtuel
Code : | Sélectionner tout |
1 2 | python3 -m venv venv source ./venv/bin/activate |
2. Dupliquez le fichier alpha_codium/settings/.secrets_template.toml, renommez-le en alpha_codium/settings/.secrets.toml, et indiquez votre clé API OpenAI :
Code : | Sélectionner tout |
1 2 | [openai] key = "..." |
Comment exécuter
Configuration
Le fichier : alpha_codium/settings/configuration.toml contient la configuration du projet. Dans la section config, vous pouvez choisir le modèle que vous souhaitez utiliser ("gpt-4", "gpt-3.5-turbo-16k", ou autres).
Résoudre un problème spécifique à partir de CodeContest
Pour résoudre un problème spécifique avec AlphaCodium, à partir du dossier racine, exécutez :
Code : | Sélectionner tout |
1 2 3 4 | python -m alpha_codium.solve_problem \ --dataset_name /path/to/dataset \ --split_name test \ --problem_number 0 |
- Le dataset_name est le chemin d'accès au dossier du jeu de données que vous avez téléchargé lors de l'étape d'installation.
- Notez que l'ensemble de validation contient 117 problèmes, et l'ensemble de test 165 problèmes, donc le paramètre problem_number doit être en conséquence (basé sur zéro).
- Le split_name peut être valid ou test.
- Les sections suivantes du fichier de configuration : solve, self_reflection,possible_solutions, generate_ai_tests,initial_code_generation,public_tests, ai_tests permettent d'ajuster les configurations possibles pour les différentes étapes du flux.
- Chaque exécution enregistre les résultats dans un fichier nommé alpha_codium/example.log. L'examen du fichier journal est un bon moyen de comprendre ce qui se passe à chaque étape du flux.
Exemple de problème (ensemble de tests, problème numéro 12) :
Résolution d'un jeu de données CodeContest complet divisé
Pour résoudre l'ensemble du jeu de données avec AlphaCodium, à partir du dossier racine run :
Code : | Sélectionner tout |
1 2 3 4 | python -m alpha_codium.solve_dataset \ --dataset_name /path/to/dataset \ --split_name test \ --database_solution_path /path/to/output/dir/dataset_output.json |
- Le split_name peut être valid ou test.
- database_solution_path est le chemin vers le répertoire où les solutions seront sauvegardées.
- La section dataset du fichier de configuration contient la configuration pour l'exécution et l'évaluation d'un jeu de données.
- Notez qu'il s'agit d'un processus long, qui peut prendre quelques jours avec de grands modèles (par exemple GPT-4) et plusieurs itérations par problème.
- dataset.num_iterations définit le nombre d'itérations pour chaque problème (pass@K). Pour un grand nombre d'itérations, il est recommandé d'introduire un peu d'aléatoire et différentes options pour chaque itération afin d'obtenir les meilleurs résultats.
Exécution de l'évaluation
Une fois que vous avez généré une solution pour l'ensemble du jeu de données (valide ou test), vous pouvez l'évaluer en l'exécutant :
Code : | Sélectionner tout |
1 2 3 4 | python -m alpha_codium.evaluate_dataset \ --dataset_name /path/to/dataset \ --split_name test \ --database_solution_path /path/to/output/dir/dataset_output.json |
Pour résoudre un problème personnalisé avec AlphaCodium, créez d'abord un fichier json qui inclut les champs du problème CodeContest, puis à partir du dossier racine, exécutez :
Code : | Sélectionner tout |
1 2 | python -m alpha_codium.solve_my_problem \ --my_problem_json_file /path/to/my_problem.json |
Voir le fichier my_problem_example.json pour voir un exemple de problème personnalisé. Le fichier json doit contenir les champs suivants :
- name est le nom du problème.
- description est une description du problème.
- (facultatif) public_tests avec les champs suivants :
- input est une liste de chaînes de caractères qui représentent l'entrée.
- output est une liste de chaînes de caractères représentant la sortie.
- (optionnel) private_tests, qui suit la même structure que public_tests
- (optionnel) generated_tests, qui suit la même structure que public_tests
Questions et réponses techniques
Les développeurs partagent les réponses aux questions techniques à propos de ce projet :
Combien de temps avez-vous consacré à l'"ingénierie des invites" par rapport à l'"ingénierie des flux" ?
La sortie structurée élimine presque complètement le besoin d'une simple ingénierie d'invite. Nous estimons qu'environ 95 % du temps a été consacré à la conception de haut niveau, au raisonnement et à l'injection de données aux bons endroits, ..., autrement dit à l'"ingénierie de flux".
Comment savez-vous qu'il n'y a pas eu de fuite de données ?
Le jeu de test CodeContests comprend des problèmes publiés après septembre 2021, alors que la variante du modèle GPT-4 que nous avons utilisée (gpt-4-0613) a une date limite d'utilisation des données fixée à septembre 2021. Il n'y a donc pas de fuite de données pour le modèle GPT4 sur l'ensemble de données de test. Pour d'autres modèles comme DeepSeek, nous ne pouvons pas être sûrs. Toutefois, il convient de noter que notre principal résultat est une comparaison entre l'"invite directe" et le "flux AlphaCodium". Les fuites de données favoriseraient les deux approches, de sorte que l'amélioration relative du flux AlphaCodium reste valable.
Ce projet concerne-t-il uniquement des langages de programmation spécifiques ?
Non. Le flux proposé est indépendant du langage. Nous avons généré des solutions en Python, mais le flux peut être appliqué à n'importe quel langage.
Comment avez-vous géré la fenêtre contextuelle ?
Nous avons utilisé des modèles avec une fenêtre contextuelle de 8192 tokens, et nous n'avons pas rencontré de cas où cela ne suffisait pas. Toutefois, nous avons clairement observé qu'à mesure que le contexte utilisé en pratique s'élargit (disons, au-delà de 4 000 tokens), le modèle commence à "ignorer" certaines des informations contenues dans le contexte. Il s'agit donc d'un compromis évident :
Ce travail est-il "réaliste" en termes de nombre d'appels au LLM ?
Par rapport à AlphaCode, nous faisons quatre ordres de grandeur ( !) de moins d'appels (AlphaCodium fait 15-20 appels par solution). Cependant, nous reconnaissons que pour certaines applications, cela peut être encore trop, et que d'autres optimisations sont nécessaires. Nous pensons toutefois que bon nombre des idées et des principes que nous avons acquis dans ce travail sont largement applicables, même lorsque le nombre d'appels est encore plus limité.
Pourquoi itérer uniquement sur le code généré, et non sur les tests générés par l'IA ?
Pour les problèmes de code dans CodeContests, les tests sont une liste de paires entrée-sortie. Par conséquent, vous n'apprenez rien de nouveau lorsque vous "corrigez" un test - vous changez simplement sa sortie pour la prédiction du code généré. Au lieu de corriger les tests, nous avons préféré essayer de toujours corriger le code, tout en utilisant des "ancres de test". Cependant, pour d'autres tâches de génération de code, où les tests sont plus complexes et contiennent du code exécutable, l'itération sur les tests, en plus de l'itération sur le code généré, peut être bénéfique.
La sortie structurée élimine presque complètement le besoin d'une simple ingénierie d'invite. Nous estimons qu'environ 95 % du temps a été consacré à la conception de haut niveau, au raisonnement et à l'injection de données aux bons endroits, ..., autrement dit à l'"ingénierie de flux".
Comment savez-vous qu'il n'y a pas eu de fuite de données ?
Le jeu de test CodeContests comprend des problèmes publiés après septembre 2021, alors que la variante du modèle GPT-4 que nous avons utilisée (gpt-4-0613) a une date limite d'utilisation des données fixée à septembre 2021. Il n'y a donc pas de fuite de données pour le modèle GPT4 sur l'ensemble de données de test. Pour d'autres modèles comme DeepSeek, nous ne pouvons pas être sûrs. Toutefois, il convient de noter que notre principal résultat est une comparaison entre l'"invite directe" et le "flux AlphaCodium". Les fuites de données favoriseraient les deux approches, de sorte que l'amélioration relative du flux AlphaCodium reste valable.
Ce projet concerne-t-il uniquement des langages de programmation spécifiques ?
Non. Le flux proposé est indépendant du langage. Nous avons généré des solutions en Python, mais le flux peut être appliqué à n'importe quel langage.
Comment avez-vous géré la fenêtre contextuelle ?
Nous avons utilisé des modèles avec une fenêtre contextuelle de 8192 tokens, et nous n'avons pas rencontré de cas où cela ne suffisait pas. Toutefois, nous avons clairement observé qu'à mesure que le contexte utilisé en pratique s'élargit (disons, au-delà de 4 000 tokens), le modèle commence à "ignorer" certaines des informations contenues dans le contexte. Il s'agit donc d'un compromis évident :
- L'injection des résultats des étapes précédentes dans le contexte peut aider le modèle à générer un meilleur code.
- Cependant, cela peut aussi amener le modèle à ignorer des détails et des nuances spécifiques de la description du problème.
Ce travail est-il "réaliste" en termes de nombre d'appels au LLM ?
Par rapport à AlphaCode, nous faisons quatre ordres de grandeur ( !) de moins d'appels (AlphaCodium fait 15-20 appels par solution). Cependant, nous reconnaissons que pour certaines applications, cela peut être encore trop, et que d'autres optimisations sont nécessaires. Nous pensons toutefois que bon nombre des idées et des principes que nous avons acquis dans ce travail sont largement applicables, même lorsque le nombre d'appels est encore plus limité.
Pourquoi itérer uniquement sur le code généré, et non sur les tests générés par l'IA ?
Pour les problèmes de code dans CodeContests, les tests sont une liste de paires entrée-sortie. Par conséquent, vous n'apprenez rien de nouveau lorsque vous "corrigez" un test - vous changez simplement sa sortie pour la prédiction du code généré. Au lieu de corriger les tests, nous avons préféré essayer de toujours corriger le code, tout en utilisant des "ancres de test". Cependant, pour d'autres tâches de génération de code, où les tests sont plus complexes et contiennent du code exécutable, l'itération sur les tests, en plus de l'itération sur le code généré, peut être bénéfique.
Bien qu'AlphaCodium présente des résultats sur l'ensemble de données CodeContests, les développeurs pensent qu'il a une applicabilité plus large.
Tout d'abord, ils pensent que le flux AlphaCodium proposé, avec des ajustements raisonnables, peut être utilisé comme un cadre plus général pour d'autres tâches de génération de code.
Deuxièmement, de nombreux concepts, principes et astuces de conception acquis dans ce travail sont largement applicables tels quels à toutes les tâches générales de génération de code. Par exemple :
[LIST][*]Sortie structurée YAML : demander au modèle de générer une sortie au format YAML, équivalente à une classe Pydantic donnée.
[*]Raisonnement sémantique via l'analyse des puces : L'analyse des puces encourage une compréhension approfondie du problème et force le modèle à diviser la sortie en sections sémantiques logiques, ce qui permet d'améliorer les résultats.
[*]Les LLM font mieux lorsqu'ils génèrent un code modulaire : lorsqu'on demande au modèle de diviser le code généré en petites...
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.