TODO: Merge into compute.
| 152 | |
| 153 | // TODO: Merge into compute. |
| 154 | Expect<ErrNo> getEmbedding(Graph &GraphRef, Context &CxtRef) noexcept { |
| 155 | LOG_DEBUG(GraphRef.EnableDebugLog, "getEmbedding"sv) |
| 156 | |
| 157 | const llama_vocab *Vocab = llama_model_get_vocab(GraphRef.LlamaModel.get()); |
| 158 | // Add SEP if not present. |
| 159 | if (CxtRef.LlamaInputs.size() > 0 && |
| 160 | CxtRef.LlamaInputs.back() != llama_vocab_sep(Vocab)) { |
| 161 | LOG_WARN( |
| 162 | "getEmbedding: last token in the prompt is not SEP, "sv |
| 163 | "'tokenizer.ggml.add_eos_token' should be set to 'true' in the GGUF "sv |
| 164 | "header."sv) |
| 165 | } |
| 166 | |
| 167 | // Check if the input is too long. |
| 168 | if (static_cast<int64_t>(CxtRef.LlamaInputs.size()) > |
| 169 | GraphRef.Params.n_batch) { |
| 170 | RET_ERROR( |
| 171 | ErrNo::PromptTooLong, |
| 172 | "getEmbedding: the prompt is too long. Your input has {} tokens exceeds batch "sv |
| 173 | "size {}. Please reduce the input size or increase your batch-size."sv, |
| 174 | CxtRef.LlamaInputs.size(), GraphRef.Params.n_batch) |
| 175 | } |
| 176 | |
| 177 | // Evaluate the input tokens. |
| 178 | auto ReturnCode = evaluateInput(GraphRef, CxtRef, "getEmbedding"sv); |
| 179 | if (ReturnCode != ErrNo::Success) { |
| 180 | return ReturnCode; |
| 181 | } |
| 182 | |
| 183 | // Main prediction loop. |
| 184 | const int32_t NEmbd = llama_model_n_embd(GraphRef.LlamaModel.get()); |
| 185 | std::vector<float> Embeddings(NEmbd); |
| 186 | |
| 187 | for (int I = 0; I < CxtRef.LlamaBatch.n_tokens; I++) { |
| 188 | if (!CxtRef.LlamaBatch.logits[I]) { |
| 189 | continue; |
| 190 | } |
| 191 | |
| 192 | // Try to get sequence embeddings. |
| 193 | auto *Embd = llama_get_embeddings_seq(GraphRef.LlamaContext.get(), |
| 194 | CxtRef.LlamaBatch.seq_id[I][0]); |
| 195 | if (Embd == nullptr) { |
| 196 | Embd = llama_get_embeddings_ith(GraphRef.LlamaContext.get(), I); |
| 197 | if (Embd == nullptr) { |
| 198 | LOG_ERROR("getEmbedding: failed to get embeddings for token {}"sv, I); |
| 199 | continue; |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | // Normalize the embeddings. |
| 204 | common_embd_normalize(Embd, Embeddings.data(), NEmbd, |
| 205 | static_cast<int32_t>(CxtRef.Conf.EmbdNormalize)); |
| 206 | } |
| 207 | |
| 208 | std::string EmbeddingString; |
| 209 | buildOutputEmbedding(EmbeddingString, NEmbd, Embeddings.data()); |
| 210 | CxtRef.LlamaOutputs = |
| 211 | std::vector<uint8_t>(EmbeddingString.begin(), EmbeddingString.end()); |
no test coverage detected