Repository navigation
Replies: 1 comment
|
Short answer: with the Generator API, the How routing works ( On current main / 0.19.0,
The Engine path won't help you either. It exists to keep the embedding table on the CPU under CUDA graphs, it still looks up a fixed table, and the documented export for it uses What works today for per-token, runtime-modified embeddings: keep the model builder's import numpy as np, onnxruntime as ort
sess = ort.InferenceSession("model/model.onnx", providers=["CPUExecutionProvider"])
kv = [i.name for i in sess.get_inputs() if i.name.startswith("past_key_values")]
out_names = [o.name for o in sess.get_outputs()]
# num_key_value_heads / head_size come from genai_config.json
past = {n: np.zeros((1, num_kv_heads, 0, head_size), np.float32) for n in kv}
step_ids, generated = prompt_ids, []
for _ in range(max_new_tokens):
embeds = E[np.array(step_ids)][None] # E = your embedding table; apply drift/persona edits here
total_len = len(prompt_ids) + len(generated)
res = sess.run(None, {"inputs_embeds": embeds,
"attention_mask": np.ones((1, total_len), np.int64), **past})
nxt = int(res[0][0, -1].argmax()) # or your own sampler
generated.append(nxt); step_ids = [nxt]
past = {n.replace("present", "past_key_values"): r
for n, r in zip(out_names, res) if n.startswith("present")}You can still use If you'd rather have this inside the Generator, the change you describe in option 2 is the right shape: let I used Claude (Anthropic) to help investigate and draft this; I reviewed it and ran the checks above myself. |
Uh oh!
There was an error while loading. Please reload this page.
Use case
I'm building runtime-mutable embeddings for a custom assistant — the goal is to let downstream subsystems (memory, persona, prompt compressor) drive per-token embedding drift without retraining the model. The natural mechanism is to use
--extra_options exclude_embeds=trueso the embedding tensor lives outside the graph, then either (a) feedinputs_embedsper call from C# or (b) override the embedding sub-graph's initializer at session creation.What I observed
When I build a Llama-typed model (
NousResearch/Hermes-3-Llama-3.1-8B,model.type: "llama"ingenai_config.json) with--extra_options exclude_embeds=true, the resultinggenai_config.jsoncorrectly declaresinputs_embedsas the decoder input:I then hand-built a small
embedding.onnxthat doesGather(embed_tokens.weight, input_ids) -> inputs_embeds(mirroring the structure used intest/test_models/qwen-vision-preprocessing/genai_config.json) and added the correspondingembeddingblock:Generator.AppendTokens(prompt_ids)then fails with:Tested on 0.13.2 Python bindings, CPU EP. The Generator looks up
input_idson the main decoder graph, not on theembeddingsub-graph.Question
Is the
embeddingblock'sinput_ids -> inputs_embedschain intended to route only for VLMmodel.typevalues (qwen2_5_vl,gemma3, etc.), or is the lack of routing for Llama-typed models an unintended limitation?The README documents
exclude_embeds=trueas a generally-available builder option, and theembeddingblock schema is the natural way to wire a separate embedding source for any decoder. The Qwen-VL test fixture (test/test_models/qwen-vision-preprocessing/genai_config.json) is the only example I've found with a non-trivialembeddingblock — itsmodel.typeis VLM.What would unblock the use case
Either of:
embeddingblock is VLM-only, with a recommended pattern for non-VLM "supply your own embedding source" workflows (e.g., a sketch of the direct-ORT inference loop).embeddingblock irrespective ofmodel.type— i.e., ifmodel.embedding.filenameis present and the decoder declaresinputs_embedsrather thaninput_ids, routeAppendTokensthrough the embedding sub-graph first.I'd be happy to put up a PR for option 2 if a maintainer can confirm direction. Same patch shape as #2116 (the Seed-OSS PR I opened earlier today): small surgical change, high leverage, no kernel touches.
Why I'm not just patching it locally
I can — but if this is a known design choice and the recommended path for non-VLM custom-embedding workflows is "use ORT directly, not ORT-GenAI Generator," that's worth knowing before I take on writing a custom inference loop on the C# side. Saving a week of integration work either way.
Thanks for the time. Excited about the project — Seed-OSS PR #2116 is a related contribution from the same workstream.
All reactions