Aller au contenu principal

Types de Données et Dimensions

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.

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.

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.

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.

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).

Impact sur la qualité

Voici un comparatif pratique de la qualité de recherche selon le dtype :

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}")

Réduire les dimensions

Le paramètre output_dimension contrôle le nombre de dimensions du vecteur :

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)

Guide de choix

Voici les recommandations selon votre contexte :

  • 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)

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