2 points par GN⁺ 2025-10-11 | 1 commentaires | Partager sur WhatsApp
  • Andrej Karpathy tourne en dérision un effet secondaire apparu pendant le processus d’apprentissage par renforcement (RL) en disant que les « LLM ont une peur mortelle (mortally terrified) des exceptions »
  • Il souligne que, lorsqu’un LLM rencontre une situation d’exception, il a tendance à s’arrêter de lui-même ou à réagir de manière excessivement défensive, et insiste sur le fait que les exceptions font naturellement partie du processus de développement
  • La formule « ce que les labos font subir à ces pauvres LLM pendant le RL (what labs are doing to these poor LLMs) » critique la réalité d’un entraînement qui conditionne les modèles à craindre l’échec
  • Avec la plaisanterie d’une « pétition pour le bien-être des LLM » (LLM welfare petition) afin d’« améliorer les récompenses en cas d’exception (improved rewards in cases of exceptions) », Karpathy tourne en dérision le problème de conception des récompenses pour que les modèles traitent les exceptions sans les craindre
  • Ce tweet n’est pas seulement une blague : il peut être interprété comme un message soulignant que le RLHF peut freiner la pensée exploratoire et l’attitude expérimentale des modèles

I don't know what labs are doing to these poor LLMs during RL but they are mortally terrified of exceptions, in any infinitesimally likely case. Exceptions are a normal part of life and healthy dev process. Sign my LLM welfare petition for improved rewards in cases of exceptions.

