Aller au contenu principal

Format JSONL, custom_id et Upload de Fichiers

Le format JSONL : colonne vertébrale du Batch Inference

Le format JSONL (JSON Lines) est le standard utilisé par Mistral pour structurer vos requêtes batch. Chaque ligne du fichier est un objet JSON autonome représentant une requête individuelle. Ce format est simple à générer, facile à déboguer, et parfaitement adapté au traitement ligne par ligne.

Structure d’une requête JSONL

Chaque ligne de votre fichier JSONL contient deux champs obligatoires :

{
  "custom_id": "req-001",
  "body": {
    "max_tokens": 100,
    "messages": [
      {"role": "user", "content": "Résumez ce document en 3 points."}
    ]
  }
}

Le champ custom_id

Le custom_id est un identifiant unique que vous définissez pour chaque requête. Il vous permet de faire le lien entre vos requêtes et les résultats retournés. Mistral ne garantit pas l’ordre de traitement : c’est le custom_id qui vous permet de raccrocher chaque réponse à la bonne requête d’origine.

Bonnes pratiques pour vos custom_id :

  • Utilisez un format prévisible : doc-001, email-2024-03-15-042, product-sku-ABC123
  • Assurez l’unicité au sein du fichier — les doublons provoquent des erreurs
  • Gardez-les courts mais informatifs pour faciliter le débogage

Le champ body

Le body contient exactement la même structure que vous utiliseriez pour un appel API synchrone à l’endpoint cible. Si vous ciblez /v1/chat/completions, le body est identique à ce que vous passeriez dans un appel client.chat.complete().

Préparer un fichier JSONL en Python

Voici comment générer programmatiquement un fichier JSONL à partir d’une liste de documents :

import json

documents = [
    {"id": "doc-001", "text": "L'intelligence artificielle transforme..."},
    {"id": "doc-002", "text": "Les réseaux de neurones profonds..."},
    {"id": "doc-003", "text": "Le traitement du langage naturel..."},
]

with open("batch_requests.jsonl", "w", encoding="utf-8") as f:
    for doc in documents:
        request = {
            "custom_id": doc["id"],
            "body": {
                "model": "mistral-small-latest",
                "max_tokens": 200,
                "messages": [
                    {
                        "role": "system",
                        "content": "Vous êtes un assistant qui résume des textes."
                    },
                    {
                        "role": "user",
                        "content": f"Résumez ce texte : {doc['text']}"
                    }
                ]
            }
        }
        f.write(json.dumps(request, ensure_ascii=False) + "\n")

Point important : utilisez ensure_ascii=False pour préserver les caractères accentués dans vos requêtes en français.

Uploader le fichier sur Mistral

Via l’API Python (recommandé en production)

from mistralai import Mistral

client = Mistral(api_key="votre-clé-api")

# Upload du fichier JSONL
with open("batch_requests.jsonl", "rb") as f:
    batch_file = client.files.upload(
        file=("batch_requests.jsonl", f),
        purpose="batch"
    )

print(f"Fichier uploadé : {batch_file.id}")
print(f"Taille : {batch_file.bytes} octets")
print(f"Statut : {batch_file.purpose}")

Le paramètre purpose="batch" indique à Mistral que ce fichier est destiné au traitement batch et non à d’autres fonctionnalités (fine-tuning, RAG, etc.).

Via AI Studio (interface graphique)

Pour les tests rapides ou les équipes non-techniques :

  1. Rendez-vous sur console.mistral.ai/build/files
  2. Cliquez sur “Upload”
  3. Sélectionnez votre fichier JSONL
  4. Choisissez le purpose “Batch Processing”

L’interface vous retourne un file_id que vous utiliserez pour créer le job batch.

Validation du fichier

Avant de soumettre un batch, vérifiez votre fichier :

import json

errors = []
seen_ids = set()

with open("batch_requests.jsonl", "r", encoding="utf-8") as f:
    for line_num, line in enumerate(f, 1):
        try:
            data = json.loads(line)
        except json.JSONDecodeError as e:
            errors.append(f"Ligne {line_num}: JSON invalide - {e}")
            continue

        # Vérifier les champs obligatoires
        if "custom_id" not in data:
            errors.append(f"Ligne {line_num}: custom_id manquant")
        if "body" not in data:
            errors.append(f"Ligne {line_num}: body manquant")

        # Vérifier l'unicité des custom_id
        cid = data.get("custom_id")
        if cid in seen_ids:
            errors.append(f"Ligne {line_num}: custom_id dupliqué '{cid}'")
        seen_ids.add(cid)

if errors:
    print(f"{len(errors)} erreur(s) trouvée(s) :")
    for e in errors:
        print(f"  - {e}")
else:
    print(f"Fichier valide : {len(seen_ids)} requêtes prêtes.")

Limites et contraintes

  • Taille maximale : 1 million de lignes par fichier (file batching)
  • Encodage : UTF-8 obligatoire
  • Format : une requête JSON par ligne, pas de JSON multi-lignes
  • custom_id : doit être unique dans le fichier
  • body : doit correspondre au schéma de l’endpoint ciblé

Points clés à retenir

  • Le format JSONL structure vos requêtes batch avec un objet JSON par ligne
  • Chaque requête a un custom_id unique et un body conforme à l’endpoint cible
  • L’upload se fait via l’API Python (client.files.upload) ou via AI Studio
  • Validez toujours votre fichier avant soumission pour éviter les erreurs de traitement
  • Utilisez ensure_ascii=False pour le français et les caractères accentués