william-ricursive's picture
Set server context to 1Mi with a 16Ki draft window
e27e171 verified
|
Raw History Blame Contribute Delete
3.66 kB
# Ripple on B200
BF16 Ripple-65B + native DFlash2 on two NVIDIA B200 GPUs, using **SGLang 0.5.19**.
Four files here: this README, `model.py`, `ripple_format.py`, and `serve.py`. Both
inference folders share `chat_template.jinja` at the repository root; keep that layout.
Uses the tools-aware ChatML template from our evals.
Requires Linux, CUDA Toolkit 13, a C++ compiler, and [uv](https://docs.astral.sh/uv/).
Use complete, unquantized BF16 target and matching `DFlash2DraftModel` checkpoints.
Run the commands below from `inference/server`.
```bash
export CUDA_HOME=/usr/local/cuda-13.0
export PATH="$CUDA_HOME/bin:$PATH"
CUDA_VISIBLE_DEVICES=0,1 uv run --script serve.py \
--model-path /path/to/target \
--speculative-draft-model-path /path/to/draft
```
Dependencies install automatically. The server listens on `127.0.0.1:30000`.
It uses the checkpoint's tokenizer and the repository-root chat template.
```bash
curl http://127.0.0.1:30000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"ripple","messages":[{"role":"user","content":"Hello"}],"max_tokens":128}'
```
Defaults: TP=2, BF16 weights and KV cache, TRT-LLM target attention, Triton draft
attention, 16 draft tokens, and a **1Mi-token target context** (`--context-length 1048576`,
including prompt and generated tokens). Standard SGLang CLI flags apply.
The DFlash2 draft's last layer is global attention without RoPE. It was trained on
16Ki-token rows, so the draft keeps a **16Ki-token window** (`--speculative-draft-window-size 16384`);
smaller windows are refused.
The launcher defaults `SGLANG_ALLOW_OVERWRITE_LONGER_CONTEXT_LEN=1` so stock SGLang can
extend the draft's positional cache beyond its 128Ki checkpoint limit. This does not
increase the draft attention window. The target checkpoint supports up to 2Mi positions.
For four GPUs, run a second copy with `CUDA_VISIBLE_DEVICES=2,3` and `--port 30001`.
This gives two independent replicas, each using two GPUs. Send eight concurrent
requests to each port for sixteen total.
The launcher enables Ripple's parsers from `ripple_format.py` (`--reasoning-parser ripple`
and `--tool-call-parser ripple`). Responses separate `message.reasoning_content`,
final-answer `message.content`, and structured `message.tool_calls`. Streaming uses the
corresponding `delta` fields. Allow enough output tokens for both reasoning and the answer.
Pass OpenAI-style `tools` and `tool_choice: "auto"` to request calls:
```json
{
"model": "ripple",
"messages": [{"role": "user", "content": "Use add_numbers to calculate 23 + 19."}],
"tools": [{"type": "function", "function": {
"name": "add_numbers", "description": "Add two integers.", "strict": true,
"parameters": {"type": "object", "properties": {
"a": {"type": "integer"}, "b": {"type": "integer"}
}, "required": ["a", "b"], "additionalProperties": false}
}}],
"tool_choice": "auto",
"temperature": 0,
"max_tokens": 1024
}
```
Your application executes the requested function. Append the returned assistant
message unchanged, then a `tool` message containing its `tool_call_id` and a string
`content` with the result, and send the history again. The template re-renders an
unchanged message to exactly the tokens the model generated. Previous
`reasoning_content` is retained by default (`chat_template_kwargs.clear_thinking=false`).
The template does not implement a thinking on/off switch or reasoning-effort levels.
For `tool_choice: "required"`, use `function.strict=true` and
`parameters.additionalProperties=false`, as above. Non-strict required calls
produced extra argument fields in validation with this SGLang version.