\n\n\n\n Comment ottimizzare l’utilizzo dei token con Milvus (passo dopo passo) - AgntUp \n

Comment ottimizzare l’utilizzo dei token con Milvus (passo dopo passo)

📖 12 min read2,379 wordsUpdated Apr 4, 2026

Come Ottimizzare l’Utilizzo dei Token con Milvus (Passo Dopo Passo)

Gestire in modo efficace l’utilizzo dei token con Milvus può ridurre i costi di calcolo non necessari e rendere i vostri embeddings—e quindi la vostra ricerca vettoriale—molto più rapidi e intelligenti. Sebbene molti considerino “milvus ottimizzare l’utilizzo dei token” come una scatola nera, vi mostrerò esattamente come potete ridurre il flusso di token nei vostri pipeline RAG, nella vostra ricerca vettoriale e nelle vostre query successive senza sacrificare la precisione.

Requisiti

  • Python 3.11+
  • Milvus Server 2.2.9+ (ultima versione stabile a partire dal 21 marzo 2026)
  • pymilvus>=2.2.9
  • Conoscenza di base dei concetti di embeddings e di ricerca vettoriale
  • Accesso a un codificatore vettoriale basato su GPU o CPU (come gli embeddings OpenAI, i modelli Huggingface, o simili)
  • Familiarità con i limiti di token dei vostri LLM (ad esempio, i 8k token di GPT-4) e come influenzano il costo e la latenza

Cosa State Realmente Costruendo

Stiamo progettando un pipeline di ricerca vettoriale che elimina il superfluo delle vostre entrate testuali in modo che Milvus conservi solo ciò che arricchisce realmente il contesto della vostra query, mantenendo allo stesso tempo la qualità degli embeddings. Se avete già inviato tutti i vostri documenti sorgente direttamente in Milvus e avete osservato l’esplosione dei costi e dei conteggi di token, questa è la soluzione.

Passo Dopo Passo

Passo 1 : Misurate i Vostri Token Prima di Convalidare

from transformers import GPT2TokenizerFast

tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")

def count_tokens(text: str) -> int:
 return len(tokenizer.encode(text))

sample_text = "Questo paragrafo sarà tokenizzato e conteggiato per evitare di sprecare token."
print(f"Conteggio dei token : {count_tokens(sample_text)}")

Perché : Se inviate ciecamente testi lunghi così come sono nella fase di embedding, bruciate token che non avete bisogno di pagare o immagazzinare. Il tokenizer GPT-2 è un proxy economico e facile che corrisponde più o meno ai conteggi di token in stile OpenAI. Questo passaggio di conteggio iniziale impedisce che pezzi troppo lunghi si infiltrino in Milvus.

Errori che potreste incontrare : Usare un tokenizer che non corrisponde al vostro LLM porta a un sotto-conteggio o a un sovra-conteggio. Ad esempio, i tokenizzatori Huggingface per T5 differiscono notevolmente da quelli di GPT-3/4. Controllate sempre quale tokenizer è allineato con l’utilizzo del vostro modello.

Passo 2 : Suddividete il Testo in Modo Intelligente – Optate per il Semantico Anziché il Statistico

def chunk_text(text: str, max_tokens: int = 500):
 words = text.split()
 chunks = []
 current_chunk = []
 current_tokens = 0
 for word in words:
 word_tokens = count_tokens(word)
 if current_tokens + word_tokens > max_tokens:
 chunks.append(" ".join(current_chunk))
 current_chunk = [word]
 current_tokens = word_tokens
 else:
 current_chunk.append(word)
 current_tokens += word_tokens
 if current_chunk:
 chunks.append(" ".join(current_chunk))
 return chunks

long_text = " ".join(["parola"] * 2000) # Esempio di lungo testo
split_chunks = chunk_text(long_text, max_tokens=500)
print(f"Creati {len(split_chunks)} pezzi.")

Perché : Suddividere per conteggi di token invece che per lunghezze di caratteri fissi evita di superare accidentalmente i limiti di token nella fase di embedding o di query. Ho visto pipeline bloccarsi o degradarsi perché i conteggi di token sono esplosi in modo inatteso quando sono apparsi spazi o caratteri UTF-8. Il taglio semantico (come i confini delle frasi o i salti di paragrafo) funziona spesso meglio, ma una semplice massimizzazione dei token funziona in modo affidabile.

