Reinforcement Learning Integration
Experimental. This guide is for RL framework authors and rollout orchestrator maintainers who need Dynamo to serve rollouts during a training loop, return token IDs and log probabilities, expose routing or engine metadata, discover live workers, and push weight updates without restarting the serving stack. Use the frontend for rollout inference, discover vLLM workers through the read-only RL discovery API, and send lifecycle or weight updates directly to the selected worker system URL.
Backend Support
Experimental means the RL integration surfaces are still converging around real framework usage. Treat nvext.token_data, the documented nvext.extra_fields values, and /v1/rl/workers for RL-enabled vLLM workers as the API-shaped surfaces to build against first. Treat engine_data, SGLang uploaded meta_info, direct /engine/ route bodies, custom route names, and backend-native response shapes as backend-specific escape hatches that can change independently.
Choose an Interface
The discovery API runs on a dedicated frontend listener. It is not mounted on the main frontend port, and it does not proxy /engine/ calls. The request-plane URL in its response is used internally to query route descriptors; an RL orchestrator should use the returned system_url for administration.
The worker system server does not add an authentication layer to /engine/ routes. Restrict the system port and RL discovery listener to the orchestrator network, and do not expose them through a public inference gateway.
vLLM Happy Path
This is the shortest path for wiring an RL orchestrator to a vLLM rollout worker: start the frontend discovery listener, start an RL-enabled worker, discover its system URL, run a token-in rollout, then pause, update weights, and resume generation.
Frontend Feature Support
The OpenAI-compatible completion routes provide the current token-in/token-out interface.
See NVIDIA Request Extensions for the complete nvext reference.
Backend RL flags also select engine-specific behavior:
- On vLLM,
--enable-rlregisters the discovery and administration routes, selects processed log probabilities, and prevents modelgeneration_config.jsonsampling overrides from changing RL token-in requests marked withnvext.token_data. Explicit request sampling values still apply. - On SGLang,
--enable-rlenables out-of-bandmeta_infoupload and the/engine/call_tokenizer_managerpassthrough route. SGLang also exposes control routes such as/engine/control/update_weights_from_disk, but SGLang workers do not currently register with/v1/rl/workers.
Token-In/Token-Out Example
Send pre-tokenized input and request token IDs plus prompt and completion log probabilities:
The relevant response fields have this shape:
To use the chat route while retaining pre-tokenized input, provide the normal messages field and set nvext.token_data to the complete token sequence that the engine should receive. The frontend uses token_data instead of rendering and tokenizing messages.
Routed Expert Data
Opt into routed-expert data per request:
The payload format is backend-specific:
- vLLM-compatible builds return an object containing base64
data,shape,dtype, andstart. Thestartoffset identifies the first returned routing row in the full prompt-plus-completion sequence. - SGLang builds whose
async_generateAPI supportsreturn_routed_expertsreturn the engine’s base64 string. Start SGLang with--enable-return-routed-expertsto request capture. Builds that omit this engine argument do not return the field. - TensorRT-LLM does not currently return routed-expert data through this frontend extension.
Use nvext.engine_data only when the orchestrator must consume other backend-specific data. The named completion_token_ids, prompt_logprobs, and routed_experts fields provide more stable contracts.
Upload SGLang Metadata
SGLang can upload the final cumulative meta_info for each choice to any filesystem supported by the installed fsspec backend. This path keeps large log probability tensors, routed-expert data, and custom metadata out of the HTTP response.
Treat metadata_upload.url as trusted RL control-plane input. The worker trims the value, checks that it is a non-empty string, and passes it to fsspec without restricting the storage scheme or destination. Do not allow untrusted inference callers to set this URL; fsspec can access local or remote storage with the worker’s permissions and credentials.
Start the worker with RL support. Add the routed-expert flag only when the SGLang engine build supports it:
Set a unique upload directory for each request:
The worker writes choice_0.msgpack.zst, choice_1.msgpack.zst, and so on beneath the URL. Each file contains a Zstandard-compressed MessagePack object:
Install the matching fsspec extra for remote storage, such as fsspec[s3] for S3. The worker also requires msgspec and zstandard. Local URLs such as file:///tmp/rollouts/request-7 are useful for development.
When metadata_upload is present, SGLang uploads only the final cumulative meta_info for each choice and omits inline log probabilities and routed-expert metadata. The final response waits for the upload. An upload failure fails the request, so use a durable destination and a unique URL to avoid overwriting another request’s choice_<index>.msgpack.zst objects.
Discover RL Workers
RL discovery currently covers RL-enabled vLLM workers. Start the frontend discovery listener and a vLLM worker with its system server enabled:
Query the dedicated discovery port:
The response describes each live worker and probes it for the routes available in that process:
Treat routes as the capability list for that worker instead of assuming every engine exposes the same methods. Optional features such as Low-Rank Adaptation (LoRA) add routes only when enabled. Discovery can also return a worker with an error and an empty route list when its descriptor probe times out or fails.
The discovery listener uses these environment variables:
Call vLLM Engine Routes Directly
Read system_url and routes from the discovery response, then call the selected vLLM worker. Send a JSON object even when the route does not require arguments:
For a vLLM weight update cycle, pause the selected worker, call one of its advertised weight-update routes, validate the result, and resume generation. Install jq before running this example. The exit trap attempts to resume the worker if the update or another command fails:
Route request bodies and response fields are engine-specific. A callback can return {"status":"error"} with HTTP 200, while an exception in the callback produces HTTP 500. Check both the HTTP status and the JSON result before advancing the rollout state.
SGLang direct administration uses SGLang-specific routes and response shapes. For example, call /engine/control/update_weights_from_disk directly when you already know the worker URL, or call /engine/call_tokenizer_manager with {"method":"update_weights_from_disk", ...} for tokenizer-manager passthrough behavior.
The /v1/rl/workers endpoint is read-only. It intentionally does not expose /v1/rl/engine or /v1/rl/engines proxy routes, which prevents an accidental frontend fan-out of a mutating engine operation.
Register a Custom Engine Route
Register an asynchronous Python callback on the worker’s DistributedRuntime. The route name is appended to /engine/ on the system server:
Enable the system server with DYN_SYSTEM_PORT, then call the route directly:
register_engine_route makes the HTTP route callable but does not automatically advertise it in the RL discovery response. When extending an RL-enabled vLLM worker, register and advertise the route together with the shared helper:
The next GET /v1/rl/workers probe includes rl/set_rollout_state in that worker’s routes list.