Skip to content

Return a list of token lists for a text array with one string - #4665

Merged
przepeck merged 4 commits into
openvinotoolkit:mainfrom
Daksha1611:fix-tokenize-single-element-batch
Oct 26, 2026
Merged

przepeck merged 4 commits into
openvinotoolkit:mainfrom
Daksha1611:fix-tokenize-single-element-batch

Conversation

@Daksha1611

Copy link
Copy Markdown
Contributor

🛠 Summary

Fixes #4664.

The /v1/tokenize response nested the tokens only when the tokenizer returned more than one row, so
"text": ["hello world"] got the same flat list as "text": "hello world".

TokenizeRequest now records whether text was given as an array of strings (inputIsBatch), and
parseTokenizeResponse() takes it as a new last parameter, defaulting to false. When it is set the
response is always a list of token lists. The three callers (LLM servable, embeddings and rerank
calculators) pass it through.

This changes the response for a client that sends a one-element array and reads the flat list. A
single string is unchanged, as are arrays of two or more strings. The docs now show the list form.

Tests: three request tests (string, one-element array, longer array) and three response tests in
tokenize_parser_test.cpp.

I have no OVMS build container available, so this is not compiled with Bazel. I compiled the real
tokenize_parser.cpp and tokenize_parser_test.cpp against the OpenVINO runtime with abseil stubbed;
all 24 tests in the file pass. I also ran the request through a real Qwen3 tokenizer: before,
["hello world"] gave [14990,1879]; now it gives [[14990,1879]]. The one-argument additions in the
three callers could not be compiled here.

🧪 Checklist

  • Unit tests added.
  • The documentation updated.
  • Change follows security best practices.

The /v1/tokenize response nested the tokens only when the tokenizer returned more than one row,
so "text": ["hello world"] was answered with the flat list used for "text": "hello world".

TokenizeRequest records whether text was an array of strings, and parseTokenizeResponse() takes
that as a new last parameter and nests accordingly. The LLM servable, embeddings and rerank
callers pass it through. A single string and arrays of two or more strings are unchanged.

Adds request and response tests and documents the list form.
Comment thread src/tokenize/tokenize_parser.cpp Resolved
parseInput() now returns a plain string for an unbatched input and an array of strings for a batch,
so validateTokenizeRequest() no longer looks at the JSON again to tell them apart. Errors are
returned as an absl::StatusOr status, with the same messages as before. The embeddings request
parser is updated for the new return type.

Adds tests for the values parseInput() returns.
@Daksha1611
Daksha1611 requested a review from przepeck October 20, 2026 12:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The shared parser interface and production callers still need validation with actual dependencies in a full Bazel build.

No open issues 🎉

What changed in this PR

Fixes #4664 by preserving the request’s input form in /v1/tokenize responses: a one-string array now returns nested token lists, while a plain string remains unchanged.

Changes:

  • Track batch input and pass it through all three tokenizer integrations.
  • Adapt embeddings parsing to the shared parser’s updated return type.
  • Add regression tests and document list responses.
File Description
src/​tokenize/​tokenize_parser.hpp Declare batch tracking and updated parser interfaces.
src/​tokenize/​tokenize_parser.cpp Preserve input form and serialize batches consistently.
src/​test/​tokenize_parser_test.cpp Test parsing and response shapes.
src/​rerank/​rerank_calculator_ov.cc Forward batch metadata for rerank tokenization.
src/​llm/​servable.cpp Forward batch metadata for LLM tokenization.
src/​embeddings/​embeddings_calculator_ov.cc Forward batch metadata for embeddings tokenization.
src/​embeddings/​embeddings_api.cpp Handle the updated shared parser result.
docs/​model_server_rest_api_tokenizer.md Document nested responses for string arrays.

Review effort: Balanced

@Daksha1611

Copy link
Copy Markdown
Contributor Author

@przepeck I've pushed the change you suggested (parseInput now reports the unbatched case and errors through a status) and all checks are green. Could you take another look when you have a moment? Thanks.

@przepeck
przepeck merged commit 89dde36 into openvinotoolkit:main Oct 26, 2026
@przepeck

Copy link
Copy Markdown
Collaborator

PR merged, thank you for your contribution @Daksha1611

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/v1/tokenize returns a flat list when the text array holds a single string

3 participants