Errori che potreste incontrare : Le suddivisioni naive dei caratteri creano corrispondenze di query errate—i frammenti di contesto non rappresentano un significato coerente. Pezzi troppo grandi provocano errori API di embedding o vi spingono rapidamente oltre i limiti gratis.

Passo 3 : Deduplicate Prima di Inviare a Milvus

from hashlib import sha256

def deduplicate_chunks(chunks):
 seen = set()
 unique_chunks = []
 for chunk in chunks:
 fingerprint = sha256(chunk.encode("utf-8")).hexdigest()
 if fingerprint not in seen:
 unique_chunks.append(chunk)
 seen.add(fingerprint)
 return unique_chunks

unique_chunks = deduplicate_chunks(split_chunks)
print(f"Deduplicato a {len(unique_chunks)} pezzi unici.")

Perché : La ridondanza è il nemico. Non posso sottolineare abbastanza questo punto—molti set di dati reali presentano ripetizioni strane, che si tratti di PDF corrotti o di log. La deduplicazione evita il desapre di token di embedding e di storage in Milvus, risparmiando denaro e prevenendo il rumore di ricerca in seguito.

Errori che potreste incontrare : Saltare la deduplicazione riempie Milvus di vettori duplicati, rallenta la ricerca e gonfia lo storage. Il vostro budget basato sui token esploderà.

Passo 4 : Codificate i Pezzi in Vettori in Modo Efficiente

from sentence_transformers import SentenceTransformer

model = SentenceTransformer('all-MiniLM-L6-v2')

def encode_chunks(chunks):
 embeddings = model.encode(chunks, convert_to_tensor=True)
 return embeddings

embeddings = encode_chunks(unique_chunks)
print(f"Forma degli embeddings prodotti : {embeddings.shape}")

Perché : Scegliete modelli di embedding più piccoli e veloci a meno che non abbiate specificamente bisogno dei più grandi transformer per una precisione semantica. Per la maggior parte delle applicazioni, modelli come “all-MiniLM-L6-v2” rappresentano il miglior compromesso tra dimensione vettoriale (384), velocità e budget di token. Gli embeddings ad alta dimensione non sono sempre migliori; possono gonfiare il vostro indice Milvus e rallentare la ricerca.

Errori che potreste incontrare : Tentare di usare gli embeddings OpenAI per migliaia di lunghi pezzi senza pre-elaborazione brucerà token e raggiungerà rapidamente i limiti di rate dell’API. Inoltre, l’embedding senza batching riduce il throughput.

Passo 5 : Archivia con Metadati per Filtrare il Contesto

from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection

connections.connect("default", host="localhost", port="19530")

fields = [
 FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
 FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=384),
 FieldSchema(name="token_count", dtype=DataType.INT64),
 FieldSchema(name="chunk_text", dtype=DataType.VARCHAR, max_length=1024)
]

schema = CollectionSchema(fields, "Pezzi di documenti con metadati di token")
collection = Collection("doc_chunks", schema)

token_counts = [count_tokens(chunk) for chunk in unique_chunks]

entities = [
 token_counts,
 embeddings.tolist(),
 unique_chunks
]

collection.insert(entities)
collection.create_index("embedding", {"index_type": "IVF_FLAT", "params": {"nlist": 128}, "metric_type": "L2"})
collection.load()

Perché : Archiviare i conteggi di token accanto agli embeddings vi permette di filtrare o ordinare i pezzi a basso costo senza dover retokenizzare in seguito. I metadati dei token riducono le query che tentano di comprimere troppo contesto—e vi danno il controllo sulla dimensione del payload di Milvus al momento della ricerca.

Passo 6 : Interrogate Tenendo a Mente i Budget dei Token

def search_similar(query: str, top_k=5, max_query_tokens=1000):
 query_token_count = count_tokens(query)
 if query_token_count > max_query_tokens:
 raise ValueError(f"La query supera il budget di token : {query_token_count} > {max_query_tokens}")

 query_embedding = model.encode([query])[0].tolist()
 results = collection.search(
 [query_embedding],
 "embedding",
 param={"metric_type": "L2", "params": {"nprobe": 10}},
 limit=top_k,
 output_fields=["token_count", "chunk_text"]
 )
 
 filtered_results = [res for res in results[0] if res.entity.get("token_count", 0) + query_token_count < max_query_tokens]
 return filtered_results

query = "Utilizzo efficiente dei token con Milvus"
result_docs = search_similar(query)
for hit in result_docs:
 print(hit.entity.get("chunk_text"))

