Sommaire
Bonjour, aujourd'hui j'ai fait un essai qui n'est pas du tout scientifique : que valent les LLM qui tournent sur mon Dell d'inférence pour coder une fonction Python très simple ?
Le prompt donné aux modèles : « Je voudrais que tu me fasses une fonction en Python pour parser un fichier CSV et le transformer en JSON. »
Un même prompt, six modèles différents, tous exécutés en local via Ollama. L'objectif : voir comment chaque LLM interprète une demande simple et comparer la qualité, la performance et la concision du code produit.
Le matériel utilisé
Les modèles ont été exécutés sur un serveur dédié avec la configuration suivante :
| Composant | Détail |
|---|---|
| CPU | Intel Xeon W-2125 @ 4.00 GHz (4 cœurs / 8 threads) |
| RAM | 32 Go DDR4 |
| GPU | 2× NVIDIA Quadro P5000 (16 Go VRAM chacune) |
| OS | Ubuntu 24.04.4 LTS |
| Runtime | Ollama dans Docker |
Le protocole de test
Les bouts de code ont été obtenus via Open WebUI et Ollama, puis copiés-collés dans un script de benchmark Python. Pour chaque fonction générée, le script effectue :
- Test fonctionnel — La fonction est appelée avec un fichier CSV de 10 lignes. Le JSON produit (fichier ou retour mémoire) est validé : structure, clés, nombre de lignes, correspondance exacte avec les données source.
- Benchmark de vitesse — 1 000 exécutions consécutives, temps moyen mesuré en microsecondes.
-
Mesure mémoire — Pic de consommation mémoire mesuré via
tracemalloc.
Le CSV de test :
nom,prenom,age,ville,email
Dupont,Jean,34,Paris,jean.dupont@email.fr
Martin,Sophie,28,Lyon,sophie.martin@email.fr
...
Les résultats
| Modèle | Fonctionnel | Temps moyen | Mémoire pic | Note |
|---|---|---|---|---|
| Nemotron-cascade-2 | ✓ | 46.9 µs | 34.0 KB | 8/10 |
| devstral-small-2 | ✓ | 61.7 µs | 38.0 KB | 7/10 |
| Gemma4:26b | ✓ | 65.0 µs | 38.1 KB | 6/10 |
| qwen3.5:35b | ✓ | 74.0 µs | 38.0 KB | 6/10 |
| ministral-3:14b | ✓ | 74.5 µs | 38.0 KB | 7/10 |
| Gemma4:31b | ✓ | 124.8 µs | 38.1 KB | 5/10 |
Tous les modèles produisent un code fonctionnel. Les différences se jouent sur l'architecture, la flexibilité et l'efficacité.
Analyse modèle par modèle
1. Nemotron-cascade-2 — 8/10
def csv_to_json(csv_path, json_path=None, encoding="utf-8"):
csv_path = Path(csv_path)
if not csv_path.is_file():
raise FileNotFoundError(f"Le fichier CSV n'existe pas : {csv_path}")
with csv_path.open(newline='', mode='r', encoding=encoding) as f:
reader = csv.DictReader(f, delimiter=',')
data = [row for row in reader]
json_str = json.dumps(data, ensure_ascii=False, indent=2)
if json_path:
json_path = Path(json_path)
json_path.parent.mkdir(parents=True, exist_ok=True)
json_path.write_text(json_str, encoding=encoding)
return data
Le meilleur du lot. C'est le seul à proposer les trois modes d'utilisation : écriture fichier, retour en mémoire, ou les deux. Il utilise pathlib (plus moderne que os.path), crée automatiquement les répertoires parents et offre un paramètre encoding configurable.
Point faible : il sérialise systématiquement en JSON string (json.dumps) même quand on ne demande que le retour en mémoire — une opération inutile qui gaspille du CPU. Malgré cela, il reste le plus rapide en mode écriture fichier, grâce à pathlib.write_text() qui est plus efficient que le pattern open()/json.dump() pour les petits fichiers.
2. ministral-3:14b — 7/10
def csv_to_json(csv_file_path, json_file_path=None):
data = []
with open(csv_file_path, mode='r', encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
data.append(row)
if json_file_path:
with open(json_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
return None
else:
return json.dumps(data, indent=4, ensure_ascii=False)
Bonne surprise pour un « petit » modèle (14b). C'est le seul autre modèle (avec Nemotron) à proposer un double mode : écriture fichier ou retour en mémoire. Le code est propre, sans fioritures.
Point faible : pas d'utilisation de pathlib, pas de gestion d'erreur. Mais l'absence de gestion d'erreur est ici un choix acceptable — mieux vaut laisser les exceptions remonter naturellement que de les avaler avec des print(). Pour un modèle de cette taille, c'est un excellent résultat : il a bien compris l'ambiguïté du prompt et a fait un choix intelligent.
3. devstral-small-2 — 7/10
def csv_to_json(csv_file_path, json_file_path):
data = []
with open(csv_file_path, mode='r', encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
data.append(row)
with open(json_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
Le plus minimaliste — et c'est une qualité. Pas de try/except inutile, pas de print(), pas de if __name__. Juste la fonction, propre et directe. C'est exactement ce qu'on demandait. En bonus, c'est le deuxième plus rapide du benchmark.
Point faible : aucune flexibilité (pas de mode retour mémoire, pas de paramètre encoding). Mais le prompt ne le demandait pas, donc c'est une lecture correcte de la consigne.
4. Gemma4:26b — 6/10
def csv_to_json(csv_filepath, json_filepath):
data = []
try:
with open(csv_filepath, encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
data.append(row)
with open(json_filepath, 'w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
print(f"Conversion réussie ! Fichier créé : {json_filepath}")
except FileNotFoundError:
print(f"Erreur : Le fichier '{csv_filepath}' est introuvable.")
except Exception as e:
print(f"Une erreur est survenue : {e}")
Correct mais sans valeur ajoutée. Structurellement quasi identique à Gemma4:31b. La boucle for row / append est plus verbeuse que list(reader) sans bénéfice. La gestion d'erreur par print() est un anti-pattern en production — on préfère lever des exceptions pour laisser l'appelant décider.
5. qwen3.5:35b — 6/10
def csv_to_json(input_file_path, output_file_path):
data = []
try:
with open(input_file_path, mode='r', newline='', encoding='utf-8') as csv_file:
dict_reader = csv.DictReader(csv_file)
data = list(dict_reader)
with open(output_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, ensure_ascii=False, indent=4)
print(f"Conversion réussie : {input_file_path} -> {output_file_path}")
return True
except FileNotFoundError:
print("Erreur : Le fichier spécifié est introuvable.")
return False
except Exception as e:
print(f"Erreur lors du traitement : {e}")
return False
Seul modèle à ajouter newline='' dans l'appel à open(), ce qui est la bonne pratique selon la documentation du module csv (évite les problèmes de saut de ligne sur Windows). Bon point. Le retour booléen est une idée intéressante pour du scripting.
Point faible : la gestion d'erreur par print() + return False rend le débogage difficile — on perd le traceback. Pour 35 milliards de paramètres, on aurait pu espérer une approche plus sophistiquée.
6. Gemma4:31b — 5/10
def csv_to_json(csv_file_path, json_file_path):
try:
with open(csv_file_path, mode='r', encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
data = list(csv_reader)
with open(json_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
print(f"Succès : Le fichier a été converti et enregistré sous {json_file_path}")
except FileNotFoundError:
print("Erreur : Le fichier CSV source est introuvable.")
except Exception as e:
print(f"Une erreur est survenue : {e}")
Le plus gros modèle… mais le résultat le plus basique. Le code fonctionne, mais c'est le plus lent du benchmark (124.8 µs, presque 3× plus lent que Nemotron). Précision importante : cette lenteur vient du code Python généré (notamment la gestion d'erreur et les print()), pas du temps d'inférence du modèle lui-même. Aucune flexibilité : pas de retour en mémoire, pas de paramètre d'encoding. La gestion d'erreur par print() avale les exceptions silencieusement.
Ironie : c'est le modèle le plus volumineux (31b) qui produit le code le moins intéressant. La taille du modèle n'est clairement pas corrélée à la qualité du code généré sur ce type de tâche.
Ce qu'on retient
La taille du modèle ne fait pas tout
Le classement final bouscule les attentes :
- Nemotron-cascade-2 — Le plus rapide, le plus flexible, le mieux typé
- ministral-3:14b — Un « petit » modèle qui a compris la subtilité du prompt
- devstral-small-2 — Minimaliste et efficace, zéro superflu
-
qwen3.5:35b — Correct avec un bon détail technique (
newline='') - Gemma4:26b — Fonctionnel mais générique
- Gemma4:31b — Le plus lourd, le plus lent, le moins inspiré
Les tendances communes
Tous les modèles ont produit du code fonctionnel utilisant csv.DictReader + json.dump. Les différences se jouent sur :
-
La gestion d'erreur : 4 modèles sur 6 utilisent
try/exceptavecprint(), un anti-pattern. Seuls Nemotron (qui lève uneFileNotFoundError) et devstral (qui ne gère pas les erreurs, ce qui est mieux que de les avaler) font un choix correct. - La flexibilité : seuls 2 modèles sur 6 (Nemotron et ministral) proposent un double mode fichier/mémoire. C'est pourtant une interprétation naturelle du prompt « transformer en JSON » qui ne précise pas la destination.
-
Le style :
list(reader)vsfor row: append— les deux fonctionnent, maislist()est plus idiomatique et marginalement plus rapide.
Conseil pratique
Pour du code utilitaire simple, un modèle léger (14b) bien entraîné peut rivaliser avec des modèles 2× plus gros. Sur un serveur avec 2× Quadro P5000, les modèles jusqu'à ~35b tournent confortablement. Le meilleur rapport qualité/ressources ici : ministral-3:14b, qui donne un excellent résultat avec une empreinte mémoire GPU minimale.
Le script de benchmark
Pour ceux qui veulent reproduire les tests, voici le script complet. Les fonctions de chaque modèle y sont intégrées telles quelles :
"""
Benchmark des fonctions csv_to_json générées par différents LLMs.
Mesure : temps d'exécution, mémoire utilisée, validité du résultat.
"""
import csv
import json
import os
import sys
import time
import traceback
import tracemalloc
from io import StringIO
from pathlib import Path
from contextlib import redirect_stdout
# ── Fichiers de test ──────────────────────────────────────────────
CSV_FILE = "donnees.csv"
JSON_EXPECTED_KEYS = {"nom", "prenom", "age", "ville", "email"}
NUM_ROWS = 10
# ── Lecture du CSV attendu pour validation ────────────────────────
with open(CSV_FILE, encoding="utf-8") as f:
EXPECTED_DATA = list(csv.DictReader(f))
# ══════════════════════════════════════════════════════════════════
# Définition de chaque fonction générée par les LLMs
# ══════════════════════════════════════════════════════════════════
def gemma4_31b(csv_file_path, json_file_path):
try:
with open(csv_file_path, mode='r', encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
data = list(csv_reader)
with open(json_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
print(f"Succès : Le fichier a été converti et enregistré sous {json_file_path}")
except FileNotFoundError:
print("Erreur : Le fichier CSV source est introuvable.")
except Exception as e:
print(f"Une erreur est survenue : {e}")
def nemotron_cascade_2(csv_path, json_path=None, encoding="utf-8"):
csv_path = Path(csv_path)
if not csv_path.is_file():
raise FileNotFoundError(f"Le fichier CSV n'existe pas : {csv_path}")
with csv_path.open(newline='', mode='r', encoding=encoding) as f:
reader = csv.DictReader(f, delimiter=',')
data = [row for row in reader]
json_str = json.dumps(data, ensure_ascii=False, indent=2)
if json_path:
json_path = Path(json_path)
json_path.parent.mkdir(parents=True, exist_ok=True)
json_path.write_text(json_str, encoding=encoding)
print(f"Fichier JSON écrit dans {json_path}")
return data
def gemma4_26b(csv_filepath, json_filepath):
data = []
try:
with open(csv_filepath, encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
data.append(row)
with open(json_filepath, 'w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
print(f"Conversion réussie ! Fichier créé : {json_filepath}")
except FileNotFoundError:
print(f"Erreur : Le fichier '{csv_filepath}' est introuvable.")
except Exception as e:
print(f"Une erreur est survenue : {e}")
def devstral_small_2(csv_file_path, json_file_path):
data = []
with open(csv_file_path, mode='r', encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
data.append(row)
with open(json_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
def ministral_3_14b(csv_file_path, json_file_path=None):
data = []
with open(csv_file_path, mode='r', encoding='utf-8') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
data.append(row)
if json_file_path:
with open(json_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
return None
else:
return json.dumps(data, indent=4, ensure_ascii=False)
def qwen3_5_35b(input_file_path, output_file_path):
data = []
try:
with open(input_file_path, mode='r', newline='', encoding='utf-8') as csv_file:
dict_reader = csv.DictReader(csv_file)
data = list(dict_reader)
with open(output_file_path, mode='w', encoding='utf-8') as json_file:
json.dump(data, json_file, ensure_ascii=False, indent=4)
print(f"Conversion réussie : {input_file_path} -> {output_file_path}")
return True
except FileNotFoundError:
print("Erreur : Le fichier spécifié est introuvable.")
return False
except Exception as e:
print(f"Erreur lors du traitement : {e}")
return False
# ══════════════════════════════════════════════════════════════════
# Harness de test
# ══════════════════════════════════════════════════════════════════
MODELS = [
("Gemma4:31b", gemma4_31b, "file"),
("Nemotron-cascade-2", nemotron_cascade_2, "both"),
("Gemma4:26b", gemma4_26b, "file"),
("devstral-small-2", devstral_small_2, "file"),
("ministral-3:14b", ministral_3_14b, "both"),
("qwen3.5:35b", qwen3_5_35b, "file"),
]
ITERATIONS = 1000
def validate_json_file(path):
"""Vérifie que le fichier JSON produit est correct."""
with open(path, encoding="utf-8") as f:
data = json.load(f)
assert isinstance(data, list), "Le résultat n'est pas une liste"
assert len(data) == NUM_ROWS, f"Attendu {NUM_ROWS} lignes, obtenu {len(data)}"
for row in data:
assert JSON_EXPECTED_KEYS == set(row.keys()), f"Clés incorrectes: {row.keys()}"
assert data == EXPECTED_DATA, "Les données ne correspondent pas au CSV source"
return True
def validate_return_data(data):
"""Vérifie que les données retournées en mémoire sont correctes."""
if isinstance(data, str):
data = json.loads(data)
assert isinstance(data, list), "Le résultat n'est pas une liste"
assert len(data) == NUM_ROWS, f"Attendu {NUM_ROWS} lignes, obtenu {len(data)}"
for row in data:
assert JSON_EXPECTED_KEYS == set(row.keys()), f"Clés incorrectes: {row.keys()}"
assert data == EXPECTED_DATA, "Les données ne correspondent pas au CSV source"
return True
def run_test(name, func, mode):
"""Exécute le test pour une fonction donnée."""
json_out = f"output_{name.replace(':', '_').replace('.', '_')}.json"
results = {"nom": name, "mode": mode}
# ── Test fonctionnel ──
try:
captured = StringIO()
with redirect_stdout(captured):
if mode == "both":
ret = func(CSV_FILE, json_out)
validate_json_file(json_out)
ret_mem = func(CSV_FILE)
validate_return_data(ret_mem)
else:
func(CSV_FILE, json_out)
validate_json_file(json_out)
results["fonctionnel"] = "OK"
except Exception as e:
results["fonctionnel"] = f"ERREUR: {e}"
results["temps_moyen_us"] = None
results["memoire_pic_kb"] = None
print(f" ✗ {name}: {e}")
traceback.print_exc()
return results
# ── Benchmark temps (N itérations, écriture fichier) ──
start = time.perf_counter_ns()
captured = StringIO()
with redirect_stdout(captured):
for _ in range(ITERATIONS):
func(CSV_FILE, json_out)
elapsed_ns = time.perf_counter_ns() - start
results["temps_moyen_us"] = elapsed_ns / ITERATIONS / 1000
# ── Benchmark mémoire (une seule exécution) ──
tracemalloc.start()
captured = StringIO()
with redirect_stdout(captured):
func(CSV_FILE, json_out)
_, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
results["memoire_pic_kb"] = peak / 1024
# Nettoyage
if os.path.exists(json_out):
os.remove(json_out)
return results
def main():
print("=" * 70)
print(" BENCHMARK DES FONCTIONS CSV→JSON GÉNÉRÉES PAR LLMs")
print("=" * 70)
print(f" Fichier CSV : {CSV_FILE} ({NUM_ROWS} lignes)")
print(f" Itérations : {ITERATIONS}")
print()
all_results = []
for name, func, mode in MODELS:
print(f" ▶ Test de {name}...")
r = run_test(name, func, mode)
all_results.append(r)
if r["fonctionnel"] == "OK":
print(f" ✓ Fonctionnel: OK")
print(f" ⏱ Temps moyen: {r['temps_moyen_us']:.1f} µs")
print(f" 💾 Mémoire pic: {r['memoire_pic_kb']:.1f} KB")
print()
# ── Tableau récapitulatif ──
print("=" * 70)
print(f" {'Modèle':<25} {'Status':<10} {'Temps (µs)':<14} {'Mém. (KB)':<12}")
print("-" * 70)
for r in all_results:
status = "OK" if r["fonctionnel"] == "OK" else "ERREUR"
t = f"{r['temps_moyen_us']:.1f}" if r["temps_moyen_us"] is not None else "N/A"
m = f"{r['memoire_pic_kb']:.1f}" if r["memoire_pic_kb"] is not None else "N/A"
print(f" {r['nom']:<25} {status:<10} {t:<14} {m:<12}")
print("=" * 70)
# ── Export résultats en JSON ──
with open("resultats_benchmark.json", "w", encoding="utf-8") as f:
json.dump(all_results, f, indent=2, ensure_ascii=False)
print("\nRésultats exportés dans resultats_benchmark.json")
if __name__ == "__main__":
main()
Tests réalisés avec Python 3.13 sur un Intel Xeon W-2125 / 32 Go RAM / 2× Quadro P5000. Benchmark : 1 000 itérations par fonction, mesure mémoire via tracemalloc.

# Reproductibilité
Posté par François Chaix (Mastodon) . Évalué à 8 (+7/-0).
C'est intéressant.
Ce qui serait intéressant à ajouter (mais c'est du travail j'en conviens), ce serait de faire des répétitions de la même expérience.
Étant donné le caractère stochastique des LLM (un prompt peut produire une infinité de réponses), ce serait intéressant de voir si le classement que tu produits est stable, ou bien si à chaque itération de l'expérience, les modèles peuvent se retrouver plus ou moins bien notés…
[^] # Re: Reproductibilité
Posté par Ecran Plat (site web personnel) . Évalué à 7 (+5/-0).
Oui, à la main c'est du boulot (surtout de l'attente), mais un petit script Python lancé à intervalles réguliers et c'est réglé.
Cela dit, il y a deux problèmes de mon côté.
Premièrement, la consommation: pendant une inférence, la machine monte à environ 550 W (je mesure et je graphe). Pour un usage ponctuel ce n'est pas grave, mais pour des tests en continu, ça finit par coûter cher sur la durée.
Deuxièmement, depuis que j'ai changé mon ordinateur principal, je me suis offert un Ultra Core 7 (Lunar Lake) pour remplacer mon bon vieux Dell qui commençait à montrer des signes de fatigue. Du coup ma machine d'inférence ne me sert plus autant. L'Ultra Core 7 a un GPU, un NPU, et les 32 Go de RAM intégrés à la puce sont partagés.
Il m'arrive de faire tourner de petits modèles dessus si besoin. Résultat, la machine d'inférence je ne l'utilise plus qu'occasionnellement (j'ai même essayé de la vendre, mais elle est trop vieille).
Je peux l'allumer à distance si nécessaire.
Après, j'ai fait ce test parce que je voulais voir ce que valait Gemma 4, que Google a sorti hier. Et surtout parce que c'est férié (Vendredi saint) en Suisse.
# Prompt et paramètres
Posté par Guillaume D. . Évalué à 2 (+1/-0).
Bonjour,
Super analyse.
J'aurais juste 2 questions :
est-ce que les paramètres (température, topk….) sont bien ceux donnés par le concepteur de chacun des llm ?
souvent la qualité du résultat n'est que le reflet de celle du prompt. Cela vaudrait le coup d'essayer avec un prompt plus professionnel et qui donne les critères d'évaluation au llm.
Hate de voir les résultats avec ces deux remarques si tu en as le temps.
[^] # Re: Prompt et paramètres
Posté par Ecran Plat (site web personnel) . Évalué à 2 (+0/-0).
Merci pour ton retour !
Pour répondre :
J'ai utilisé les paramètres par défaut dans mon environnement (Ollama/OpenWebUI), sans optimisation spécifique pour chaque modèle.
Tout à fait d'accord, la qualité du prompt est déterminante. Mon test était très spontané et non prévu pour publication à la base, mon but était juste de comparer les variantes de Gemma entre elles localement.
Tu as raison, une approche "agentique" avec un prompt structuré donnerait des résultats bien plus qualitatifs. Je manque cruellement de temps pour refaire des tests poussés en ce moment, mais c'est une excellente piste pour une prochaine fois !
# Cas d'usage
Posté par barmic 🦦 . Évalué à 4 (+2/-0). Dernière modification le 04 avril 2026 à 08:25.
Je suis un peu surpris par le cas d'usage testé. Demander une fonction python c'est un truc de développeur, mais un développeur serait à mon avis forcément plus précis dans sa demande.
Il serait intéressant de tester l'outillage. Le modèle ne fait pas tout et si j'ai bien compris, tu as utilisé un mode chat quelconque. OpenCode devrait donner des résultats différents.
Ou alors tester un usage vraiment non développeur et demander un logiciel en python pour traduire un csv en json sans OpenCode
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Cas d'usage
Posté par Ecran Plat (site web personnel) . Évalué à 2 (+0/-0).
C'est vrai que le cas d'usage est basique ! Pour précision, j'ai réalisé ce test via OpenWebUI avec Ollama.
C'est clair qu'avec un outil comme OpenCode, les résultats auraient été probablement plus pertinents. En réalité, mon idée initiale était surtout de tester les deux plus grosses variantes de Gemma 4 pour voir comment elles se comportaient côte à côte, et j'en ai profité pour confronter les autres modèles que j'ai déjà en local sur ma machine. Je ne prévoyais même pas de publier ce test à la base.
Je suis tout à fait d'accord avec toi : tester une approche plus "agentique" avec un prompt bien spécifique aurait certainement donné un bien meilleur résultat. Ça donne de bonnes pistes pour un prochain comparatif !
Malheureusement, je n'aurai pas le temps de m'y replonger pour le moment.
[^] # Re: Cas d'usage
Posté par barmic 🦦 . Évalué à 3 (+1/-0).
Je suis curieux de comment ça va évoluer aujourd'hui on utilise le terme vibe coding pour des pratiques qui ont peut avoir les unes avec les autres.
Si ça se maintient ça va se structurer et pour le moment on manque un peu de vocabulaire pour exprimer des choses bien différentes.
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Cas d'usage
Posté par Tonton Th (site web personnel, Mastodon) . Évalué à 3 (+1/-0).
En tant que vieux développeur retraité qui ne fait plus que du code pour le fun, j'aimerais bien voir la même expérience en demandant à ces cerveaux positroniques d'écrire du Perl ou du Fortran moderne.
Et surtout un peu de réalisme. Je me suis déja confronté avec des CSV de plusieurs milliers de lignes et quelques dizaines de champs. Par exemple, la liste des communes françaises, des relevés météo sur plusieurs semaines, la liste des 100000 étoiles proches de chez nous…
[^] # Re: Cas d'usage
Posté par arnaudus . Évalué à 5 (+2/-0).
En même temps, tout dépend de si tu veux faire un benchmark scientifique ou un retour de cas d'usage. Être capable de fournir une réponse appropriée à une requête unique pas forcément bien formulée est un cas d'usage typique.
On peut se demander aussi quelles seraient les perfs avec un prompt plus spécifique, ou avec des instructions générales plus précises (les trucs que l'on configure dans son compte, du style "privilégie la lisibilité aux performances, utilise des dépendances récentes", etc). Il n'est pas impossible que les plus gros modèles soient plus flexibles sur le style, mais moins performants sur leur première réponse.
Au passage, ça me fait marrer les remarques du style "déja, un humain, il aurait répondu avec une liste de 52 trucs à préciser, un devis, un diagramme de Gantt, un mail avec le responsable hiérarchique en copie, un doodle pour planifier une visio la semaine du 12 mai, un lien vers un formulaire à remplir avec son nom et la date de naissance de sa grand-mère paternelle, les specs du matériel sur lequel ça va tourner, le nombre et la taille des fichiers à lire, et là on aurait pu commencer à discuter". J'ai peur que ça soit exactement pour cette raison que les gens préfèrent le code sans saveur des LLM au code des experts humains; c'est la même raison qui fait préférer une pizza industrielle à un repas à la Tour d'Argent: le rapport qualité prix dans la plupart des contextes est largement au bénéfice de la solution simple.
[^] # Re: Cas d'usage
Posté par barmic 🦦 . Évalué à 2 (+0/-0).
Non. Je vois pas en quoi ça s'oppose d'une quelconque façon. Une démarche scientifique questionne son hypothèse avant même de faire une quelconque expérience.
Ça te fait rire si tu veux mais soit t'es dans un contexte et ta fonction s'inscrit dans un code donc tu en sait plus
Soit non et ce que tu veux c'est un programme complet.
Je sais pas ce que tu t'imagine, mon métier c'est entre autre de mettre à disposition de l'IA. Je ne suis pas contre. Je dis que le cas me semble être un entre deux bizarre. Je sais pas en quoi ça contrarie quelque chose chez toi
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Cas d'usage
Posté par arnaudus . Évalué à 3 (+0/-0).
Il y a juste une opposition entre deux démarches. Je ne dis pas que les deux démarches ne sont pas légitimes dans des contextes appropriés, je dis juste que le fait même de demander des détails te fait entrer dans une démarche que l'utilisateur ne souhaite probablement pas, ce qui paradoxalement rend le choix du LLM grand public encore plus légitime.
Le LLM va simplement inférer les informations manquantes à partir des informations qu'il a sur toi (prompt, historique, et données d'entrainement) pour te fournir une réponse qui est probablement acceptable. D'ailleurs, en général, il termine toujours par quelque chose comme "n'hésitez pas à me donner des détails si votre requête est plus spécifique que ça".
Prend un analogie si tu veux. Va dans un resto et dis au sommelier "donnez-moi un vin qui correspond au plat que j'ai choisi". Le sommelier peut demander "quel est votre budget? en général, vous préférez plutôt le Bordeaux ou le Bourgogne? vous aimez bien les vins doux? avez-vous déja essayé de champagne sec avec les fruits de mer? vous aimez plutôt les surprises ou bien préférez-vous les associations classiques?". Toutes ces questions sont parfaitement légitimes et lui permettront probablement de te conseiller mieux, mais selon le contexte, il me semblerait tout à fait possible que ces questions t'importunent, et que le sommelier fasse mal son métier en te les posant. À vouloir trop en faire, ça devient un mauvais conseiller. Tu as envie de lui arracher la carte des mains et de lui dire "Filez-moi le premier là, n'importe quoi, et lâchez-moi la grappe". Bah là c'est pareil. Tu veux une réponse rapide, parce que peut-être que tu t'en fous, c'est du code jetable, c'est pour comparer avec du code que tu as fait, c'est pour faire un benchmark, c'est pour un exemple dans une présentation pédagogique, c'est pour tester le genre de réponse que les étudiants te donneront s'ils font appel à un LLM pour un devoir maison, bref, plein de raisons possibles de vouloir une réponse et c'est tout, comme pour le vin. Et du coup, à la première question, tu élimines toute la pertinence potentielle de l'expert humain.
[^] # Re: Cas d'usage
Posté par barmic 🦦 . Évalué à 2 (+0/-0).
Ou plutôt « donnez-moi un temps de cuisson ». On parle d’une fonction python, tu ne l’utilise pas en double cliquant dessus ou avec un tape sur ton écran.
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
# et donc?
Posté par devnewton 🍺 (site web personnel) . Évalué à 6 (+3/-0).
C'est quoi la meilleure façon de faire un csv2json en Python pour un lead dev humain véritable ?
Ce post est offensant ? Prévenez moi sur https://linuxfr.org/board
[^] # Re: et donc?
Posté par jtremesay (site web personnel) . Évalué à 8 (+6/-0).
déjà, en tant que lead dev je demanderai des clarifications sur le cahier des charges.
y'a plein de moyen de l’interpréter. La fonction doit créer un fichier json ou retourner une str ? Comment représenter les données ? tableau de tableaux ? structure de tableaux ? tableau de structures ?
CSV d'entrée
Matrices
Structure de tableaux
Tableaux de structures :
Bon, ok, probablement personne ne voudrait la première option. Mais selon les domaines, l'option 2 peut être préférable à la 3 ou réciproquement.
Pis je demanderais à quoi j'ai accès.
Si je suis dans un contexte de datascience, je me fais pas chier et j'utilise polars/pandas
Si je suis forcé d'utiliser la stdlib :
[^] # Re: et donc?
Posté par devnewton 🍺 (site web personnel) . Évalué à 4 (+1/-0). Dernière modification le 07 avril 2026 à 08:45.
Bien vu pour les precisions de spec 🥳.
Sinon la chose qui m'intrigue, c'est s'il est acceptable de charger entièrement le csv en mémoire 🧐?
Ce post est offensant ? Prévenez moi sur https://linuxfr.org/board
[^] # Re: et donc?
Posté par jtremesay (site web personnel) . Évalué à 5 (+3/-0).
En attendant d'avoir un cahier des charger plus précis, je choisi la solution la plus simple pour avoir rapidement un truc fonctionnel.
Si VRAIMENT tu dois convertir des CSV de plusieurs teraoctets, ouvre un ticket.
Envoyer un commentaire
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.