# L2 normalization for cosine similarityembedding = cactus_embed(model, "Text", normalize=True)# Cosine similarity is now just dot productsimilarity = np.dot(embedding1, embedding2)
import numpy as np# Generate embeddings for multiple imagesimages = ["cat1.jpg", "cat2.jpg", "dog.jpg"]embeddings = [cactus_image_embed(model, img) for img in images]# Find most similar to query imagequery_embedding = cactus_image_embed(model, "query.jpg")similarities = [np.dot(query_embedding, emb) for emb in embeddings]most_similar_idx = np.argmax(similarities)print(f"Most similar: {images[most_similar_idx]}")print(f"Similarity: {similarities[most_similar_idx]:.3f}")
import numpy as np# Document corpusdocuments = [ "Cactus is an AI inference engine for mobile devices", "Python is a programming language", "The weather is sunny today", "Machine learning models run on smartphones"]# Generate document embeddingsdoc_embeddings = [cactus_embed(model, doc, True) for doc in documents]# Search queryquery = "on-device AI inference"query_embedding = cactus_embed(model, query, True)# Compute similaritiessimilarities = [np.dot(query_embedding, doc_emb) for doc_emb in doc_embeddings]# Get top resultstop_indices = np.argsort(similarities)[::-1][:3]for idx in top_indices: print(f"Score: {similarities[idx]:.3f} - {documents[idx]}")
Combine text and image embeddings in the same space:
model = cactus_init("weights/lfm2-vl-1.6b", None, False)# Text and image share the same embedding spacetext_emb = cactus_embed(model, "A photo of a cat", True)image_emb = cactus_image_embed(model, "cat.jpg")# Cross-modal similaritysimilarity = np.dot(text_emb, image_emb)print(f"Text-image similarity: {similarity:.3f}")
For models that support it, choose pooling method:
# Mean pooling (default)embedding = cactus_embed(model, "Text", normalize=True)# CLS token pooling (model-dependent)# Automatically selected based on model architecture
Reuse the same model instance for multiple embeddings to avoid reloading weights.
# Good: Reuse modelmodel = cactus_init("weights/lfm2-350m", None, False)for text in large_dataset: emb = cactus_embed(model, text, True) # process embeddingcactus_destroy(model)# Bad: Reload model each timefor text in large_dataset: model = cactus_init("weights/lfm2-350m", None, False) emb = cactus_embed(model, text, True) cactus_destroy(model)