Perché : La finestra di contesto del vostro LLM è preziosa. Se dimenticate di controllare i vostri token di query più i token di pezzi pertinenti, superate i vostri limiti—il che porta a errori o a prompt troncati. Il filtraggio di Milvus basato sui metadati dei token archiviati vi aiuta a rimanere dinamicamente entro il budget.

Errori che potreste incontrare : Passare set di token combinati troppo grandi al vostro generatore porta a fallimenti di completamento o a salti di contesto strani. Una volta, ho avuto un crash di sistema dopo aver ignorato i limiti di token. Non è stato divertente.

Le Insidie

  1. Il Conte dei Token dell'API di Embedding Ti Danneggerà: Gli embedding di OpenAI contano token che potresti non aspettarti sempre, come i token di invito impliciti o i separatori. Esegui sempre test a secco con conteggi per pezzo prima di fare embedding in massa.
  2. I Costi di Archiviazione di Milvus Crescono Rapidamente: Il deposito Milvus sotto licenza Apache-2.0 milvus-io/milvus ha 43.421 stelle—sì, è popolare—ma la dimensione vettoriale e il numero di vettori che archivi provocano un uso rapido di RAM/archiviazione. Vettori sovradimensionati senza potatura dei token aumentano i costi.
  3. I Tokenizers non Sono Compatibili: Se il tokenizer per la creazione dei pezzi e il tokenizer del tuo LLM non corrispondono, ti troverai in una situazione di sovrastima o sottostima dei token. Usa il tokenizer esatto di cui ha bisogno il tuo LLM.
  4. Tempo di Creazione dell'Indice & Memoria: Usare grandi valori nlist negli indici IVF_FLAT migliora il richiamo ma aggiunge latenza e consumo di RAM. Trova il tuo giusto equilibrio. Di solito inizio da nlist=128.
  5. Coerenza dei Pezzi vs Dimensione: Pezzi più grandi contengono più contesto ma costano più token. Pezzi più piccoli causano frammentazione e riducono la precisione. Fai esperimenti.

Codice Completo

from transformers import GPT2TokenizerFast
from sentence_transformers import SentenceTransformer
from hashlib import sha256
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection

# Passo 1: Inizializzare il tokenizer e i modelli
tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")
model = SentenceTransformer('all-MiniLM-L6-v2')

def count_tokens(text: str) -> int:
 return len(tokenizer.encode(text))

def chunk_text(text: str, max_tokens: int = 500):
 words = text.split()
 chunks = []
 current_chunk = []
 current_tokens = 0
 for word in words:
 word_tokens = count_tokens(word)
 if current_tokens + word_tokens > max_tokens:
 chunks.append(" ".join(current_chunk))
 current_chunk = [word]
 current_tokens = word_tokens
 else:
 current_chunk.append(word)
 current_tokens += word_tokens
 if current_chunk:
 chunks.append(" ".join(current_chunk))
 return chunks

def deduplicate_chunks(chunks):
 seen = set()
 unique_chunks = []
 for chunk in chunks:
 fingerprint = sha256(chunk.encode("utf-8")).hexdigest()
 if fingerprint not in seen:
 unique_chunks.append(chunk)
 seen.add(fingerprint)
 return unique_chunks

def encode_chunks(chunks):
 embeddings = model.encode(chunks, convert_to_tensor=True)
 return embeddings

# Connettersi a Milvus
connections.connect("default", host="localhost", port="19530")

# Definire lo schema
fields = [
 FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
 FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=384),
 FieldSchema(name="token_count", dtype=DataType.INT64),
 FieldSchema(name="chunk_text", dtype=DataType.VARCHAR, max_length=1024)
]
schema = CollectionSchema(fields, "Pezzi di documento con metadati sui token")

collection = Collection("doc_chunks", schema)

def insert_chunks(chunks):
 unique_chunks = deduplicate_chunks(chunks)
 embeddings = encode_chunks(unique_chunks)
 token_counts = [count_tokens(chunk) for chunk in unique_chunks]

 entities = [
 token_counts,
 embeddings.tolist(),
 unique_chunks
 ]

 collection.insert(entities)
 collection.create_index("embedding", {"index_type": "IVF_FLAT", "params": {"nlist": 128}, "metric_type": "L2"})
 collection.load()

