Skip to content

v0.0.8

Choose a tag to compare

@github-actions github-actions released this 04 Nov 21:10
· 22 commits to main since this release
a604d9e

Highlights

Sampling pools. Sampling now goes through pools (#386, design in #324). The API server adds each sample request to a Redis Stream for the model's pool (#336). A dispatcher reads the stream, sends each request to a sampler, and saves exactly one result per request (#354). A sampler that stops does not lose requests. A shared pool serves its jobs in round-robin order, so one job's large batch does not block the other jobs. A request that no sampler answers within OPEN_RL_SAMPLE_DEADLINE_SECONDS fails with an error. A pool with one owner runs its sampler in process, as before. Shared LoRA pools and pools with two or more replicas run vllm serve replicas behind a dispatcher pod with Envoy and the llm-d endpoint picker. The dispatcher loads each new FFT revision onto every replica (#357).

Inspection API. The API server now serves read-only routes under /api/v1/inspect/ for agents and dashboards (#388, #389, #392, #393, #395, #396, #397):

  • inventory lists each run with its model, recipe, lifecycle, pods and nodes. It also lists the cluster's nodes, GPUs and problem pods.
  • runs lists one line per run. runs/{run_id}/summary explains why a run does not behave: pace, goodput, lost requests, failures, saves and placement.
  • runs/{run_id}/steps returns each step's ops, timing and metrics, including the density of each sparse delta (#404).
  • activity returns one lane per Workload with its GPUs, runs, held interval, time-slicer turns and waits (#411).
  • logs?run_id=<id> pages a run's logs. Set OPEN_RL_LOG_STORE=cloud-logging on the API server to enable it.
  • query?name= runs named PromQL queries such as gpu_util and gpu_busy. Set OPEN_RL_PROMETHEUS_URL to enable it.

The scheduler now records the GPU UUIDs, the placement time and the release time on each Workload's status (#393). Each DRA node lists its GPUs by name, UUID, product and memory (#409). Trainers and samplers record their activity in Redis (#396). One flusher thread per process writes the records every 5 seconds, so the request path makes no Redis calls.

Fleet demo app. k8s/deploy/demo adds a web app over the inspection API (#412). It starts a sweep of RL client Jobs and shows the fleet as one row per GPU. It also draws an occupancy timeline and shows the sparse deltas of each FFT run. It runs on the API server image with its code in a ConfigMap, so there is no image to build.

GPU metrics in every bundle. The lora and fft bundles now ship the DCGM exporter (#391). Before, only the distributed-fft-timeslice bundle had it. docs/configuration.md lists the Workload Identity grants that the inspection API needs for metrics and logs on GKE.

Faster job start.

  • If you set openrl.recipe=rl in TINKER_TAGS or user_metadata, create_model starts the sampler together with the trainer (#368). Before, the sampler started at the first sample request. In an eight-job fleet test, every job reached its first step 17 to 60 seconds sooner.
  • Sampler pods keep vLLM's compile cache on the shared volume (#358). The first sampler for a model, GPU type and engine setup compiles and saves the result. Later samplers load it in 2 to 6 seconds instead of 42 to 83 seconds.
  • The sampler records CUDA graphs for power-of-two batch sizes only (#359).
  • The gemma-4 LoRA sampler loads the text-only model (#360). Set VLLM_ENABLE_MULTIMODAL=1 to keep the full model.
  • Trainers read a checkpoint on nfs or lustre into the page cache with eight threads before they load it (#380).
  • The client image installs the projects at build time, so a client container starts 8 to 27 seconds sooner (#410).

Faster training steps.

  • If OPEN_RL_TRAIN_TOKEN_BUDGET is unset or auto, the trainer groups sequences into passes of up to 16384 tokens, or fewer on a small GPU (#350). Before, an unset budget meant one sequence per pass. A 64-sequence gemma-4-E2B LoRA step on an A100 takes 3.5 s instead of 43 s.
  • The trainer starts a new pass when padding would exceed 25% of a pass (#351).
  • The trainer computes target log-probabilities in chunks of 1024 positions, so loss memory no longer grows with tokens × vocabulary size (#348). This raises the token budget for large-vocabulary models such as gemma-4.

Fleet placement.

  • OPEN_RL_LORA_JOBS_PER_RUNTIME caps the LoRA jobs on one shared trainer and sampler (#371). The next job on the same base model starts a second runtime with its own workers. Unset or 0 keeps one runtime.
  • The scheduler flag --max-seats-per-claim (OPEN_RL_MAX_SEATS_PER_CLAIM) caps the time-sliced workers on one shared GPU (#394). A worker that finds every claim full waits for a free GPU or a free seat. The default 0 sets no limit.

Shared volume class and size. make render takes STORAGE_CLASS and STORAGE_SIZE and patches open-rl-shared-pvc with them (#384). Unset keeps standard-rwx and 1Ti, so the release bundles do not change. A five-job fleet finished in 412 s on a Filestore Zonal volume instead of 950 s on Basic HDD.

Performance comparison script. scripts/perf_compare.py runs the same 23-job GSM8K workload on a "before" and an "after" image set (#385). Its report compares total time, time to the first step, step time by phase and peak GPU memory. Run it with make perf-compare PERF_BEFORE=... PERF_AFTER=....

Breaking changes

  • Sampling pools (#386). Drain every job before you upgrade. Old samplers read the old queue, and the owner names of shared LoRA runtimes change. Apply the Role before the image. The API server needs new list verbs on Deployments and NetworkPolicies. Rebuild custom trainer images, because the trainer now freezes each LoRA save for the sampler. This release removes the old queue sampler.
  • Sampling settings (#352). vLLM no longer applies a checkpoint's default sampling settings, such as Qwen3's temperature of 0.6. A request gets exactly what the client asks for. vLLM now uses prefix caching.
  • Token budget default (#350). An unset OPEN_RL_TRAIN_TOKEN_BUDGET now means auto. Set it to 0 to keep one sequence per pass.
  • PodMonitoring CRD (#391). The lora and fft bundles now need the PodMonitoring CRD, which GKE's Managed Prometheus provides.

Fixes

  • A time-sliced sampler now wakes its weights, applies the delta, and then wakes its KV cache (#425). Before, a large delta ran out of memory because the KV cache took the GPU first.
  • A sampler that exits during a turn now lets its park finish before it unregisters (#427). Before, the process died with readuntil() called while another coroutine is already waiting.
  • A time-sliced sampler can restart while the llm-d snapshot agent still holds its job as SAVED. That sampler now fails its pending requests with the reason in seconds (#428). Before, it restarted for an hour until the client hit the 3600 s deadline. The job still cannot recover under the same name.
  • The FFT trainer writes a full sampler save when no earlier save holds the base of a sparse delta, for example after load_from_state (#357). Before, the sampler could end up on the wrong weights.
  • The gpu_busy query falls back to DCGM_FI_DEV_GPU_UTIL when Managed Service for Prometheus answers null for a query with no series (#408).
  • The openrl skill's SKILL.md frontmatter now parses as YAML (#356).

Docs and site

  • Sampling pools design (#324).
  • The NVIDIA DRA driver install now sets gpuResourcesEnabledOverride=true, which chart 25.8.0 requires (#418).
  • Blog posts: OpenRL in October (#334, #335) and Delta Weight Sync in OpenRL (#346).
  • The slide deck has a new section on the problems OpenRL solves, and controls for background, text and presenter (#367).

New Contributors

Full Changelog: v0.0.7...v0.0.8