Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
54c243a
trainers: stream checkpoint files into the page cache before loading …
droot Oct 15, 2026
18409bd
runs: cold start on open-rl-dra, measured, before and after the train…
droot Oct 15, 2026
231c934
scripts: render and report N in-cluster GSM8K GRPO client Jobs for th…
droot Oct 17, 2026
65350ba
scripts: per-step rows in the demo report
droot Oct 17, 2026
22fa006
trainer: size the per-pass token budget from the vocabulary and free …
droot Oct 17, 2026
6ff6b6f
trainer: log the token budget and pass count once
droot Oct 17, 2026
3f5d1bb
deploy: pre-pull the worker image on every node; keep vLLM's compile …
droot Oct 17, 2026
aa45d40
scripts: one-screen watch for a demo run
droot Oct 17, 2026
459e718
deploy: let the vLLM compile cache live on a shared directory (OPEN_R…
droot Oct 17, 2026
0e025fa
deploy: share vLLM's compile cache on the shared volume by default
droot Oct 17, 2026
8736ff0
sampler: capture CUDA graphs for power-of-two batch sizes only
droot Oct 17, 2026
d5361ed
sampler: keep room for the weight update's dense staging copy
droot Oct 18, 2026
ed0f629
scripts: give each demo client its own Hugging Face cache
droot Oct 18, 2026
87417c2
sampler: wake the KV cache after the weight update, and size the upda…
droot Oct 18, 2026
943eb38
scheduler: cap the seats a shared claim may hold
droot Oct 18, 2026
fcf8b8d
scripts: let demo Jobs carry openrl.* session tags
droot Oct 18, 2026
aba8144
scheduler: show the status reason in kubectl get workloads
droot Oct 19, 2026
fc1ccbb
scripts: drill cells in any region, and a one-command rehearsal
droot Oct 19, 2026
4272cf3
runs: keep the written reports, drop the raw logs; add the fleet demo…
droot Oct 19, 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
5 changes: 5 additions & 0 deletions k8s/deploy/base/api-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ spec:
key: BASE_MODEL
- name: OPEN_RL_TMP_DIR
value: "/mnt/shared/open-rl"
# vLLM's compile cache, shared by every sampler in the fleet: the first
# sampler of a model on a GPU type compiles (about a minute), the rest
# load the result in a second. Unset it to keep a per-node hostPath instead.
- name: OPEN_RL_VLLM_CACHE_DIR
value: "/mnt/shared/open-rl/vllm-cache"
# vLLM sampling enabled on cluster.
- name: SAMPLING_BACKEND
value: "vllm"
Expand Down
1 change: 1 addition & 0 deletions k8s/deploy/base/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ resources:
- rbac.yaml
- redis.yaml
- api-server.yaml
- worker-prepull.yaml

generatorOptions:
disableNameSuffixHash: true
Expand Down
44 changes: 44 additions & 0 deletions k8s/deploy/base/worker-prepull.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Pulls the worker image onto every node the scheduler may use, at deploy time
# instead of inside the first job. Measured on GKE (runs/2026-10-15_cold_start):
# a worker pull is 92 s on an H100 node with local SSD and 169 s on an L4 node
# with a pd-balanced boot disk, and a cold job pays it twice, trainer and
# sampler. The container only sleeps; it holds no GPU. The image reference is
# rewritten by the kustomize images transformer like every other OpenRL image,
# so a tag bump in the bundle re-pulls on every node as the DaemonSet rolls.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: open-rl-worker-prepull
labels:
app: open-rl-worker-prepull
spec:
selector:
matchLabels:
app: open-rl-worker-prepull
updateStrategy:
type: RollingUpdate
rollingUpdate:
# Every node pulls at once; there is nothing to protect by rolling slowly.
maxUnavailable: 100%
template:
metadata:
labels:
app: open-rl-worker-prepull
spec:
nodeSelector:
openrl.io/enabled: "true"
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: prepull
image: ghcr.io/gke-labs/open-rl/server:latest
imagePullPolicy: IfNotPresent
command: ["sleep", "infinity"]
resources:
requests:
cpu: "10m"
memory: "16Mi"
limits:
memory: "64Mi"
12 changes: 12 additions & 0 deletions runs/2026-10-15_cold_start/A-0.5b-l4-cold/monitoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
| minute ending (UTC) | read MiB/s | read ops/s | write MiB/s |
|---|---|---|---|
| 2026-10-15T03:04:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:05:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:06:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:07:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:08:00Z | 0.0 | 0 | 1.7 |
| 2026-10-15T03:09:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:10:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:11:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:12:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:13:00Z | 0.0 | 0 | 0.0 |
111 changes: 111 additions & 0 deletions runs/2026-10-15_cold_start/A-0.5b-l4-cold/timeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Cold start timeline: A-0.5b-l4-cold

t=0 is the client's `create_model` call at 2026-10-15T03:04:15.892+00:00 UTC. Offsets are seconds after t=0; a negative offset is before it.

## trainer: `orw-lora-qwen-qwen2-5-0-5b-0-trainer` on `gke-open-rl-dra-l4-trainer-2x-ed601d8b-lvw8`

| Mark | Clock (UTC) | t+ s | Self-reported s | Source |
|---|---|---|---|---|
| trainer.workload_created | 03:04:16.000 | 0.1 | | Workload creationTimestamp (apiserver) |
| trainer.pod_created | 03:04:16.000 | 0.1 | | pod creationTimestamp (apiserver) |
| trainer.workload_first_seen_by_poller | 03:04:16.578 | 0.7 | | workloads.tsv poller (laptop clock, 1 s) |
| trainer.workload_reports_pod | 03:04:16.578 | 0.7 | | workloads.tsv poller: status.podName set |
| trainer.pod_Initialized | 03:04:17.000 | 1.1 | | pod condition Initialized |
| trainer.pod_PodScheduled | 03:04:17.000 | 1.1 | | pod condition PodScheduled |
| trainer.event_Scheduled | 03:04:17.000 | 1.1 | | event: Successfully assigned openrl-system/orw-lora-qwen-qwen2-5-0-5b-0-trainer to gke-open-rl-dra-l4-trainer-2x-ed601d8b-lvw8 |
| trainer.workload_reports_node | 03:04:18.224 | 2.3 | | workloads.tsv poller: status.nodeName set |
| trainer.event_Pulling | 03:04:21.000 | 5.1 | | event: Pulling image "us-central1-docker.pkg.dev/cdrollouts-sunilarora/open-rl/open-rl-server:agent3-9f8dc13" |
| trainer.event_Pulled | 03:07:09.000 | 173.1 | 168.59 | event: Successfully pulled image "us-central1-docker.pkg.dev/cdrollouts-sunilarora/open-rl/open-rl-server:agent3-9f8dc13" in 2m48.59s (2m48.59s inc |
| trainer.event_Created | 03:07:09.000 | 173.1 | | event: Container created |
| trainer.container_started | 03:07:10.000 | 174.1 | | containerStatuses.state.running.startedAt |
| trainer.event_Started | 03:07:10.000 | 174.1 | | event: Container started |
| trainer.condition_Placed_True | 03:07:11.000 | 175.1 | | Workload condition Placed |
| trainer.pod_Ready | 03:07:11.000 | 175.1 | | pod condition Ready |
| trainer.pod_ContainersReady | 03:07:11.000 | 175.1 | | pod condition ContainersReady |
| trainer.process_first_log | 03:07:17.253 | 181.4 | | container log, first line |
| trainer.load_start | 03:07:17.410 | 181.5 | | container log: Loading base model Qwen/Qwen2.5-0.5B to cuda:0... |
| trainer.ready_key | 03:07:21.000 | 185.1 | | redis poller: open_rl:trainer_ready:Qwen/Qwen2.5-0.5B |
| trainer.load_done | 03:07:21.686 | 185.8 | | container log: Successfully loaded. |
| trainer.processor_started | 03:07:21.689 | 185.8 | | container log: [WORKER] Training requests processor started (model=Qwen/Qwen2.5-0.5B active_set=Qwen/Qwen2.5-0.5B-1). |

## sampler: `orw-lora-qwen-qwen2-5-0-5b-0-sampler` on `gke-open-rl-dra-l4-sampler-2x-ab5fdc9d-2208`

| Mark | Clock (UTC) | t+ s | Self-reported s | Source |
|---|---|---|---|---|
| sampler.workload_first_seen_by_poller | 03:07:28.976 | 193.1 | | workloads.tsv poller (laptop clock, 1 s) |
| sampler.workload_created | 03:07:29.000 | 193.1 | | Workload creationTimestamp (apiserver) |
| sampler.pod_created | 03:07:29.000 | 193.1 | | pod creationTimestamp (apiserver) |
| sampler.pod_Initialized | 03:07:30.000 | 194.1 | | pod condition Initialized |
| sampler.pod_PodScheduled | 03:07:30.000 | 194.1 | | pod condition PodScheduled |
| sampler.event_Scheduled | 03:07:30.000 | 194.1 | | event: Successfully assigned openrl-system/orw-lora-qwen-qwen2-5-0-5b-0-sampler to gke-open-rl-dra-l4-sampler-2x-ab5fdc9d-2208 |
| sampler.workload_reports_pod | 03:07:30.816 | 194.9 | | workloads.tsv poller: status.podName set |
| sampler.workload_reports_node | 03:07:30.816 | 194.9 | | workloads.tsv poller: status.nodeName set |
| sampler.event_Pulling | 03:07:33.000 | 197.1 | | event: Pulling image "us-central1-docker.pkg.dev/cdrollouts-sunilarora/open-rl/open-rl-server:agent3-9f8dc13" |
| sampler.container_started | 03:10:22.000 | 366.1 | | containerStatuses.state.running.startedAt |
| sampler.event_Pulled | 03:10:22.000 | 366.1 | 168.566 | event: Successfully pulled image "us-central1-docker.pkg.dev/cdrollouts-sunilarora/open-rl/open-rl-server:agent3-9f8dc13" in 2m48.566s (2m48.566s i |
| sampler.event_Created | 03:10:22.000 | 366.1 | | event: Container created |
| sampler.event_Started | 03:10:22.000 | 366.1 | | event: Container started |
| sampler.condition_Placed_True | 03:10:23.000 | 367.1 | | Workload condition Placed |
| sampler.pod_Ready | 03:10:23.000 | 367.1 | | pod condition Ready |
| sampler.pod_ContainersReady | 03:10:23.000 | 367.1 | | pod condition ContainersReady |
| sampler.process_first_log | 03:10:33.926 | 378.0 | | container log, first line |
| sampler.engine_init_start | 03:11:01.668 | 405.8 | | container log: (EngineCore pid=161) INFO 10-15 03:11:01 [core.py:123] Initializing a V1 LLM engine (v0.30.0) with config: model='Qwen/Q |
| sampler.load_start | 03:11:03.371 | 407.5 | | container log: (EngineCore pid=161) INFO 10-15 03:11:03 [model_runner.py:396] Loading model from scratch... |
| sampler.prefetch_start | 03:11:04.731 | 408.8 | | container log: (EngineCore pid=161) INFO 10-15 03:11:04 [weight_utils.py:857] Prefetching checkpoint files into page cache started (in |
| sampler.weights_loaded | 03:11:06.644 | 410.8 | 1.92 | container log: (EngineCore pid=161) INFO 10-15 03:11:06 [default_loader.py:430] Loading weights took 1.92 seconds |
| sampler.model_loaded | 03:11:07.445 | 411.6 | 4.387871 | container log: (EngineCore pid=161) INFO 10-15 03:11:07 [model_runner.py:428] Model loading took 1.47 GiB memory and 4.387871 seconds |
| sampler.compile_done | 03:11:38.154 | 442.3 | 28.48 | container log: (EngineCore pid=161) INFO 10-15 03:11:38 [monitor.py:53] torch.compile took 28.48 s in total |
| sampler.graphs_captured | 03:11:53.539 | 457.6 | 11.0 | container log: (EngineCore pid=161) INFO 10-15 03:11:53 [model_runner.py:1066] Graph capturing finished in 11 secs, took 0.23 GiB |
| sampler.kv_cache_sized | 03:11:54.078 | 458.2 | | container log: (EngineCore pid=161) INFO 10-15 03:11:54 [gpu_worker.py:640] Available KV cache memory: 17.33 GiB |
| sampler.engine_init_done | 03:12:04.781 | 468.9 | 57.33 | container log: (EngineCore pid=161) INFO 10-15 03:12:04 [core.py:372] init engine (profile, create kv cache, warmup model) took 57.33 s |
| sampler.ready_key | 03:12:06.000 | 470.1 | | redis poller: open_rl:sampler_ready:Qwen/Qwen2.5-0.5B |

## client

| Phase | Clock (UTC) | t+ s |
|---|---|---|
| client.start | 03:04:15.891 | -0.0 |
| client.create_model.start | 03:04:15.892 | 0.0 |
| client.create_model.done | 03:07:22.617 | 186.7 |
| client.forward_backward.start | 03:07:25.417 | 189.5 |
| client.forward_backward.done | 03:07:28.837 | 192.9 |
| client.optim_step.done | 03:07:29.600 | 193.7 |
| client.save_weights_and_get_sampling_client.start | 03:07:29.600 | 193.7 |
| client.save_weights_and_get_sampling_client.done | 03:07:30.173 | 194.3 |
| client.sample.start | 03:07:30.174 | 194.3 |
| client.sample.done | 03:12:07.151 | 471.3 |
| client.end | 03:12:07.154 | 471.3 |

## Critical path (derived from the marks above)

### trainer

| Phase | From | To | Seconds |
|---|---|---|---|
| placement: Workload to pod | client.create_model.start | trainer.pod_created | 0.1 |
| pod scheduled | trainer.pod_created | trainer.pod_PodScheduled | 1.0 |
| image pull (0 if cached) | trainer.pod_PodScheduled | trainer.event_Pulled | 172.0 |
| container create | trainer.event_Pulled | trainer.container_started | 1.0 |
| process start to load start (imports) | trainer.container_started | trainer.load_start | 7.4 |
| weights load | trainer.load_start | trainer.load_done | 4.3 |
| ready key | trainer.load_done | trainer.ready_key | -0.7 |
| client: create_model blocked | client.create_model.start | client.create_model.done | 186.7 |
| client: first forward_backward | client.forward_backward.start | client.forward_backward.done | 3.4 |

### sampler

| Phase | From | To | Seconds |
|---|---|---|---|
| placement: Workload to pod | client.save_weights_and_get_sampling_client.start | sampler.pod_created | -0.6 |
| pod scheduled | sampler.pod_created | sampler.pod_PodScheduled | 1.0 |
| image pull (0 if cached) | sampler.pod_PodScheduled | sampler.event_Pulled | 172.0 |
| container create | sampler.event_Pulled | sampler.container_started | 0.0 |
| process start to first log | sampler.container_started | sampler.process_first_log | 11.9 |
| imports until engine init | sampler.process_first_log | sampler.engine_init_start | 27.7 |
| engine init until load start | sampler.engine_init_start | sampler.load_start | 1.7 |
| weights load (vLLM prefetch into page cache + load) | sampler.load_start | sampler.weights_loaded | 3.3 |
| torch.compile | sampler.weights_loaded | sampler.compile_done | 31.5 |
| profiling, KV cache, graph capture | sampler.compile_done | sampler.engine_init_done | 26.6 |
| ready key | sampler.engine_init_done | sampler.ready_key | 1.2 |
| client: first sample blocked | client.sample.start | client.sample.done | 277.0 |

7 changes: 7 additions & 0 deletions runs/2026-10-15_cold_start/B-0.5b-l4-cached/monitoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
| minute ending (UTC) | read MiB/s | read ops/s | write MiB/s |
|---|---|---|---|
| 2026-10-15T02:59:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:00:00Z | 0.0 | 0 | 1.3 |
| 2026-10-15T03:01:00Z | 0.0 | 0 | 0.4 |
| 2026-10-15T03:02:00Z | 0.0 | 0 | 0.0 |
| 2026-10-15T03:03:00Z | 0.0 | 0 | 0.0 |
Loading
Loading