FastEmbed: Bikin Embedding Cepat dan Ringan Tanpa Torch dari Qdrant
Halo temen-temen, balik lagi sama aku Ruby Abdullah. Kali ini aku pengen ngajakin kalian ngulik satu library yang menurutku underrated banget di dunia AI dan RAG, namanya FastEmbed. Ini library buatan tim Qdrant, yang emang terkenal di dunia vector database. Kalau kalian pernah bikin sistem retrieval, semantic search, atau RAG (Retrieval Augmented Generation), pasti kalian butuh yang namanya embedding. Nah, biasanya buat generate embedding kita pakai sentence-transformers yang notabene narik torch, CUDA, dan segudang dependency berat lainnya. Ukurannya bisa nyampe gigabyte-an cuma buat install doang.
FastEmbed hadir buat nyelesain masalah itu. Dia ringan, cepat, dan yang paling penting nggak butuh torch sama sekali. Di balik layar dia pakai ONNX Runtime dengan model yang udah di-quantize, jadi inference-nya ngebut bahkan cuma di CPU. Buat kalian yang mau deploy embedding di server kecil, di serverless function, atau di environment yang resource-nya terbatas, ini tuh solusi yang pas banget. Di tutorial ini aku bakal bahas dari nol, mulai dari install, generate dense embedding, milih model, batch embedding, sampai yang agak advanced kayak sparse embedding SPLADE, late interaction ColBERT, image embedding, dan gimana nyambungin FastEmbed ke Qdrant buat bikin search engine beneran. Yuk kita mulai.
Introduction: Kenapa FastEmbed?
Sebelum masuk ke kode, aku pengen kalian ngerti dulu kenapa FastEmbed ini penting dan kapan kalian sebaiknya milih dia ketimbang alternatif lain.
Pertama soal ukuran dan kecepatan. Waktu kalian install sentence-transformers, itu bakal narik PyTorch yang ukurannya gede banget, apalagi kalau versi CUDA. Buat kasus di mana kalian cuma butuh inference (bukan training), narik torch tuh sebenernya overkill. FastEmbed cuma butuh onnxruntime dan beberapa dependency ringan. Hasilnya, ukuran instalasi jauh lebih kecil dan startup time-nya lebih cepat. Ini krusial banget buat serverless kayak AWS Lambda atau Google Cloud Functions di mana cold start itu musuh utama.
Kedua soal performa. Model yang dipakai FastEmbed udah di-quantize, artinya bobot model dikonversi ke precision yang lebih rendah (misalnya int8) tanpa ngorbanin akurasi secara signifikan. Efeknya inference di CPU jadi kenceng banget. Buat batch processing dokumen dalam jumlah besar, ini ngirit waktu dan biaya.
Ketiga soal integrasi. FastEmbed dibikin sama tim Qdrant, jadi integrasinya sama Qdrant itu mulus. Bahkan client Qdrant sekarang bisa langsung pakai FastEmbed di belakang layar buat generate embedding otomatis. Tapi FastEmbed juga bisa dipakai standalone tanpa Qdrant, jadi fleksibel.
Keempat soal variasi jenis embedding. FastEmbed nggak cuma ngasih dense embedding biasa. Dia juga support sparse embedding (kayak SPLADE) yang bagus buat keyword-based matching, late interaction model (ColBERT) yang akurasinya tinggi buat re-ranking, dan bahkan image embedding buat kasus multimodal. Jadi satu library bisa nyoverin banyak kebutuhan.
Nah kalau kalian lagi bangun aplikasi yang butuh embedding di production dengan resource terbatas dan pengen yang cepat, FastEmbed ini pilihan yang bijak. Sekarang kita langsung praktik.
Instalasi
Instalasi FastEmbed gampang banget, cukup satu perintah pip. Aku saranin kalian bikin virtual environment dulu biar rapi dan nggak ganggu project lain.
# Bikin virtual environment dulu
python -m venv venv
source venv/bin/activate # kalau di Windows: venv\Scripts\activate
Install FastEmbed
pip install fastembed
Kalau kalian punya GPU dan pengen inference yang lebih kenceng lagi, ada varian GPU-nya:
pip install fastembed-gpu
Tapi jujur aja, buat kebanyakan kasus, versi CPU biasa udah lebih dari cukup dan itu justru salah satu jualan utama FastEmbed. Buat pemakaian dengan Qdrant, kalian bisa install sekalian client Qdrant yang udah bundling FastEmbed:
pip install "qdrant-client[fastembed]"
Setelah keinstall, kita cek dulu apakah bisa di-import dengan bener. Coba jalanin skrip kecil ini:
from fastembed import TextEmbedding
Cek versi dan pastikan import berhasil
print("FastEmbed berhasil diimport!")
Inisialisasi model default
model = TextEmbedding()
print("Model default siap dipakai.")
Waktu pertama kali kalian inisialisasi model, FastEmbed bakal otomatis download model ONNX-nya dari repository dan nyimpen di cache lokal (biasanya di folder cache home directory). Jadi run pertama mungkin agak lama karena download, tapi run berikutnya bakal cepat karena modelnya udah ada di lokal. Ini perilaku yang perlu kalian inget, terutama kalau deploy di lingkungan yang read-only atau ephemeral, kalian mungkin perlu pre-download model dulu atau set direktori cache yang persisten.
Basic Usage: Generate Dense Text Embedding
Oke sekarang kita masuk ke inti pemakaian, yaitu generate dense embedding dari teks. Dense embedding itu adalah representasi teks dalam bentuk vektor angka float dengan dimensi tetap, misalnya 384 atau 768 dimensi. Vektor ini nangkep makna semantik dari teks, jadi teks yang mirip maknanya bakal punya vektor yang berdekatan di ruang vektor.
Cara pakainya simpel banget. Perhatiin bahwa method embed() itu mengembalikan generator, bukan list langsung. Ini desain yang sengaja biar hemat memori waktu ngeproses data besar. Jadi kita perlu bungkus dengan list() atau iterasi pakai loop.
from fastembed import TextEmbedding
Inisialisasi model. Kalau kosong, dia pakai model default
yaitu BAAI/bge-small-en-v1.5 (dimensi 384)
model = TextEmbedding()
Daftar dokumen yang mau kita embed
documents = [
"FastEmbed adalah library embedding yang ringan dari Qdrant.",
"Qdrant adalah vector database yang cepat dan open source.",
"Aku suka minum kopi di pagi hari sambil coding.",
]
embed() mengembalikan generator, jadi kita bungkus list()
embeddings = list(model.embed(documents))
Setiap embedding adalah numpy array
print(f"Jumlah embedding: {len(embeddings)}")
print(f"Dimensi tiap embedding: {embeddings[0].shape}")
print(f"5 angka pertama vektor pertama: {embeddings[0][:5]}")
Kalau kalian jalanin, kalian bakal liat ada 3 embedding, masing-masing dengan shape (384,), dan isinya angka-angka float. Nah, angka-angka ini yang nanti kita pakai buat ngitung kemiripan antar teks.
Buat ngitung kemiripan, kita biasanya pakai cosine similarity. Cosine similarity ngukur sudut antar dua vektor, nilainya dari -1 sampai 1, di mana makin mendekati 1 berarti makin mirip. Ini contoh gimana ngitungnya pakai numpy:
import numpy as np
from fastembed import TextEmbedding
model = TextEmbedding()
documents = [
"Kucing suka bermain di taman.",
"Anjing berlari mengejar bola.",
"Saham teknologi naik tajam hari ini.",
]
embeddings = list(model.embed(documents))
def cosinesimilarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
Bandingkan kalimat pertama dengan yang lain
for i in range(1, len(documents)):
sim = cosinesimilarity(embeddings[0], embeddings[i])
print(f"Similarity '{documents[0]}' vs '{documents[i]}': {sim:.4f}")
Kalian bakal liat bahwa kalimat tentang kucing dan anjing (dua-duanya tentang hewan) punya similarity lebih tinggi dibanding kalimat tentang saham. Nah gitu cara kerja semantic similarity.
Satu hal yang perlu kalian tau, ada perbedaan antara embed dokumen dan embed query. FastEmbed nyediain method khusus queryembed() buat query pencarian dan passageembed() buat dokumen. Beberapa model dilatih dengan instruksi khusus buat query vs passage, jadi pakai method yang tepat bisa ningkatin kualitas hasil.
from fastembed import TextEmbedding
model = TextEmbedding()
Untuk dokumen yang mau disimpan di database
passages = [
"Python adalah bahasa pemrograman yang populer untuk data science.",
"JavaScript banyak dipakai untuk pengembangan web frontend.",
]
passageembeddings = list(model.passageembed(passages))
Untuk query pencarian dari user
query = "bahasa pemrograman untuk analisis data"
queryembedding = list(model.queryembed(query))[0]
print(f"Dimensi passage embedding: {passageembeddings[0].shape}")
print(f"Dimensi query embedding: {queryembedding.shape}")
Memilih dan Melihat Daftar Model
Salah satu kelebihan FastEmbed adalah dukungan banyak model. Setiap model punya karakteristik beda, ada yang kecil dan cepat, ada yang lebih besar tapi lebih akurat, ada yang khusus multilingual. Buat liat daftar model apa aja yang tersedia, kalian bisa panggil listsupportedmodels().
from fastembed import TextEmbedding
Lihat semua model dense yang didukung
supported = TextEmbedding.listsupportedmodels()
for modelinfo in supported:
print(f"Model: {modelinfo['model']}")
print(f" Dimensi: {modelinfo['dim']}")
print(f" Deskripsi: {modelinfo.get('description', '-')}")
print(f" Ukuran (GB): {modelinfo.get('sizeinGB', '-')}")
print()
Dari daftar itu kalian bisa milih model yang sesuai kebutuhan. Beberapa model yang sering dipakai:
Buat bahasa Inggris umum, BAAI/bge-small-en-v1.5 (default, 384 dimensi) itu pilihan bagus karena kecil dan cepat. Kalau butuh akurasi lebih, ada BAAI/bge-base-en-v1.5 (768 dimensi). Buat kasus multilingual termasuk bahasa Indonesia, intfloat/multilingual-e5-large itu jempolan walaupun ukurannya lebih gede. Ada juga sentence-transformers/all-MiniLM-L6-v2 yang legendaris dan ringan.
Cara milih model tinggal masukin nama modelnya waktu inisialisasi:
from fastembed import TextEmbedding
Pakai model multilingual biar bisa handle bahasa Indonesia dengan baik
model = TextEmbedding(modelname="intfloat/multilingual-e5-large")
texts = [
"Aku sedang belajar machine learning.",
"I am learning machine learning.",
]
embeddings = list(model.embed(texts))
print(f"Dimensi: {embeddings[0].shape}")
Tips dari aku, kalau kalian ragu mau pakai model apa, mulai aja dari yang default atau yang kecil dulu. Ukur kualitasnya di use case kalian. Kalau kurang memuaskan baru upgrade ke model yang lebih besar. Jangan langsung pakai model gede karena bakal makan lebih banyak resource dan lebih lambat.
Batch Embedding untuk Data Besar
Kalau kalian punya ribuan bahkan jutaan dokumen buat di-embed, kalian nggak bisa asal masukin semua sekaligus tanpa mikirin efisiensi. FastEmbed udah didesain buat handle ini dengan baik. Method embed() menerima parameter batchsize dan parallel buat ngatur gimana data diproses.
from fastembed import TextEmbedding
model = TextEmbedding()
Anggap ini dataset besar
largedocuments = [f"Ini adalah dokumen nomor {i} yang berisi informasi."
for i in range(10000)]
batchsize ngatur berapa dokumen diproses sekaligus per batch
parallel ngatur jumlah worker process. 0 berarti pakai semua core CPU
embeddingsgenerator = model.embed(
largedocuments,
batchsize=256,
parallel=0, # 0 = pakai semua CPU core, None = tanpa multiprocessing
)
Karena ini generator, kita proses satu per satu biar hemat memori
count = 0
for embedding in embeddingsgenerator:
count += 1
# Di sini kalian bisa langsung simpan ke database, dsb
if count % 1000 == 0:
print(f"Sudah memproses {count} dokumen...")
print(f"Total dokumen diproses: {count}")
Poin penting di sini adalah karena embed() mengembalikan generator, kalian bisa memproses dokumen satu per satu tanpa harus nampung semua embedding di memori sekaligus. Ini penting banget kalau datasetnya gede. Bayangin kalau kalian punya 1 juta dokumen dengan embedding 768 dimensi float32, itu bisa makan memori berapa giga kalau ditampung semua. Dengan pola generator, kalian bisa langsung streaming ke database sambil embedding jalan.
Soal parameter parallel, ini yang perlu diperhatiin. Kalau di-set ke angka positif, FastEmbed bakal pakai multiprocessing dengan jumlah worker segitu. Kalau di-set 0, dia pakai semua core CPU yang ada. Kalau None, dia nggak pakai multiprocessing sama sekali (cocok buat data kecil di mana overhead multiprocessing malah bikin lambat). Buat dataset besar, pakai parallel=0 biasanya ngasih speedup signifikan. Tapi buat request kecil yang real-time, mending parallel=None biar nggak ada overhead spawn process.
Advanced Usage
Nah sekarang kita masuk bagian yang lebih seru. FastEmbed nggak cuma soal dense embedding. Ada beberapa fitur advanced yang bikin dia powerful banget buat sistem retrieval modern.
Sparse Embedding dengan SPLADE
Dense embedding bagus buat nangkep makna semantik, tapi dia kadang lemah buat exact keyword matching. Misalnya kalau user nyari kode produk spesifik atau istilah teknis yang jarang, dense embedding bisa meleset. Di sinilah sparse embedding masuk. Sparse embedding kayak SPLADE menghasilkan vektor dengan dimensi besar tapi kebanyakan nilainya nol, di mana hanya token yang relevan yang punya bobot. Ini menggabungkan kelebihan keyword matching dengan pemahaman semantik.
from fastembed import SparseTextEmbedding
Lihat model sparse yang tersedia
for m in SparseTextEmbedding.listsupportedmodels():
print(m["model"])
Inisialisasi model SPLADE
sparsemodel = SparseTextEmbedding(modelname="prithivida/SpladePPenv1")
documents = [
"FastEmbed mendukung sparse embedding menggunakan SPLADE.",
"Vector database menyimpan embedding untuk pencarian cepat.",
]
sparseembeddings = list(sparsemodel.embed(documents))
Sparse embedding punya indices dan values, bukan array padat
for i, emb in enumerate(sparseembeddings):
print(f"Dokumen {i}:")
print(f" Jumlah token non-zero: {len(emb.indices)}")
print(f" Indices (5 pertama): {emb.indices[:5]}")
print(f" Values (5 pertama): {emb.values[:5]}")
Perhatiin bahwa output sparse embedding beda sama dense. Dia punya atribut indices (posisi token mana yang aktif) dan values (bobot masing-masing token). Ini format yang efisien karena kita nggak perlu nyimpen ribuan angka nol. Dalam praktik, sparse embedding sering dikombinasi sama dense embedding dalam pendekatan yang disebut hybrid search, dan Qdrant support ini secara native.
Late Interaction dengan ColBERT
Model late interaction kayak ColBERT punya pendekatan beda. Alih-alih memampatkan seluruh dokumen jadi satu vektor, ColBERT menghasilkan satu vektor per token. Waktu pencarian, dia ngitung interaksi antara setiap token query dengan setiap token dokumen. Hasilnya lebih akurat karena informasi per token nggak hilang, tapi konsekuensinya butuh lebih banyak storage dan komputasi. ColBERT biasanya dipakai buat re-ranking, yaitu tahap kedua setelah kita dapet kandidat dari pencarian dense yang cepat.
from fastembed import LateInteractionTextEmbedding
Lihat model late interaction yang tersedia
for m in LateInteractionTextEmbedding.listsupportedmodels():
print(m["model"])
Inisialisasi model ColBERT
colbertmodel = LateInteractionTextEmbedding(
modelname="colbert-ir/colbertv2.0"
)
documents = [
"FastEmbed menyediakan model ColBERT untuk late interaction.",
"Late interaction memberikan akurasi retrieval yang tinggi.",
]
colbertembeddings = list(colbertmodel.embed(documents))
Tiap dokumen jadi matriks: satu vektor per token
for i, emb in enumerate(colbertembeddings):
print(f"Dokumen {i} shape: {emb.shape}") # (jumlahtoken, dimensi)
Kalian bakal liat bahwa output ColBERT itu berbentuk matriks dua dimensi, bukan vektor tunggal. Bentuknya (jumlahtoken, dimensi). Makanya butuh storage lebih. Tapi buat kasus di mana akurasi retrieval itu kritis, ColBERT sepadan.
Image Embedding
FastEmbed juga bisa generate embedding dari gambar, bukan cuma teks. Ini berguna banget buat kasus multimodal kayak image search, di mana kalian mau nyari gambar berdasarkan kemiripan visual, atau bahkan nyari gambar pakai query teks kalau modelnya CLIP-based.
from fastembed import ImageEmbedding
Lihat model image embedding yang tersedia
for m in ImageEmbedding.listsupportedmodels():
print(m["model"])
Inisialisasi model image embedding
imagemodel = ImageEmbedding(modelname="Qdrant/clip-ViT-B-32-vision")
Path ke file gambar lokal
images = [
"path/ke/gambar1.jpg",
"path/ke/gambar2.png",
]
imageembeddings = list(imagemodel.embed(images))
for i, emb in enumerate(imageembeddings):
print(f"Gambar {i} dimensi embedding: {emb.shape}")
Yang keren, kalau kalian pakai model CLIP-based, embedding gambar dan embedding teks berada di ruang vektor yang sama. Artinya kalian bisa nyari gambar pakai deskripsi teks. Ini pondasi buat bikin fitur kayak "cari gambar yang mirip deskripsi ini". Kalian tinggal embed teks query pakai CLIP text model, terus bandingin sama embedding gambar-gambar yang udah tersimpan.
Menggunakan FastEmbed dengan Qdrant
Nah ini bagian yang aku tunggu-tunggu, gimana nyambungin FastEmbed ke Qdrant buat bikin search engine beneran. Karena FastEmbed dan Qdrant sama-sama dari tim yang sama, integrasinya mulus banget. Client Qdrant bahkan bisa generate embedding otomatis pakai FastEmbed di belakang layar.
Pertama, cara paling gampang pakai fitur otomatis:
from qdrantclient import QdrantClient
Pakai in-memory buat testing, atau ganti dengan URL server Qdrant
client = QdrantClient(":memory:")
Data dokumen kita
docs = [
"FastEmbed membuat embedding jadi cepat dan ringan.",
"Qdrant adalah vector database berperforma tinggi.",
"RAG menggabungkan retrieval dengan generative AI.",
"Python adalah bahasa favorit untuk machine learning.",
]
add() otomatis pakai FastEmbed buat generate embedding
client.add(
collectionname="dokumensaya",
documents=docs,
)
Query juga otomatis di-embed
hasil = client.query(
collectionname="dokumensaya",
querytext="vector database yang cepat",
limit=2,
)
for point in hasil:
print(f"Score: {point.score:.4f} | Dokumen: {point.document}")
Gampang banget kan? Kalian nggak perlu manual generate embedding, Qdrant client yang urus semua pakai FastEmbed. Tapi kalau kalian mau kontrol lebih, kalian bisa generate embedding manual pakai FastEmbed terus insert ke Qdrant sendiri. Ini contohnya:
from qdrantclient import QdrantClient, models
from fastembed import TextEmbedding
Setup
model = TextEmbedding(modelname="BAAI/bge-small-en-v1.5")
client = QdrantClient(":memory:")
Bikin collection dengan konfigurasi vektor
client.createcollection(
collectionname="artikel",
vectorsconfig=models.VectorParams(
size=384, # sesuai dimensi model bge-small
distance=models.Distance.COSINE,
),
)
Data kita
documents = [
"Cara memasak nasi goreng yang enak dan mudah.",
"Tutorial machine learning untuk pemula.",
"Resep membuat kopi susu kekinian di rumah.",
"Panduan deep learning dengan PyTorch.",
]
Generate embedding pakai FastEmbed
embeddings = list(model.embed(documents))
Insert ke Qdrant sebagai points
client.upsert(
collectionname="artikel",
points=[
models.PointStruct(
id=idx,
vector=embedding.tolist(),
payload={"teks": doc},
)
for idx, (doc, embedding) in enumerate(zip(documents, embeddings))
],
)
Sekarang lakukan pencarian
query = "belajar AI dan neural network"
queryvector = list(model.queryembed(query))[0]
hasil = client.querypoints(
collectionname="artikel",
query=queryvector.tolist(),
limit=2,
).points
print(f"Query: {query}\n")
for point in hasil:
print(f"Score: {point.score:.4f} | {point.payload['teks']}")
Dengan pendekatan manual ini kalian punya kontrol penuh atas model yang dipakai, payload yang disimpan, dan konfigurasi collection. Buat production, aku biasanya lebih suka cara manual ini karena lebih eksplisit dan gampang di-debug.
Best Practices
Setelah kita bahas panjang lebar, aku pengen kasih beberapa best practice dari pengalaman aku pakai FastEmbed biar kalian nggak kejeblos di masalah yang sama.
Pertama, reuse instance model. Waktu kalian inisialisasi TextEmbedding(), itu load model ke memori yang butuh waktu dan resource. Jangan bikin instance baru tiap kali mau embed. Bikin sekali di awal aplikasi, terus reuse instance itu buat semua embedding. Kalau kalian pakai framework web kayak FastAPI, load model waktu startup dan simpan sebagai variabel global atau dependency.
from fastembed import TextEmbedding
BENAR: load sekali, reuse berkali-kali
model = TextEmbedding()
def embedteks(tekslist):
return list(model.embed(tekslist))
SALAH: jangan bikin instance baru tiap panggilan
def embedtekssalah(tekslist):
modelbaru = TextEmbedding() # ini boros banget!
return list(modelbaru.embed(tekslist))
Kedua, atur cache directory dengan bijak. FastEmbed download model ke cache lokal. Di lingkungan production yang ephemeral kayak container, kalian mau pastiin model nggak di-download ulang tiap deploy. Kalian bisa set direktori cache pakai parameter cachedir atau pre-download model waktu build image Docker.
from fastembed import TextEmbedding
Set cache directory yang persisten
model = TextEmbedding(
modelname="BAAI/bge-small-en-v1.5",
cachedir="/data/fastembedcache",
)
Ketiga, pilih batchsize yang sesuai. Batch size yang terlalu kecil bikin overhead per batch tinggi, tapi kalau terlalu besar bisa makan memori banyak. Buat CPU biasa, batch_size antara 128 sampai 256 biasanya sweet spot. Eksperimen dikit buat cari yang paling pas di hardware kalian.
Keempat, konsisten pakai model yang sama antara indexing dan query. Ini kesalahan klasik. Kalau kalian embed dokumen pakai model A, terus embed query pakai model B, hasilnya bakal kacau karena ruang vektornya beda. Selalu pakai model yang sama buat indexing dan pencarian.
Kelima, manfaatin generator buat data besar. Jangan langsung list() semua embedding kalau datanya jutaan. Iterasi generator dan streaming langsung ke database. Ini ngehemat memori drastis.
Keenam, pertimbangkan quantization di sisi Qdrant juga. Kalau kalian nyimpen jutaan vektor, Qdrant punya fitur scalar quantization yang bisa ngecilin footprint memori tanpa ngorbanin akurasi banyak. Gabungin FastEmbed yang ringan sama Qdrant quantization, kalian dapet sistem yang super efisien.
Ketujuh, buat multilingual, pilih model yang tepat. Kalau aplikasi kalian handle bahasa Indonesia, jangan pakai model English-only kayak bge-small-en. Pakai model multilingual kayak multilingual-e5. Kualitas embedding buat bahasa Indonesia bakal jauh lebih bagus.
Conclusion
Oke temen-temen, kita udah keliling cukup jauh soal FastEmbed. Mari aku rangkum apa aja yang udah kita pelajarin. FastEmbed itu library embedding dari tim Qdrant yang ringan dan cepat karena pakai ONNX Runtime dengan model quantized, tanpa perlu narik torch yang berat. Ini bikin dia pilihan ideal buat deployment dengan resource terbatas, serverless, atau di mana pun kecepatan dan ukuran instalasi itu penting.
Kita udah belajar cara install yang cukup satu perintah pip, generate dense embedding pakai TextEmbedding, ngitung cosine similarity, milih dan lihat daftar model yang tersedia, sampai batch embedding buat data besar dengan pola generator yang hemat memori. Kita juga udah eksplor fitur advanced kayak sparse embedding SPLADE yang bagus buat keyword matching, late interaction ColBERT buat akurasi retrieval tinggi, image embedding buat kasus multimodal, dan tentu aja integrasi mulus sama Qdrant buat bikin search engine beneran.
Yang paling aku suka dari FastEmbed adalah filosofinya yang fokus ke efisiensi tanpa ngorbanin fungsionalitas. Buat kalian yang lagi bangun sistem RAG atau semantic search di production, terutama dengan constraint resource, aku rekomendasiin banget buat coba FastEmbed. Kombinasi FastEmbed plus Qdrant itu stack yang solid dan hemat buat berbagai skala aplikasi.
Saran aku, mulai dari yang sederhana dulu. Coba generate dense embedding, ukur kualitasnya di data kalian sendiri, terus baru bereksperimen dengan sparse dan hybrid search kalau butuh peningkatan akurasi. Jangan langsung pakai fitur paling kompleks kalau kebutuhannya belum ada. Prinsipnya sama kayak coding pada umumnya, mulai simpel, ukur, baru optimasi.
Sekian dulu tutorial dari aku. Semoga bermanfaat dan bikin kalian makin semangat ngoprek dunia embedding dan retrieval. Kalau ada pertanyaan atau mau diskusi lebih lanjut, jangan ragu buat reach out. Sampai ketemu di tutorial berikutnya, temen-temen. Happy coding dan tetap semangat belajar!