PAL : Modèles de langage assistés par programme pour une arithmétique financière fiable
Après avoir passé du temps sur la littérature consacrée au raisonnement tabulaire, j'ai voulu comprendre l'approche complémentaire : plutôt que de faire raisonner les LLM sur des tableaux en langage naturel, que se passe-t-il si on les laisse écrire du code et déléguer entièrement le calcul ? PAL (Gao et al., 2022, arXiv:2211.10435) est la réponse canonique, et elle a des implications évidentes pour tout système devant effectuer des calculs arithmétiques fiables sur des données financières.
L'article
"PAL: Program-Aided Language Models" (Gao, Madaan, Zhou, Alon, Liu, Yang, Callan, Neubig ; ICML 2023) part d'une observation simple : les LLM décomposent bien les problèmes mais exécutent mal l'arithmétique. L'incitation par chaîne de pensée (chain-of-thought) corrige le premier problème mais laisse le second intact. La solution proposée est de modifier ce que le LLM produit comme "étapes de raisonnement" — au lieu d'une arithmétique en langage naturel, il génère du code Python. Un interpréteur Python exécute ensuite ce code et renvoie la réponse.
La séparation décomposition-exécution est nette : le LLM s'occupe de la compréhension du problème et de la structure du programme ; l'interpréteur gère tout ce qui est numérique. Une question comme "Olivia a 23 $, achète cinq bagels à 3 $ chacun — combien lui reste-t-il ?" devient money_left = 23 - (5 * 3), et non une séquence d'arithmétique en prose que le modèle pourrait rater.
Idées clés
- Sur GSM8K (problèmes mathématiques textuels de niveau primaire), PAL avec Codex atteint 72,0 % de précision contre 65,6 % pour la chaîne de pensée avec le même modèle Codex — un gain de +6,4 points de pourcentage — et 56,9 % pour CoT avec le modèle beaucoup plus grand PaLM-540B. Un modèle plus petit gagne en déléguant l'arithmétique à Python.
- Sur GSM-hard, une version de GSM8K où les nombres sont remplacés par des valeurs plus grandes, PAL atteint 61,2 % contre 23,1 % pour CoT — un écart absolu de +38,1 points de pourcentage. Les grands nombres cassent l'arithmétique au niveau des jetons (tokens) ; ils ne cassent pas Python.
- Avec un vote majoritaire sur 40 échantillons, PAL atteint 80,4 % sur GSM8K, devançant Minerva-540B (78,5 %) avec un modèle environ 10 fois plus petit.
- Les gains se généralisent au raisonnement symbolique. Sur les tâches BIG-Bench Hard comme le comptage d'objets (Object Counting), PAL obtient 96,7 % contre 73,0 % pour CoT ; sur "Penguins in a Table", 93,3 % contre 79,2 %.
- Une étude d'ablation révèle où le travail est réellement effectué : lorsque le LLM agit comme son propre interpréteur (sans Python externe), la précision sur GSM8K s'effondre à 23,2 %. L'interpréteur n'est pas une amélioration mineure — il effectue toute l'arithmétique.
- Le nommage des variables est important. Remplacer des noms de variables explicites par des caractères aléatoires provoque des chutes de précision substantielles sur les tâches symboliques. Le modèle lit son propre code.
Ce qui tient la route — et ce qui ne la tient pas
L'affirmation centrale est trivialement correcte et les expériences la confirment de manière convaincante : Python est meilleur qu'un LLM pour l'arithmétique, et GSM-hard rend cela brutalement visible. Les +38 points de pourcentage ne sont pas une anomalie de benchmark — ils reflètent un mode de défaillance catégorique de CoT face à l'échelle.
Ce que je trouve moins convaincant, c'est la présentation comme une percée générale du raisonnement. PAL fonctionne sur des tâches qui ont par hasard des réponses déterministes exprimables en Python. Une grande partie de ce qui compte dans le raisonnement financier ne se décompose pas de cette manière. Décider si un schéma de transaction est "inhabituel pour ce compte au quatrième trimestre" ou si un transfert justifie un signalement pour examen manuel n'est pas réductible à une expression Python. PAL vous donne un moteur arithmétique fiable ; il ne vous donne pas de jugement.
La dimension sécuritaire ne reçoit aucune attention dans l'article. Les benchmarks s'exécutent dans un environnement contrôlé, mais tout déploiement qui génère et exécute du Python arbitraire en réponse à des entrées fournies par l'utilisateur constitue une surface d'attaque significative. Évasions de noyau à partir d'interpréteurs en bac à sable (sandboxed), accès au système de fichiers ou aux secrets, entrées conçues de manière malveillante générant du code néfaste — rien de tout cela n'est abordé. Pour des applications financières, ce n'est pas une simple note de bas de page.
L'article n'analyse pas non plus en profondeur les modes de défaillance lorsque la génération de code échoue. Si PAL émet du Python syntaxiquement invalide, il n'a aucune solution de repli. Les auteurs rapportent des taux de réussite d'exécution mais ne caractérisent pas les causes des échecs de génération, ni si ces derniers sont aléatoires ou systématiques. Étant donné que l'interpréteur effectue toute l'arithmétique, la qualité du code est l'unique goulot d'étranglement de la fiabilité — et elle est sous-analysée.
Pourquoi cela compte pour l'IA financière
C'est l'un des articles les plus directement applicables à Beancount que j'ai lus. Les opérations sur le grand livre sont presque parfaitement alignées avec ce que PAL fait bien : sommer des transactions par catégorie, appliquer des taux de change, calculer la base d'imposition sur plusieurs lots, rapprocher les totaux des relevés bancaires avec les soldes du grand livre. Ce sont des tâches déterministes, à forte intensité arithmétique et exprimables en Python. Les agents basés sur CoT hallucineront des chiffres ici ; PAL ne le fera pas, tant que la structure du programme est correcte.
Program of Thoughts (arXiv:2211.12588), un article concomitant qui a développé indépendamment la même idée, a été évalué sur trois ensembles de données de questions-réponses financières — FinQA, ConvFinQA et TATQA — et a rapporté un gain moyen d'environ 12 % par rapport à la chaîne de pensée. C'est la preuve la plus directe que l'approche de génération de programme aide au raisonnement dans le domaine de la finance, et pas seulement pour les mathématiques de l'école primaire.
La question de la sécurité de l'écriture (write-back) est cependant plus aiguë dans un contexte de grand livre que sur des benchmarks. Un agent qui génère du Python pour lire les données Beancount présente un risque faible. Un agent qui génère du Python pour écrire des écritures comptables nécessite un environnement d'exécution strictement restreint — un environnement qui ne peut toucher qu'aux objets du grand livre et à rien d'autre, qui se verrouille par défaut (fail closed) sur n'importe quelle exception, et qui exige que le code généré passe par une liste blanche avant exécution. PAL traite l'interpréteur comme un moteur de calcul neutre. Un agent financier en production ne peut pas se le permettre.
Que lire ensuite
- Program of Thoughts Prompting (Chen et al., arXiv:2211.12588) — travail concomitant qui évalue sur FinQA, ConvFinQA et TATQA et rapporte un gain moyen d'environ 12 % par rapport à CoT ; l'évaluation spécifique à la finance que PAL diffère.
- FinQA: A Dataset of Numerical Reasoning over Financial Reports (Chen et al., EMNLP 2021) — le benchmark sous-jacent aux évaluations financières de PoT ; comprendre ce qui est réellement testé permet de calibrer la confiance à accorder au transfert vers des cas d'utilisation réels de Beancount.
- Self-Refine: Iterative Refinement with Self-Feedback (Madaan et al., arXiv:2303.17651) — même premier auteur que PAL, étend l'idée de génération de code à des boucles d'auto-correction itératives ; pertinent pour savoir si les agents de style PAL peuvent se remettre de leurs propres échecs de génération de code.
