Types de Données et Dimensions
Mis à jour le 29 juillet 2026
Optimiser taille et qualité
codestral-embed offre un contrôle précis sur deux axes : le nombre de dimensions et le type de données (dtype) des valeurs. Ces paramètres permettent d’ajuster le compromis entre qualité de la recherche et coût de stockage/calcul.
L’enjeu devient concret dès que les volumes montent. Un index de deux millions de fonctions en 1536 dimensions float pèse environ douze gigaoctets et ne tient plus en mémoire sur une machine ordinaire ; le même index en int8 sur 768 dimensions descend sous le gigaoctet et redevient interrogeable en temps réel. C’est cette arithmétique, et non une préférence esthétique, qui doit guider vos choix.
Les cinq types de sortie
float (défaut)
Le type float produit des valeurs en virgule flottante 32 bits. C’est le format le plus précis, idéal quand la qualité prime sur l’espace de stockage.
from mistralai import Mistral
client = Mistral(api_key=api_key)
response = client.embeddings.create(
model="codestral-embed",
output_dtype="float",
inputs=["def hello(): print('world')"],
)
embedding = response.data[0].embedding
print(f"Type: float, Valeurs: {embedding[:5]}")
# [0.0234375, -0.15625, 0.08984375, 0.01171875, -0.046875]
int8
Chaque dimension est un entier entre -128 et 127. Utilise 4x moins de mémoire que float32 avec une perte de qualité minime. Comparez les valeurs affichées avec celles de l’exemple précédent : c’est le même vecteur, quantifié sur une échelle plus grossière, et le classement des résultats reste presque inchangé.
response = client.embeddings.create(
model="codestral-embed",
output_dtype="int8",
inputs=["def hello(): print('world')"],
)
embedding = response.data[0].embedding
print(f"Type: int8, Valeurs: {embedding[:5]}")
# [3, -20, 11, 1, -6]
uint8
Similaire à int8 mais avec des valeurs entre 0 et 255 (non signées). Utile pour certains moteurs de recherche vectorielle qui n’acceptent que des valeurs positives — une contrainte que vous découvrez généralement au moment de l’intégration, pas avant.
response = client.embeddings.create(
model="codestral-embed",
output_dtype="uint8",
inputs=["def hello(): print('world')"],
)
embedding = response.data[0].embedding
print(f"Type: uint8, Valeurs: {embedding[:5]}")
# [131, 108, 139, 129, 122]
binary
Le format le plus compact. Chaque dimension est quantisée en 1 bit, puis les bits sont regroupés par paquets de 8 dans des valeurs int8. Le vecteur résultant est 32x plus petit que float — la longueur de 192 affichée ci-dessous correspond bien aux 1536 dimensions d’origine, empaquetées huit par huit.
response = client.embeddings.create(
model="codestral-embed",
output_dtype="binary",
inputs=["def hello(): print('world')"],
)
embedding = response.data[0].embedding
print(f"Type: binary, Longueur: {len(embedding)}")
# Longueur: 192 (au lieu de 1536 en float)
ubinary
Identique à binary mais avec des valeurs uint8 (0-255) au lieu de int8 (-128 à 127). Le choix entre les deux relève de ce qu’accepte votre moteur de stockage en aval, pas de la qualité de recherche.
Impact sur la qualité
Les chiffres de compression ne disent rien de ce que vous perdez réellement. La fonction suivante mesure la chose sur un cas concret : un test de palindrome, interrogé en français, encodé successivement avec trois dtypes. Les similarités obtenues vous donnent l’ordre de grandeur de la dégradation sur votre propre matière.
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
def compare_dtypes(code_snippet, query):
"""Comparer la qualité de recherche selon le dtype."""
dtypes = ["float", "int8", "uint8"]
results = {}
for dtype in dtypes:
# Encoder le code et la requête avec le même dtype
resp_code = client.embeddings.create(
model="codestral-embed",
output_dtype=dtype,
inputs=[code_snippet],
)
resp_query = client.embeddings.create(
model="codestral-embed",
output_dtype=dtype,
inputs=[query],
)
emb_code = np.array(resp_code.data[0].embedding, dtype=np.float32)
emb_query = np.array(resp_query.data[0].embedding, dtype=np.float32)
sim = cosine_similarity([emb_code], [emb_query])[0][0]
results[dtype] = sim
return results
# Tester
code = "def is_palindrome(s): return s == s[::-1]"
query = "fonction qui vérifie si un mot est un palindrome"
scores = compare_dtypes(code, query)
for dtype, score in scores.items():
print(f" {dtype:8s}: similarité = {score:.4f}")
Notez que le code et la requête sont toujours encodés avec le même dtype à l’intérieur de la boucle. Mélanger les types entre l’index et la requête produirait des scores incohérents, et l’erreur est d’autant plus vicieuse qu’elle ne lève aucune exception.
Réduire les dimensions
Le paramètre output_dimension contrôle le nombre de dimensions du vecteur. La boucle ci-dessous parcourt six valeurs et affiche pour chacune l’empreinte mémoire d’un seul vecteur, en float puis en int8.
import numpy as np
# Comparer différentes dimensions
dims = [256, 512, 768, 1024, 1536, 3072]
for dim in dims:
response = client.embeddings.create(
model="codestral-embed",
output_dimension=dim,
inputs=["def quicksort(arr): ..."],
)
emb = response.data[0].embedding
# Taille mémoire approximative
size_float32 = dim * 4 # 4 octets par float32
size_int8 = dim * 1 # 1 octet par int8
print(f" {dim:5d} dims -> {size_float32:6d} octets (float) | {size_int8:5d} octets (int8)")
Sortie :
256 dims -> 1024 octets (float) | 256 octets (int8)
512 dims -> 2048 octets (float) | 512 octets (int8)
768 dims -> 3072 octets (float) | 768 octets (int8)
1024 dims -> 4096 octets (float) | 1024 octets (int8)
1536 dims -> 6144 octets (float) | 1536 octets (int8)
3072 dims -> 12288 octets (float) | 3072 octets (int8)
Multipliez la colonne de droite par votre nombre réel de vecteurs et vous obtenez immédiatement le dimensionnement de votre serveur. Entre 3072 dimensions en float et 768 en int8, le rapport est de seize : le même index passe de douze gigaoctets à sept cent cinquante mégaoctets.
Guide de choix
Les configurations suivantes couvrent les situations les plus fréquentes :
| Contexte | Configuration | Motif |
|---|---|---|
| Prototype / développement | float + 1536 dims | défaut, aucun compromis |
| Production standard | float + 1024 dims | bon compromis qualité/coût |
| Gros volume (millions de vecteurs) | int8 + 768 dims | 4x plus compact |
| Recherche en temps réel à grande échelle | binary + 1536 dims | pré-filtrage rapide, puis re-rank en float |
| Embarqué / edge | int8 + 256 dims | minimum viable |
La ligne « temps réel » décrit une architecture en deux temps qu’il vaut la peine de comprendre : l’index binaire, très léger, sert à ramener quelques centaines de candidats en quelques millisecondes ; ces candidats seulement sont ensuite reclassés avec les vecteurs float, plus coûteux mais bien plus fins. Vous obtenez la vitesse du binaire et, sur la tête de liste, la précision du float.
Points clés à retenir
- codestral-embed supporte 5 types de sortie : float, int8, uint8, binary, ubinary
- Le type binary est 32x plus compact que float, avec une perte de qualité acceptable pour le pré-filtrage
- Les premières dimensions contiennent le plus d’information (Matryoshka representation)
- Combinez dimension réduite + int8 pour des index très compacts
- Testez toujours sur vos données réelles avant de choisir les paramètres de production