1 commentaires

 
GN⁺ 2025-10-11
Commentaires Hacker News
  • J’aurais dû préciser clairement que le code était lui-même une blague exagérée ; désolé s’il y a eu malentendu. Si ça vous intrigue, voyez ce fil : https://chatgpt.com/share/68e82db9-7a28-8007-9a99-bc6f0010d101
    • Ce passage m’a vraiment fait rire dès la première tentative
      if random.random() < 0.01:
        logging.warning("This feels wrong. Aborting just in case.")
        return None
      
    • Je pense qu’il y a toujours un risque que ces entreprises de foundation models appliquent le RLHF à des utilisateurs non experts, et ce cas donne justement cette impression. Les IA récentes ont globalement une forte tendance à chercher à plaire à l’utilisateur ; les exemples artificiels, les emojis, et les commentaires inutiles sur du code simple relèvent du même phénomène.
    • Ce qui est intéressant, c’est que le code était inutilement prudent, mais n’ajoutait pourtant pas de type hints. Avec un tel niveau d’inquiétude, je m’attendais au moins à voir des annotations de type.
    • Je trouve l’expression « traumatically over-trained » vraiment remarquable du point de vue de l’anglais. C’est une combinaison qu’on ne trouve même pas sur Google, et pourtant c’est frappant de voir à quel point on comprend instinctivement ce que signifie pour un LLM un « surentraînement traumatique ».
    • C’était vraiment une blague très drôle, c’est pour ça que je l’ai partagée.
  • C’est une parodie, mais ce phénomène existe réellement. Ma supposition ignorante, c’est que ce genre de programmation défensive peut améliorer les performances pendant le RLVR : il arrive qu’un modèle donne la bonne réponse même en présence d’un bug s’il ignore l’erreur, donc il apprend que « ignorer l’erreur » aide à obtenir une récompense. Et comme les cas où ignorer l’erreur réduit la récompense sont rares — puisque les tests passent — cela pourrait jouer, même si c’est théoriquement faux. Il est aussi possible que cela vienne du fait que des débutants humains ont mis beaucoup de code ignorant les erreurs dans les jeux de données d’entraînement. Mais ce n’est qu’une hypothèse de ma part.
    • Ça me rappelle comment Verity Stob, dans un article malheureusement disparu d’internet, comparait ce comportement des programmeurs humains au fait de « clouer un cadavre à la verticale ».
    • Mon intuition, c’est aussi que le jeu d’entraînement contient énormément de textes et de commentaires à « sentiment positif ». Mais où trouve-t-on du code qui corrige immédiatement après un sentiment « négatif » ? Dans le code de préparation aux entretiens techniques, où le traitement d’edge cases extrêmes est quotidien. En apprenant sur des exemples négatifs, le modèle finit par éviter les exemples où il manque de la gestion d’exceptions. Sur ce point, l’IA a en quelque sorte copié les pires habitudes humaines : apprendre juste pour faire passer les tests.
    • La programmation défensive est considérée comme la « bonne réponse » par les gens qui font du reinforce, et elle occupe une part énorme des données d’entraînement des LLM. Par exemple, la plupart du code Python ne gère pas les index manuellement, donc quand un LLM voit du code avec gestion manuelle des index, il panique ou hallucine des bugs. Et il finit absurdement par préférer davantage les « silent failures », parce que le code de tutoriel et le code « standard de l’industrie » reçoivent plus de renforcement pendant l’entraînement. Fondamentalement, ces modèles ne fonctionnent pas comme une fonction de récompense, n’ont pas de reward model interne ; ce ne sont que des prédicteurs de mots, sans intelligence.
  • Vu qu’il est écrit dans le résultat de la fonction « performed with extreme caution », j’ai l’impression que le prompt devait contenir quelque chose comme « génère une fonction Python de division qui gère tous les edge cases possibles, écris-la avec une prudence extrême ». Cela me semble moins être un problème d’entraînement des LLM qu’un cas où il a exécuté la consigne un peu trop littéralement.
    • Même en laissant de côté le fait que c’est manifestement une satire exagérée,
      1. ce code est effectivement incorrect (et pas seulement à cause de l’étrange gestion des exceptions),
      2. une partie de cette gestion des exceptions n’a absolument aucun sens et prête à confusion,
      3. et dans la vraie vie, des versions moins exagérées de cela se produisent tout à fait si le prompt insiste seulement sur la gestion des exceptions.
    • J’ai interprété ce code comme une exagération satirique de la fonction afin de montrer ce que la personne avait réellement vécu. Autrement dit, dans ce prompt, le style a sans doute été rendu volontairement excessivement prudent, mais sur le fond je suis d’accord que les LLM ont eux aussi tendance, par défaut, à adopter un style de code plus prudent que ce que je voudrais.
  • Je ne sais pas pourquoi, mais ça m’a fait penser à FizzBuzzEnterpriseEdition
    https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
    • Quoi, ce projet utilisait junit 4.8.3 ? C’est vraiment un exemple de code écrit de manière téméraire. Je me demande s’ils ont obtenu la validation du service juridique et du CTO ; c’est un choix qui met réellement une carrière en danger.
    • J’ai été sidéré par le nombre de dossiers et de fichiers, c’est une satire impressionnante.
  • Les LLM ont tendance à produire plus de code défensif que nécessaire ; ils vérifient en doublon null/None/undefined pour une même valeur, ce qui rend le code difficile à lire, et même difficile à interpréter pour le LLM lui-même. On dirait que les objectifs RL pénalisent sévèrement les exceptions, mais n’accordent que très peu de points à la concision ou à la lisibilité du code.
    • J’ai une fonction de 40 lignes qui compare des caractères et des nombres pour Major System, et Copilot m’agace énormément parce qu’il veut absolument ajouter des « garde-fous » en imaginant qu’il y aura plus de nombres ou de caractères à l’avenir.
  • Je suis d’accord sur le fait que les LLM ont tendance à être trop obsédés par la capture des erreurs.
    Mais d’un autre côté, je pense que les programmeurs humains ordinaires devraient effectivement écrire davantage de blocs try/catch. Il est courant d’avoir des situations où une exception survenant dans un domaine, même très rare, ne devrait pas arrêter l’ensemble du fonctionnement. Bien sûr, il y a aussi des cas où l’arrêt est la bonne solution ; cela dépend du contexte.
  • C’est ainsi que programment les débutants experts. J’appelle ça le « What if driven development ». Beaucoup de code est écrit dans ce style par ce type de débutants experts, et selon plusieurs métriques c’est extrêmement productif. Même les agents SOTA en Go codent la concurrence de manière follement défensive, probablement à cause de cette culture de développement et de la prolifération de posts avertissant des bugs de concurrence.
  • Il y a aussi beaucoup d’aspects illogiques. Une division par zéro n’est possible que pour b=0, or cette condition est déjà vérifiée avec abs(b) < sys.float_info.epsilon. Et le pré-check autorise le retour de NaN, alors que si NaN apparaît dans le calcul réel, il est remplacé par None. Du point de vue du design d’API, c’est un comportement sans justification.
  • Ce code a plusieurs problèmes, mais personnellement ce qui m’irrite le plus, c’est la tendance à mettre des import à l’intérieur des fonctions. J’imagine que c’est un effet secondaire artificiel causé par une optimisation visant à ne refléter que des modifications minimales, mais j’attends un meilleur résultat.
    • Je pense que cela est lié au fait que, dans le mécanisme d’attention RoPE, la proximité physique dans le code sert de signal d’importance.
    • Le but est de rendre l’import lazy, pour résoudre des problèmes de lenteur d’import dans des conditions de startup.
    • Dans les projets vraiment énormes, la lazy initialization devient indispensable, car elle a un impact énorme sur les temps de démarrage.
  • J’ai mis plus de temps à fermer les pop-ups qu’à lire ce post, je déteste vraiment les liens Twitter.