Skip to content

Speed up train completion usage serialization - #1787

Merged
xeophon merged 1 commit into
feat/nano-as-v1from
codex/v1-train-usage-dict
Jun 21, 2026
Merged

Speed up train completion usage serialization#1787
xeophon merged 1 commit into
feat/nano-as-v1from
codex/v1-train-usage-dict

Conversation

@xeophon

@xeophon xeophon commented Jun 21, 2026

Copy link
Copy Markdown
Member

Overview

Build the OpenAI-compatible completion usage payload directly from the already-typed vf.Usage object in the renderer training client.

Rationale

The previous path constructed CompletionUsage plus optional nested OpenAI Pydantic detail models, then immediately dumped those temporary objects back into a dictionary. Usage has already been validated earlier in the Verifiers pipeline, so reconstructing and serializing SDK models adds allocations and validation work without changing the wire contract.

The new path assembles the final dictionary directly. It preserves cached-token accounting, total-token calculation, omission of absent optional details, inclusion of zero-valued details, and usage: null when usage is absent. A short code comment documents why direct construction is intentional.

Performance impact

A Python 3.13.12 microbenchmark using the real vf.Response and vf.Usage types ran 100,000 serializations across seven repetitions:

Resource Before After Saved
Median wall time per 100k calls 0.316947 s 0.039146 s 0.277801 s (87.65%)
Median wall time per call 3.16947 µs 0.39146 µs 2.77801 µs
Peak traced Python allocation 5,008 bytes 2,584 bytes 2,424 bytes (48.40%)
Retained traced bytes after GC 32 bytes 32 bytes 0 bytes

This keeps the optimization local to synthesized completion responses from TrainClient; other clients and shared usage types are unchanged.


Note

Low Risk
Localized serialization change in the training client with the same intended wire shape; no auth, security, or shared pipeline changes.

Overview
serialize_completion in the renderer TrainClient now builds the OpenAI-style usage object as a plain dict instead of instantiating CompletionUsage and nested token-detail Pydantic models and then calling model_dump.

The mapping is unchanged: input_tokensprompt_tokens, optional reasoning_tokens and cached_input_tokens nested under completion_tokens_details / prompt_tokens_details, and usage stays absent when there is no usage. A short comment notes that usage is already validated upstream.

OpenAI SDK imports used only for this path are removed. Other clients and interception serialization are untouched.

Reviewed by Cursor Bugbot for commit 65cc626. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Speed up train completion usage serialization by replacing OpenAI model objects with plain dicts

In serialize_completion, the usage field is now built as a plain Python dict instead of constructing an openai.types.CompletionUsage object and calling model_dump(). Sub-dicts for completion_tokens_details and prompt_tokens_details are built conditionally based on the presence of reasoning_tokens and cached_input_tokens. This avoids Pydantic model instantiation overhead on every call.

Macroscope summarized 65cc626.

@macroscopeapp

macroscopeapp Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

This is a simple performance optimization replacing Pydantic model construction with direct dict building. The serialized output format remains identical, making this a low-risk mechanical change with no behavioral impact.

You can customize Macroscope's approvability policy. Learn more.

@xeophon
xeophon merged commit 824d87e into feat/nano-as-v1 Jun 21, 2026
5 checks passed
pull Bot pushed a commit to Stars1233/verifiers that referenced this pull request Jun 23, 2026
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.

1 participant