Skip to content
Merged
Show file tree
Hide file tree
Changes from 88 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
dbee699
feat: add renderers package and RendererClient
hallerite Mar 25, 2026
c559760
feat: barrage test suite + fix tool_call_no_content + DefaultRenderer…
hallerite Mar 25, 2026
1704066
feat: add INTELLECT-3.1 support + Kimi K2.5 assessment
hallerite Mar 25, 2026
1ad4ee2
feat: add KimiRenderer + clean up auto-detection
hallerite Mar 25, 2026
3494ef1
chore: remove IntellectRenderer (needs full-string encoding approach)
hallerite Mar 25, 2026
75e5d7a
refactor: shared parsing module mirroring vLLM's tool/reasoning parsers
hallerite Mar 25, 2026
e4c4541
refactor: Tinker-style token-level parsing — scan token IDs, not deco…
hallerite Mar 25, 2026
3ef054a
fix: stop token stripping + <think> cleanup in token-level parsing
hallerite Mar 25, 2026
815c397
run ruff
hallerite Mar 25, 2026
ef8cd2a
chore: remove KimiRenderer + dead messages.py module
hallerite Mar 25, 2026
cfc9ac2
style: ruff format + check
hallerite Mar 25, 2026
3855444
feat: update proxy to use /v1/generate with VLM image support
hallerite Apr 7, 2026
77c0373
feat: switch training clients to renderers
hallerite Apr 8, 2026
49e1e5f
fix: harden renderer proxy routing
hallerite Apr 8, 2026
070c5da
refactor: simplify renderer transport
hallerite Apr 9, 2026
5fc53aa
feat: add renderers for DeepSeek V3, Kimi K2/K2.5, Nemotron 3, GPT-OS…
hallerite Apr 14, 2026
e42b025
style: ruff check + format
hallerite Apr 14, 2026
57db953
fix: resolve ty type errors at renderer/OpenAI boundary
hallerite Apr 14, 2026
cc3217d
refactor: RendererClient inherits from Client directly, not OpenAICha…
hallerite Apr 14, 2026
74df920
Merge remote-tracking branch 'origin/main' into renderers
hallerite Apr 14, 2026
fa5f015
merge: origin/main into renderers
hallerite Apr 14, 2026
b5f804e
feat: thread-pooled tokenization for parallel rollouts
hallerite Apr 14, 2026
5f292ae
Add stateful renderer prompt stitching
hallerite Apr 15, 2026
acd7f53
Enable stateful renderer stitching for VLM prompts
hallerite Apr 15, 2026
ca41eca
Add extension-break observability and end-to-end renderer tests
hallerite Apr 21, 2026
c4e50e4
fix(qwen3-vl): emit un-expanded image placeholders for vLLM
hallerite Apr 21, 2026
2d8cc29
fix(renderer-client): surface vLLM's server-expanded prompt_token_ids
hallerite Apr 21, 2026
7f44237
Revert "fix(renderer-client): surface vLLM's server-expanded prompt_t…
hallerite Apr 21, 2026
84079aa
perf(renderer-pool): parallelize tokenizer init, drop default size to 16
hallerite Apr 21, 2026
d420651
perf(renderer-pool): default pool size 1
hallerite Apr 21, 2026
c3eaea3
feat(renderers): warn on DefaultRenderer auto-detect fallback
hallerite Apr 22, 2026
939a633
refactor(renderers-client): drop unused image-extraction path
hallerite Apr 22, 2026
1d308d2
feat(renderers): pluggable tool_parser / reasoning_parser for Default…
hallerite Apr 22, 2026
0e95edf
feat(renderer-client): expose pool size via ClientConfig
hallerite Apr 22, 2026
9c5ad2b
fix(bridge): synthesize close token when prev completion was truncated
hallerite Apr 22, 2026
f47ba32
feat(bridge): gate synthesize-close on per-renderer opt-in
hallerite Apr 22, 2026
fb6ecb9
fix(bridge): let truncated steps anchor the bridge when synth is opte…
hallerite Apr 22, 2026
d3771a5
test(renderer-client): cover bridge-over-truncated-anchor across all …
hallerite Apr 22, 2026
10c6a05
feat(bridge): per-renderer bridge_to_next_turn hook + Qwen3.5 bridge fix
hallerite Apr 22, 2026
4a4f4b0
feat(bridge): GLM bridge_to_next_turn (handles next-turn-marker templ…
hallerite Apr 22, 2026
891da50
feat(bridge): chatml_bridge helper + per-renderer bridge_to_next_turn…
hallerite Apr 22, 2026
3f46828
fix(nemotron3): support tokenizers without <|endoftext|>
hallerite Apr 22, 2026
338f6b7
feat(bridge): harmony-aware bridge_to_next_turn for GptOssRenderer
hallerite Apr 22, 2026
02fe986
test(renderers): render → parse round-trip parity + fix string-arg to…
hallerite Apr 22, 2026
9020f70
test(renderers): expand round-trip matrix + fix Kimi/GPT-OSS parsing …
hallerite Apr 22, 2026
7ae1f59
feat(renderers): GLM-5.1 + Kimi K2 + Nemotron-3 parity against apply_…
hallerite Apr 23, 2026
7d2f7f7
feat(renderers): full parity wave 2 — Nemotron3/MiniMax tool BPE + in…
hallerite Apr 23, 2026
6f89c38
refactor(bridge): hand-coded bridge_to_next_turn per renderer; kill d…
hallerite Apr 23, 2026
c499099
fix(renderer-client): forward cache_salt from extra_body to /v1/generate
hallerite Apr 23, 2026
fafea87
refactor(model-map): exact-name match instead of longest-prefix
hallerite Apr 23, 2026
bcd44c9
fix(client): promote finish_reason stop->tool_calls when tool_calls p…
hallerite Apr 23, 2026
3e6b7c4
fix(default): decode tool_call arguments strings before chat template
hallerite Apr 23, 2026
2e30fd0
fix(parser): preserve whitespace at <think>/</think> boundary
hallerite Apr 23, 2026
8ab276e
fix(client): normalize tool_call.arguments as JSON in incremental match
hallerite Apr 23, 2026
4cf8d49
chore(client): add WARN-level trace in _get_incremental_prompt_ids
hallerite Apr 23, 2026
7435307
chore(client): split no_tokens trace into sub-cases
hallerite Apr 23, 2026
14fb3c9
fix(client): fall back to raw response tokens when step.tokens was tr…
hallerite Apr 23, 2026
dba2e97
fix(parse_qwen3): fall back to raw content when tool_call JSON malformed
hallerite Apr 24, 2026
5d65e3f
feat(client): categorize extension breaks in _get_incremental_prompt_ids
hallerite Apr 24, 2026
c58da4a
docs(renderers): expand README for external audience
hallerite Apr 24, 2026
7136de5
feat(renderers): add Qwen3.6 renderer
hallerite Apr 24, 2026
7b86d14
Merge remote-tracking branch 'origin/main' into renderers
hallerite Apr 24, 2026
3d2b16c
fix(client): catch vLLM overlong-prompt 400s and add /generate diagno…
hallerite Apr 27, 2026
d519870
fix(client): recover tool function name on tool-result render
hallerite Apr 28, 2026
e6c9367
feat(client): broaden vLLM /generate kwargs allowlist + extra_headers…
hallerite Apr 28, 2026
cd2d991
fix(renderers): bugbot-flagged edge cases on gpt_oss bridge, kimi_k2 …
hallerite Apr 28, 2026
623b9e6
test(renderers): assert message_indices invariants + Kimi K2 regression
hallerite Apr 28, 2026
bccc488
fix(renderers): K2.5/K2.6 token-for-token parity + drop dead minimax …
hallerite Apr 28, 2026
d2dcfe9
chore(tests): drop stale GLM-5.1 caveat from conftest comment
hallerite Apr 28, 2026
b11b9ca
fix(renderers/kimi_k25): tools encoder accepts flat ToolSpec format
hallerite Apr 28, 2026
5588f71
feat(renderers/gpt_oss): rewrite as openai-harmony adapter
hallerite Apr 28, 2026
748d03e
chore(clients): restore TITO path alongside renderer client
hallerite Apr 28, 2026
8e632d8
fix(renderers/kimi_k2): drop unused locals flagged by ruff F841
hallerite Apr 28, 2026
95a2336
chore(renderer-client): hoist imports above module helpers (ruff E402)
hallerite Apr 28, 2026
75c8ec3
fix(tests): align stale fixtures + xfail two unimplemented features
hallerite Apr 28, 2026
56063cb
style: apply ruff format across renderers package and renderer-client…
hallerite Apr 28, 2026
5e199dc
docs: re-add OpenAIChatCompletionsTokenClient (TITO) alongside Render…
hallerite Apr 28, 2026
17358ee
refactor(renderers): rename build_supervised_sample → build_training_…
hallerite Apr 28, 2026
b14033e
fix: cleanup-review small fixes
hallerite Apr 28, 2026
9afd448
refactor(renderer-client): drop extension-break diagnostic path
hallerite Apr 28, 2026
69c2b4c
refactor(renderers): drop synth-close flag and strip multimodal
hallerite Apr 28, 2026
5648765
chore: address Mika's cheap review comments
hallerite Apr 28, 2026
ebb2658
docs: explain renderer client type in training docs and FAQs
hallerite Apr 28, 2026
1ac41b4
docs: mark renderer client experimental, recommend TITO for production
hallerite Apr 28, 2026
1d991b6
refactor(renderer-client): move helpers above class to match other cl…
hallerite Apr 28, 2026
aa2ac32
style: ruff format trailing newlines in test_renderer_e2e
hallerite Apr 29, 2026
e2ede3f
fix(kimi_k25): emit tool_declare messages from content + drop dead arg
hallerite Apr 29, 2026
547b5e6
fix(kimi_k2): render assistant content verbatim, including inline <th…
hallerite Apr 29, 2026
ee6cdb5
fix(renderer-client): propagate id, model, created from /generate
hallerite Apr 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ env.set_concurrency(256)
| `--model` | `-m` | `openai/gpt-4.1-mini` | Model name or endpoint alias |
| `--api-base-url` | `-b` | `https://api.pinference.ai/api/v1` | API base URL |
| `--api-key-var` | `-k` | `PRIME_API_KEY` | Environment variable containing API key |
| `--api-client-type` | — | `openai_chat_completions` | Client type: `openai_chat_completions`, `openai_completions`, `openai_chat_completions_token`, or `anthropic_messages` |
| `--api-client-type` | — | `openai_chat_completions` | Client type: `openai_completions`, `openai_chat_completions`, `openai_chat_completions_token`, `renderer`, `anthropic_messages`, or `nemorl_chat_completions` |
| `--endpoints-path` | `-e` | `./configs/endpoints.toml` | Path to TOML endpoints registry |
| `--header` | — | — | Extra HTTP header (`Name: Value`), repeatable |
| `--header-from-state` | — | `X-Session-ID: example_id` | Per-request header whose value is read from rollout state (`Name: state_key`), repeatable |
Expand Down
10 changes: 10 additions & 0 deletions docs/faqs.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,13 @@ client = AsyncOpenAI(

outputs = await env.evaluate(client, model="your-model-name", ...)
```

### Which `client_type` should I use for RL training?

Three options trade off control vs simplicity:

- **`openai_chat_completions`** (MITO) — server-side templating, text only. Standard OpenAI path. The trainer re-tokenizes for training, which can drift across multi-turn rollouts and fragment them into multiple samples.
- **`openai_chat_completions_token`** (TITO) — server-side templating, returns token IDs alongside text. The trainer doesn't re-tokenize. Use when the server's chat template is stable across turns.
- **`renderer`** *(experimental)* — client-side tokenization via a per-model renderer in the [`renderers` package](https://github.com/PrimeIntellect-ai/verifiers/tree/main/packages/renderers). Stronger token-preservation in theory: `bridge_to_next_turn` keeps multi-turn rollouts merged into one sample and survives mid-completion truncation cleanly. Hand-coded renderers exist only for a subset of models and corner cases are still being shaken out.

For production training, use `openai_chat_completions_token` — it's the tried-and-tested path. Try `renderer` if you want the stronger guarantees and your model has a hand-coded renderer. See [Inference Client Types](training.md#inference-client-types) for the full breakdown.
6 changes: 5 additions & 1 deletion docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ ClientType = Literal[
"openai_completions",
"openai_chat_completions",
"openai_chat_completions_token",
"renderer",
Comment thread
hallerite marked this conversation as resolved.
Resolved
"anthropic_messages",
"nemorl_chat_completions",
]
```

Expand Down Expand Up @@ -654,8 +656,10 @@ Abstract base class for all model clients. Wraps a provider-specific SDK client
|-------|---------------|------------|-------------|
| `OpenAIChatCompletionsClient` | `"openai_chat_completions"` | `AsyncOpenAI` | Chat Completions API (default) |
| `OpenAICompletionsClient` | `"openai_completions"` | `AsyncOpenAI` | Legacy Completions API |
| `OpenAIChatCompletionsTokenClient` | `"openai_chat_completions_token"` | `AsyncOpenAI` | Custom vLLM token route |
| `OpenAIChatCompletionsTokenClient` | `"openai_chat_completions_token"` | `AsyncOpenAI` | Custom vLLM token route (`/v1/chat/completions/tokens`) — server-side templating + token IDs returned alongside content |
| `RendererClient` | `"renderer"` | `AsyncOpenAI` | Renderer-backed token-in generate client (client-side tokenization via the `renderers` package) |
| `AnthropicMessagesClient` | `"anthropic_messages"` | `AsyncAnthropic` | Anthropic Messages API |
| `NeMoRLChatCompletionsClient` | `"nemorl_chat_completions"` | `AsyncOpenAI` | NeMo-RL Chat Completions variant |

All built-in clients are available as `vf.OpenAIChatCompletionsClient`, `vf.AnthropicMessagesClient`, etc.

Expand Down
10 changes: 10 additions & 0 deletions docs/training.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@ RL training can be sensitive to implementation details and hyperparameters. Some

The best way to improve training is to ensure appropriate task difficulty for your model. When using Hosted Training or `prime-rl`, you can enable online difficulty filtering to ensure that rollout groups used for training always contain a diversity of rewards.

### Inference Client Types

The rollout client's `client_type` controls how prompt assembly and token state flow between the inference server and the trainer. For RL the trainer must see the exact tokens the server sampled — re-tokenization across turns drifts under BPE round-trip and fragments multi-turn rollouts into multiple training samples.

- **`openai_chat_completions`** (MITO, *messages-in*): standard OpenAI-compatible path. Server-side chat templating, returns text. The trainer re-tokenizes — fine for eval and short single-turn training, but can fragment multi-turn rollouts.
- **`openai_chat_completions_token`** (TITO, *token-in*): server-side templating, but returns prompt and completion token IDs alongside text so the trainer doesn't re-tokenize. Use when you trust the server's chat template to be stable across turns.
- **`renderer`** *(experimental)*: client-side tokenization via a per-model renderer in the [`renderers` package](https://github.com/PrimeIntellect-ai/verifiers/tree/main/packages/renderers). The trainer renders messages to token IDs locally and sends those to vLLM's `/v1/generate` endpoint. The renderer's `bridge_to_next_turn` extends prior-turn tokens verbatim across multi-turn boundaries (the *extension property*) and synthesizes the canonical turn-close on mid-completion truncation, so multi-turn rollouts merge into one training sample with one clean loss mask.

For production RL training, use `openai_chat_completions_token` — it's the tried-and-tested path with broad model coverage. The `renderer` client is newer and offers stronger token-preservation guarantees in theory, but is experimental: hand-coded renderers exist only for a subset of models, and corner cases are still being shaken out. See [reference § Built-in Clients](reference.md#built-in-client-implementations) for the full list.
Comment thread
hallerite marked this conversation as resolved.
Resolved

### Common Issues

**Non-Increasing Chat Templates:** The Qwen3 and DeepSeek-R1 model series both remove `<think>` sections from messages when processing inputs, which violates the increasing context requirement for multi-turn training. We provide versions of many of these models with modified chat templates [here](https://huggingface.co/collections/willcb/qwen3-68434f4883925bfdb4570ee5).
Expand Down
Loading
Loading