Christy Bergman : Pourquoi j’ai rejoint Zilliz
Je m’appelle Christy Bergman, et j’ai récemment rejoint Zilliz en tant que Developer Advocate basée à San Francisco. Je vais organiser des événements, y assister et y prendre la parole, rédiger des blogs et des tutoriels de code, améliorer la documentation, et aider globalement les gens (comme vous, je l’espère !) à apprendre à utiliser Milvus, la base de données vectorielle open source la plus populaire au monde (mesurée en nombre d’étoiles GitHub).
Avant Zilliz, j’étais Developer Advocate chez Anyscale, le créateur open source de Ray, qui rend le calcul distribué facile pour tous les développeurs. Avant cela, j’étais AWS AI/ML Specialist Solutions Architect, spécialisée dans la prévision par deep learning.
Alors pourquoi ai-je choisi de rejoindre Zilliz ? Tout a commencé par ma curiosité pour l’amélioration des sorties de chat de ChatGPT en injectant du contexte dans le prompt. J’ai ensuite commencé une quête pour expérimenter avec les embeddings, et à partir de là, j’ai commencé à chercher une base de données vectorielle facile à utiliser et rapide. Dans cet article de blog, je vais vous présenter les étapes qui m’ont menée ici.
Le doute : ai-je vraiment besoin d’une base de données vectorielle ?
Au départ, je me suis demandé si une base de données vectorielle était vraiment nécessaire. Cependant, quelques tentatives d’intégration de texte dans une variable Python, puis de sérialisation et désérialisation avec pickle, m’ont convaincue que les embeddings devaient être mis en cache ou persistés quelque part de mieux que pickle.
Milvus est une base de données complète conçue dès le départ spécifiquement pour les vecteurs. Des milliers de développeurs dans le monde utilisent Milvus, qui prend en charge de nombreux algorithmes de recherche vectorielle différents, des métriques de distance dans l’espace vectoriel, ainsi que d’autres fonctionnalités comme Insert/upsert, TopK et Range Search, la prise en charge GPU, et bien plus encore. La version commerciale s’appelle Zilliz Cloud et offre une disponibilité SLA de 99,9 %, l’auto-scaling, fonctionne sur AWS et GCP (Azure bientôt disponible), et vous pouvez l’exécuter sur votre compte cloud avec une conformité SOC2 complète.
Explorer les options : essayer différentes bases de données vectorielles
Pour intégrer des embeddings dans une base de données vectorielle, il vous faut : 1) des données non structurées, 2) un plan pour découper ces données, 3) un modèle d’embedding, et 4) une base de données vectorielle.
Pour les données, j’ai utilisé le jeu de données IMDB de grandes critiques de films du Stanford AI Lab. Il s’agit d’un jeu de 50 000 données traité de manière pratique (ratio d’échantillonnage 50:50 d’avis positifs/négatifs). Ces données comportent les colonnes suivantes : movie_index, texte brut de la critique, et note du film.
Pour le découpage, j’ai choisi de conserver les critiques de films entières, sauf lorsqu’elles étaient très longues. Pour les critiques très longues, j’ai utilisé les morceaux de longueur 512 par défaut habituels. Cela signifie que les longues critiques ont été divisées en plusieurs morceaux de 512 caractères. Dans le jargon des LLM, on appelle cela la “chunk size”.
Pour le modèle d’embedding, j’ai essayé différents modèles, y compris les omniprésents embeddings d’OpenAI. Jusqu’à ce que je comprenne que le plus simple était simplement de sélectionner la cible toujours mouvante du plus petit modèle, le mieux classé dans l’onglet Retriever du classement MTEB HuggingFace. À l’époque, j’ai opté pour “e5-base-v2”. C’est en réalité une bonne chose que le choix du modèle d’embedding soit indépendant de la base de données vectorielle elle-même.
Pour les bases de données, j’ai essayé FAISS, Qdrant, Chroma, Weaviate, Pinecone, et, bien sûr, Milvus. Je les ai toutes soumises aux mêmes tests : 1) Est-il facile et rapide de charger directement depuis pandas dans la base de données vectorielle ? 2) Est-il facile, rapide et configurable d’obtenir de bons résultats de requête depuis la base de données vectorielle ? 3) Est-il facile et configurable d’effectuer du RAG avec LangChain (futur article de blog !).
Milvus se démarque
Parmi toutes les bases de données que j’ai explorées, Milvus a retenu mon attention pour plusieurs raisons. Tout d’abord, il offrait une expérience conviviale, en particulier lors de l’insertion de données directement depuis pandas avec des métadonnées, puisque c’est la première approche qu’un Data Scientist pourrait essayer.
Milvus a également retenu mon attention en raison de sa rapidité de chargement des vecteurs et d’interrogation. Milvus était nettement plus réactif que d’autres approches, dont certaines étaient lentes, même à cette petite échelle. J’ai également remarqué les fonctionnalités et choisi les paramètres par défaut pour les autres bases de données (recherche exhaustive IVF-flat avec métrique L2), même si Milvus prend en charge d’autres choix.
Vous trouverez ci-dessous un gist pour insérer une trame de données pandas dans Milvus. Le code complet est sur mon GitHub.
# Complete code is at: https://github.com/christy/ZillizDemos/blob/main/milvus_onboarding/hello_world_milvus.ipynb
###########
# 1. Download to use locally, a sentence transformer from HuggingFace Hub.
###########
import os
from dotenv import load_dotenv, find_dotenv
from huggingface_hub import login
_ = load_dotenv(find_dotenv())
hub_token = os.getenv("HUGGINGFACEHUB_API_TOKEN")
login(token=hub_token);
from sentence_transformers import SentenceTransformer
model_name = "BAAI/bge-base-en-v1.5"
retriever = SentenceTransformer(model_name, device="cuda")
# Get the model parameters and save for later.
MAX_SEQ_LENGTH = retriever.get_max_seq_length()
HF_EOS_TOKEN_LENGTH = 1
EMBEDDING_LENGTH = retriever.get_sentence_embedding_dimension()
###########
# 2. Choose a chunking function from LangChain for convenience.
###########
from langchain.text_splitter import RecursiveCharacterTextSplitter
chunk_size = MAX_SEQ_LENGTH - HF_TOKEN_EOS_LENGTH
chunk_overlap = np.round(chunk_size * 0.10, 0)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size,
chunk_overlap=chunk_overlap,
length_function=len,
)
def chunk_text(text):
chunks = text_splitter.split_text(text)
return [chunk for chunk in chunks if chunk]
###########
# 3. Manipulate a pandas dataframe.
# Download: https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
###########
# 1. Batch of data from pandas DataFrame.
batch = df.head(100).copy()
# 2. Change primary key type to string.
batch["movie_index"] = batch["movie_index"].apply(lambda x: str(x))
# 3. Truncate reviews to 512 characters.
batch['chunk'] = batch['text'].apply(chunk_text)
batch = batch.explode('chunk', ignore_index=True)
# 4. Add embeddings as new column in df.
review_embeddings = torch.tensor(retriever.encode(batch['chunk']))
# Normalize embeddings to unit length.
review_embeddings = F.normalize(review_embeddings, p=2, dim=1)
# 5. Convert embeddings to list of `numpy.ndarray`, each containing `numpy.float32` numbers.
converted_values = list(map(np.float32, review_embeddings))
batch['embeddings'] = converted_values
# 6. Reorder columns for conveneince, so index first, labels at end.
new_order = ["movie_index", "text", "chunk", "embeddings", "label_int", "label"]
batch = batch[new_order]
###########
# 4. Install and import milvus.
###########
!pip install milvus pymilvus
import milvus, pymilvus
###########
# 5. Define schema for data loading into Milvus.
###########
# Set the Milvus collection name.
COLLECTION_NAME = "movies"
fields = [
FieldSchema(name="pk", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="movie_index", dtype=DataType.VARCHAR, max_length=8),
FieldSchema(name="chunk", dtype=DataType.VARCHAR, max_length=MAX_SEQ_LENGTH),
FieldSchema(name="embeddings", dtype=DataType.FLOAT_VECTOR, dim=EMBEDDING_LENGTH),
FieldSchema(name="label_int", dtype=DataType.INT64),
FieldSchema(name="label", dtype=DataType.VARCHAR, max_length=8),
]
schema = CollectionSchema(fields, "Search imdb movie reviews")
mc = Collection(COLLECTION_NAME, schema, consistency_level="Eventually")
###########
6. Démarrer un serveur Milvus local (lite).
###########
default_server.start()
connections.connect(host='127.0.0.1',
port=default_server.listen_port,
show_startup_banner=True)
###########
# 7. Insérer des données dans Milvus.
###########
# Montrer comment modifier les paramètres de l’index, au lieu d’utiliser les valeurs par défaut.
index_params = {
"index_type": "HNSW",
"metric_type": "COSINE",
"params": {'M': 16, # int. 4~64, num_layers
"efConstruction": 32} # int. 8~512, num_nearest_neighbors
}
mc.create_index("embeddings", index_params)
insert_result = mc.insert(batch)
# Une fois la dernière entité insérée, appeler flush pour arrêter les segments en croissance restés en mémoire.
mc.flush()
###########
# 8. Interroger la base de données.
###########
# Avant d’effectuer une recherche ou une requête, vous devez charger les données en mémoire.
mc.load()
# Définir un exemple de question à propos de vos données.
query = "I'm a medical doctor, what movie should I watch?"
# Intégrer la requête avec le même modèle d’embedding que celui utilisé pour créer la collection Milvus.
query_embeddings = torch.tensor(retriever.encode([query]))
# Normaliser les embeddings à une longueur unitaire.
query_embeddings = torch.nn.functional.normalize(query_embeddings, p=2, dim=1)
# Convertir les embeddings en liste de listes de np.float32.
query_embeddings = list(map(np.float32, query_embeddings))
# Exécuter une recherche vectorielle avec l’index HNSW.
TOP_K = 3
search_params = {
"M": 16,
"ef": 32,
}
results = mc.search(
data=query_embeddings,
anns_field="embeddings",
param=search_params,
output_fields=["movie_index", "chunk", "label"],
limit=TOP_K,
consistency_level="Eventually"
)
Après mes tests (rapides et non officiels), j’ai rempli un formulaire en ligne pour postuler à un poste de Developer Advocate chez Zilliz. Après mon dernier entretien, l’équipe de Zilliz a rapidement décidé de me faire une offre. Donc, sans hésiter, j’ai accepté !
J’ai des collègues formidables. Consultez les blogs de Yujian Tang et de Frank Liu pour savoir pourquoi ils ont rejoint Zilliz. Ma responsable, Chris Churilo, est le liant secret qui explique pourquoi nous travaillons tous ensemble avec autant d’efficacité. Elle utilise ses connaissances et son expérience pour nous faire tous briller. Mon collègue Filip Haltmayer est exceptionnellement patient et doué pour m’expliquer tout ce qui concerne Milvus et Zilliz pendant mon intégration. Notre CEO, Charles Xie, a eu la vision initiale en 2017 de construire une base de données, en particulier pour les données non structurées.
Et maintenant
Alors que je commence mon travail d’évangélisation pour Milvus, j’ai hâte de faire la connaissance de vous tous dans la communauté des développeurs IA ! J’organiserai le Meetup Unstructured Data à San Francisco, où je suis toujours à la recherche d’excellents intervenants, de lieux et de co-organisateurs (contactez-moi, s’il vous plaît !). Je vais bloguer et prendre la parole davantage (n’hésitez pas à me contacter !). Si vous voulez essayer Milvus open source dans votre projet de données non structurées, dites-moi comment je peux vous aider !
Je suis impliquée dans plusieurs organisations de data science à impact positif, notamment DataKind, Women in Data Science, et les San Francisco Civil Hack nights de Code for America (qui m’ont fait découvrir mon organisation locale Sonoma Safe Agriculture, où j’ai créé une carte interactive des pesticides). Rejoignez-moi également alors que j’apporte mes nouveaux apprentissages sur les bases de données vectorielles à la communauté élargie de la data-science-for-good.
Continuer à lire
Stop Building AI Data Infra for the Wrong Stage
Learn how AI data infrastructure should evolve from prototype to enterprise scale, and when Vector Lakebase becomes the right architecture for AI apps.

Why We Built Vector Lakebase: Rethinking Unstructured Data Architecture for AI
Vector Lakebase: a unified, lake-native data foundation for AI workloads — and an answer to what happens after vector databases succeed.

Our Journey to 35K+ GitHub Stars: The Real Story of Building Milvus from Scratch
Join us in celebrating Milvus, the vector database that hit 35.5K stars on GitHub. Discover our story and how we’re making AI solutions easier for developers.