def search_similar(query: str, top_k=5, max_query_tokens=1000):
 query_token_count = count_tokens(query)
 if query_token_count > max_query_tokens:
 raise ValueError(f"Il numero di token della query ({query_token_count}) supera il limite ({max_query_tokens})")

 query_embedding = model.encode([query])[0].tolist()
 results = collection.search(
 [query_embedding],
 "embedding",
 param={"metric_type": "L2", "params": {"nprobe": 10}},
 limit=top_k,
 output_fields=["token_count", "chunk_text"]
 )

 filtered_results = [res for res in results[0] if res.entity.get("token_count", 0) + query_token_count < max_query_tokens]
 return filtered_results

# Esempio di utilizzo
if __name__ == "__main__":
 raw_text = ("Questo è un esempio di paragrafo che ci piacerebbe suddividere, deduplicare, incorporare e archiviare. " * 100)
 chunks = chunk_text(raw_text)
 insert_chunks(chunks)

 query = "utilizzo dei token in un esempio di paragrafo"
 found = search_similar(query)
 for hit in found:
 print(hit.entity.get("chunk_text"))

E adesso

Ora che hai padroneggiato la proliferazione dei token in Milvus, il passo logico successivo è implementare un taglio dinamico degli inviti di query, il che significa che la tua applicazione deve monitorare la lunghezza combinata dei token (query più contesto recuperato) e automaticamente eliminare o riformulare i pezzi a basso valore prima di chiamare il tuo LLM. Questo ti farà risparmiare denaro e eviterà errori di limite dei token durante l'esecuzione in produzione.

FAQ

Q: Come posso confermare che i miei conteggi di token corrispondano a quelli del LLM?

A: La migliore cosa da fare è usare il tokenizer fornito dal tuo LLM. Per i modelli OpenAI, tiktoken è il tokenizer canonico. Il tokenizer GPT-2 è un proxy ragionevole ma non preciso. Esegui sempre casi di test con il conteggio del tuo modello per verificare.

Q: Qual è il numero massimo di vettori che Milvus può gestire prima che le prestazioni ne risentano?

A: Milvus è ottimizzato per milioni di vettori, ma in pratica, il tuo tipo di indice, la dimensione del vettore e l'hardware determinano le prestazioni. Ad esempio, IVF_FLAT con nlist=128 è gestibile a qualche milione di vettori su server adeguati, ma la latenza e la RAM possono aumentare senza elaborazione in blocco e potatura.

Q: Posso automatizzare la potatura dei token durante l'inserimento?

A: Assolutamente, ma fai attenzione. Puoi eliminare o riassumere i pezzi che superano i limiti di token prima dell'integrazione, ma una potatura eccessiva riduce la ricchezza semantica, danneggiando la qualità della ricerca a valle. Usa soglie adattive regolate sul tuo set di dati.

Riepilogo delle statistiche di Milvus

Metrica Valore Commento
Stelle GitHub 43.421 Indica una forte adozione e supporto della comunità
Forks 3.909 Mostra un contributo attivo e casi d'uso personalizzati
Problemi aperti 1.098 Indica che il sviluppo è in corso e che ci sono problemi da risolvere
Licenza Apache-2.0 Licenza permissiva favorevole a un uso aziendale
Ultimo aggiornamento 21 marzo 2026 Il progetto è attivamente mantenuto

Raccomandazioni per diversi tipi di sviluppatori

1. L'hacker di startup: Se stai costruendo MVP rapidamente, concentrati su modelli di integrazione pronti all'uso come 'all-MiniLM-L6-v2' e su un semplice taglio dei token per ridurre la deriva e i costi. Usa l'indicizzazione integrata di Milvus e monitora il tuo utilizzo dei token con contatori semplici.

2. Il data scientist: Sperimenta con approcci di taglio semantico: prova il rilevamento dei confini di frase o l'encoding dei paragrafi per migliorare la fedeltà delle integrazioni. Incorpora metadati sul conteggio dei token per la potatura al momento della query. Dovresti anche considerare un affinamento dell'integrazione basato sulla complessità dei token dei pezzi.

3. L'ingegnere d'impresa: Costruisci un pipeline adattiva che includesse un monitoraggio in tempo reale del budget di token, la deduplicazione dei pezzi, la dimensionalità dinamica dei vettori e la regolazione dell'indice su Milvus. Integra strettamente le tue pipeline LLM per evitare scenari di sovraccarico e ottimizzare le spese informatiche.

Dati al 21 marzo 2026. Fonti: https://github.com/milvus-io/milvus, Limiti dei token Milvus LangChain, Ottimizzazione LLM Milvus

Articoli Correlati

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: Best Practices | CI/CD | Cloud | Deployment | Migration
Scroll to Top