12#include <llama/llama.h>
70 return llama_model_n_embd_out(model);
103 return llama_pooling_type(ctx) != LLAMA_POOLING_TYPE_NONE;
121 return LLAMA_POOLING_TYPE_NONE;
124 return llama_pooling_type(ctx);
141 float norm_sq = 0.0f;
142 for (
float v : vec) {
146 float norm = std::sqrt(norm_sq);
148 for (
float &v : vec) {
153 "[embedding::detail::apply_l2_normalize] WARNING: near-zero norm");
188 throw std::runtime_error(
"embedding::encode - NULL context");
190 if (source.
cells() == 0) {
191 throw std::runtime_error(
"embedding::encode - empty input");
194 throw std::runtime_error(
195 "embedding::encode - this context keeps memory, attends causally and "
196 "does not pool, so it would read an input in pieces; give it a pooling "
197 "type, or use an embedding model");
200 std::vector<llama_pos> positions;
201 decode::segments(ctx, 0, 0, source,
static_cast<int32_t
>(llama_n_batch(ctx)),
227inline void encode(llama_context *ctx,
const llama_token *tokens,
228 int32_t n_tokens, int32_t n_batch) {
229 if (!tokens || n_tokens <= 0) {
230 throw std::runtime_error(
"embedding::encode - Invalid token array");
232 if (n_tokens > n_batch) {
233 throw std::runtime_error(
234 "embedding::encode - token count exceeds batch size (truncation not "
235 "supported, increase n_batch or reduce input length)");
237 decode::TokenSource source(std::span<const llama_token>(tokens,
static_cast<size_t>(n_tokens)));
244inline void encode(llama_context *ctx,
const std::vector<llama_token> &tokens,
246 encode(ctx, tokens.data(),
static_cast<int32_t
>(tokens.size()), n_batch);
266inline std::vector<float>
get(llama_context *ctx,
270 throw std::invalid_argument(
"embedding::get: ctx is null");
274 const llama_model *model = llama_get_model(ctx);
276 LLOYAL_LOG_DEBUG(
"[embedding::get] ERROR: failed to get model from context");
277 throw std::runtime_error(
"embedding::get: failed to get model");
283 "[embedding::get] WARNING: pooling not enabled, embeddings may be "
284 "invalid. Create context with pooling_type != NONE");
289 const float *embd_ptr =
nullptr;
291 embd_ptr = llama_get_embeddings_seq(ctx, 0);
292 LLOYAL_LOG_DEBUG(
"[embedding::get] Using llama_get_embeddings_seq for pooled "
295 embd_ptr = llama_get_embeddings(ctx);
296 LLOYAL_LOG_DEBUG(
"[embedding::get] Using llama_get_embeddings (no pooling)");
301 "Ensure context was created with embeddings=true and "
302 "tokens were encoded with logits=true for all tokens.");
303 throw std::runtime_error(
304 "embedding::get: embeddings unavailable (ensure embeddings=true in "
305 "context params and use encode_for_embeddings())");
310 std::vector<float> embeddings(embd_ptr, embd_ptr + n_embd);
317 LLOYAL_LOG_DEBUG(
"[embedding::get] Extracted embeddings (dim=%d, normalize=%d)",
318 n_embd,
static_cast<int>(normalize));
336inline std::vector<float>
get_seq(llama_context *ctx, llama_seq_id seq,
340 throw std::invalid_argument(
"embedding::get_seq: ctx is null");
343 const llama_model *model = llama_get_model(ctx);
346 throw std::runtime_error(
"embedding::get_seq: failed to get model");
354 const float *embd_ptr = llama_get_embeddings_seq(ctx, seq);
360 return get(ctx, normalize);
365 throw std::runtime_error(
"embedding::get_seq: embeddings unavailable");
369 std::vector<float> embeddings(embd_ptr, embd_ptr + n_embd);
395inline std::vector<float>
get_ith(llama_context *ctx, int32_t idx,
399 throw std::invalid_argument(
"embedding::get_ith: ctx is null");
402 const llama_model *model = llama_get_model(ctx);
405 throw std::runtime_error(
"embedding::get_ith: failed to get model");
408 const float *embd_ptr = llama_get_embeddings_ith(ctx, idx);
413 throw std::runtime_error(
"embedding::get_ith: embeddings unavailable");
417 std::vector<float> embeddings(embd_ptr, embd_ptr + n_embd);
447 const std::vector<float> &b) {
448 if (a.size() != b.size()) {
449 LLOYAL_LOG_DEBUG(
"[embedding::cosine_similarity] ERROR: dimension mismatch "
452 throw std::invalid_argument(
453 "embedding::cosine_similarity: dimension mismatch");
462 for (
size_t i = 0; i < a.size(); ++i) {
A token span as a stream of one TEXT segment, so text is placed by the rail like any other input.
#define LLOYAL_LOG_DEBUG(...)
liblloyal - Common definitions and logging
Batch Decoding Operations.
void segments(llama_context *ctx, llama_seq_id seq, llama_pos base, SegmentSource &source, int32_t rows_n_batch, Scratch &scratch, std::vector< llama_pos > &positions, OnLanded &&landed)
Place a source's segments into one sequence, in order.
StreamReading reading_of(llama_context *ctx)
void apply_l2_normalize(std::vector< float > &vec)
Apply L2 normalization to embedding vector (in-place)
std::vector< float > get_seq(llama_context *ctx, llama_seq_id seq, Normalize normalize=Normalize::L2)
Get embeddings for specific sequence.
float cosine_similarity(const std::vector< float > &a, const std::vector< float > &b)
Compute cosine similarity between two embedding vectors.
std::vector< float > get(llama_context *ctx, Normalize normalize=Normalize::L2)
Get embeddings for last decoded batch.
Normalize
Normalization modes for embedding vectors.
int32_t pooling_type(llama_context *ctx)
Get pooling type for context.
std::vector< float > get_ith(llama_context *ctx, int32_t idx, Normalize normalize=Normalize::L2)
Get embeddings for specific token index in last batch.
void encode(llama_context *ctx, decode::SegmentSource &source)
Encode a whole input for embeddings: text, media, or both, as one stream.
bool has_embeddings(const llama_model *model)
Check if model supports embeddings.
bool has_pooling(llama_context *ctx)
Check if context has pooling enabled.
int32_t dimension(const llama_model *model)
Get embedding dimension for model: the width the model outputs, which a model with its own output hea...
A segment of a stream once it is in the KV: what moved, for the caller's books.
Reusable scratch buffers for multi-sequence batch construction.
Supplies the segment sequence for one branch's prefill.
virtual size_t cells() const =0
KV cells this whole sequence will consume, known BEFORE anything decodes.