Skip to content

Commit 51924be

Browse files
committed
feat(sc): setup + entrypoint
Signed-off-by: Yuki Huang <yukih@nvidia.com>
1 parent a1d41bf commit 51924be

18 files changed

Lines changed: 1774 additions & 287 deletions

.github/workflows/cicd-main.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,8 @@ jobs:
717717
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
718718
- script: L1_Functional_Tests_PPO
719719
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
720+
- script: L1_Functional_Tests_SingleController
721+
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
720722
- script: L1_Functional_Tests_Eval
721723
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
722724
- script: L1_Functional_Tests_Other_1
@@ -786,6 +788,8 @@ jobs:
786788
runner: ${{ vars.GB200_RUNNER }}
787789
- script: L1_Functional_Tests_PPO
788790
runner: ${{ vars.GB200_RUNNER }}
791+
- script: L1_Functional_Tests_SingleController
792+
runner: ${{ vars.GB200_RUNNER }}
789793
- script: L1_Functional_Tests_Eval
790794
runner: ${{ vars.GB200_RUNNER }}
791795
- script: L1_Functional_Tests_Other_1
@@ -858,6 +862,8 @@ jobs:
858862
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
859863
- script: L1_Functional_Tests_PPO
860864
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
865+
- script: L1_Functional_Tests_SingleController
866+
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
861867
- script: L1_Functional_Tests_Eval
862868
runner: ${{ needs.org-member-pre-flight.outputs.runner_prefix }}
863869
- script: L1_Functional_Tests_Other_1
Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
# GRPO via SingleController (async-RL) — mirrors grpo_math_1B.yaml with
2+
# data_plane.enabled=true and a top-level async_rl: section holding the
3+
# SC-specific runtime knobs.
4+
grpo:
5+
num_prompts_per_step: 32
6+
num_generations_per_prompt: 16
7+
max_rollout_turns: 1
8+
max_num_epochs: 1
9+
max_num_steps: 1000000
10+
normalize_rewards: true
11+
use_leave_one_out_baseline: true
12+
val_period: 10
13+
val_at_start: false
14+
val_at_end: false
15+
overlong_filtering: false
16+
advantage_clip_low: null
17+
advantage_clip_high: null
18+
max_val_samples: 256
19+
val_batch_size: 256
20+
seed: 42
21+
use_dynamic_sampling: false
22+
dynamic_sampling_max_gen_batches: 10
23+
batch_multiplier: 1
24+
reward_shaping:
25+
enabled: false
26+
overlong_buffer_length: 128
27+
overlong_buffer_penalty: 1
28+
max_response_length: ${policy.max_total_sequence_length}
29+
stop_properly_penalty_coef: null
30+
31+
adv_estimator:
32+
name: "grpo"
33+
normalize_rewards: ${grpo.normalize_rewards}
34+
use_leave_one_out_baseline: ${grpo.use_leave_one_out_baseline}
35+
minus_baseline: true
36+
reward_scaling:
37+
enabled: false
38+
source_min: 0.0
39+
source_max: 1.0
40+
target_min: 0.0
41+
target_max: 1.0
42+
seq_logprob_error_threshold: null
43+
invalid_tool_call_advantage: null
44+
malformed_thinking_advantage: null
45+
46+
async_grpo:
47+
enabled: true
48+
max_trajectory_age_steps: 1
49+
in_flight_weight_updates: false
50+
recompute_kv_cache_after_weight_updates: false
51+
52+
loss_fn:
53+
reference_policy_kl_penalty: 0.01
54+
reference_policy_kl_type: "k3"
55+
kl_input_clamp_value: 20.0
56+
kl_output_clamp_value: 10.0
57+
ratio_clip_min: 0.2
58+
ratio_clip_max: 0.2
59+
ratio_clip_c: null
60+
use_on_policy_kl_approximation: false
61+
use_importance_sampling_correction: false
62+
truncated_importance_sampling_type: null
63+
truncated_importance_sampling_ratio: null
64+
truncated_importance_sampling_ratio_min: null
65+
sequence_level_importance_ratios: false
66+
token_level_loss: true
67+
force_on_policy_ratio: false
68+
use_kl_in_reward: false
69+
disable_ppo_ratio: false
70+
positive_example_nll_weight: 0.0
71+
72+
checkpointing:
73+
enabled: true
74+
checkpoint_dir: "results/grpo-single-controller"
75+
metric_name: "val:accuracy"
76+
higher_is_better: true
77+
keep_top_k: 3
78+
save_period: 10
79+
checkpoint_must_save_by: null
80+
model_save_format: "safetensors"
81+
save_consolidated: false
82+
save_optimizer: true
83+
84+
policy:
85+
model_name: "Qwen/Qwen2.5-1.5B"
86+
tokenizer:
87+
name: ${policy.model_name}
88+
chat_template_kwargs: null
89+
hf_config_overrides: {}
90+
train_global_batch_size: 512
91+
train_micro_batch_size: 4
92+
generation_batch_size: 32
93+
logprob_batch_size: ${policy.train_micro_batch_size}
94+
max_total_sequence_length: 512
95+
precision: "bfloat16"
96+
logprob_chunk_size: null
97+
offload_optimizer_for_logprob: false
98+
99+
dtensor_cfg:
100+
_v2: true
101+
enabled: false
102+
cpu_offload: False
103+
sequence_parallel: false
104+
activation_checkpointing: false
105+
tensor_parallel_size: 1
106+
context_parallel_size: 1
107+
custom_parallel_plan: null
108+
automodel_kwargs: {}
109+
lora_cfg:
110+
enabled: False
111+
target_modules: []
112+
exclude_modules: []
113+
match_all_linear: true
114+
dim: 8
115+
alpha: 32
116+
dropout: 0.0
117+
dropout_position: "post"
118+
lora_A_init: "xavier"
119+
use_triton: true
120+
121+
megatron_cfg:
122+
enabled: true
123+
force_reconvert_from_hf: False
124+
empty_unused_memory_level: 1
125+
activation_checkpointing: false
126+
recompute_granularity: "full"
127+
recompute_modules: null
128+
tensor_model_parallel_size: 1
129+
expert_tensor_parallel_size: 1
130+
expert_model_parallel_size: 1
131+
pipeline_model_parallel_size: 1
132+
num_layers_in_first_pipeline_stage: null
133+
num_layers_in_last_pipeline_stage: null
134+
context_parallel_size: 1
135+
pipeline_dtype: ${policy.precision}
136+
sequence_parallel: false
137+
freeze_moe_router: true
138+
moe_router_dtype: "fp64"
139+
moe_router_load_balancing_type: "none"
140+
moe_router_bias_update_rate: 0.0
141+
moe_permute_fusion: true
142+
apply_rope_fusion: True
143+
bias_activation_fusion: True
144+
defer_fp32_logits: False
145+
moe_per_layer_logging: False
146+
moe_enable_deepep: false
147+
moe_token_dispatcher_type: "alltoall"
148+
moe_shared_expert_overlap: false
149+
gradient_accumulation_fusion: false
150+
use_fused_weighted_squared_relu: false
151+
peft:
152+
enabled: false
153+
target_modules: []
154+
exclude_modules: []
155+
dim: 8
156+
alpha: 32
157+
dropout: 0.0
158+
dropout_position: "post"
159+
lora_A_init_method: "xavier"
160+
lora_B_init_method: "zero"
161+
a2a_experimental: false
162+
lora_dtype: None
163+
optimizer:
164+
optimizer: "adam"
165+
lr: 5.0e-6
166+
min_lr: 5.0e-7
167+
weight_decay: 0.01
168+
bf16: true
169+
fp16: false
170+
params_dtype: "float32"
171+
adam_beta1: 0.9
172+
adam_beta2: 0.999
173+
adam_eps: 1e-8
174+
sgd_momentum: 0.9
175+
use_distributed_optimizer: true
176+
use_precision_aware_optimizer: true
177+
clip_grad: ${policy.max_grad_norm}
178+
optimizer_cpu_offload: false
179+
optimizer_offload_fraction: 0.0
180+
scheduler:
181+
start_weight_decay: ${policy.megatron_cfg.optimizer.weight_decay}
182+
end_weight_decay: ${policy.megatron_cfg.optimizer.weight_decay}
183+
weight_decay_incr_style: "constant"
184+
lr_decay_style: "constant"
185+
lr_decay_iters: 1000
186+
lr_warmup_iters: 13
187+
lr_warmup_init: 5.0e-7
188+
distributed_data_parallel_config:
189+
grad_reduce_in_fp32: false
190+
overlap_grad_reduce: true
191+
overlap_param_gather: true
192+
use_custom_fsdp: false
193+
data_parallel_sharding_strategy: "optim_grads_params"
194+
fp8_cfg:
195+
enabled: false
196+
fp8: "e4m3"
197+
fp8_recipe: "blockwise"
198+
fp8_param: false
199+
env_vars: null
200+
201+
draft:
202+
enabled: false
203+
model_name: null
204+
loss_weight: 0.1
205+
num_layers: null
206+
aux_layer_indices: null
207+
208+
dynamic_batching:
209+
enabled: False
210+
train_mb_tokens: ${mul:${policy.max_total_sequence_length}, ${policy.train_micro_batch_size}}
211+
logprob_mb_tokens: ${mul:${policy.max_total_sequence_length}, ${policy.logprob_batch_size}}
212+
sequence_length_round: 64
213+
214+
sequence_packing:
215+
enabled: True
216+
train_mb_tokens: ${mul:${policy.max_total_sequence_length}, ${policy.train_micro_batch_size}}
217+
logprob_mb_tokens: ${mul:${policy.max_total_sequence_length}, ${policy.logprob_batch_size}}
218+
algorithm: "modified_first_fit_decreasing"
219+
sequence_length_round: 64
220+
221+
make_sequence_length_divisible_by: ${policy.dtensor_cfg.tensor_parallel_size}
222+
max_grad_norm: 1.0
223+
224+
optimizer:
225+
name: "torch.optim.AdamW"
226+
kwargs:
227+
lr: 5.0e-6
228+
weight_decay: 0.01
229+
betas: [0.9, 0.999]
230+
eps: 1e-8
231+
232+
scheduler:
233+
- name: "torch.optim.lr_scheduler.LinearLR"
234+
kwargs:
235+
start_factor: 0.1
236+
end_factor: 1.0
237+
total_iters: 50
238+
- name: "torch.optim.lr_scheduler.ConstantLR"
239+
kwargs:
240+
factor: 1.0
241+
total_iters: 10000000000
242+
- milestones: [50]
243+
244+
generation:
245+
port_range_low: 11001
246+
port_range_high: 15000
247+
backend: "vllm"
248+
max_new_tokens: ${policy.max_total_sequence_length}
249+
temperature: 1.0
250+
top_p: 1.0
251+
top_k: null
252+
stop_token_ids: null
253+
stop_strings: null
254+
mcore_generation_config:
255+
buffer_size_gb: 10
256+
num_cuda_graphs: 4
257+
block_size_tokens: 256
258+
use_cuda_graphs_for_non_decode_steps: true
259+
enable_chunked_prefill: true
260+
unified_memory_level: 0
261+
max_tokens: 16384
262+
vllm_cfg:
263+
async_engine: true
264+
precision: ${policy.precision}
265+
kv_cache_dtype: "auto"
266+
tensor_parallel_size: 1
267+
pipeline_parallel_size: 1
268+
expert_parallel_size: 1
269+
gpu_memory_utilization: 0.6
270+
max_model_len: ${policy.max_total_sequence_length}
271+
enforce_eager: False
272+
use_tqdm: true
273+
use_deep_gemm: False
274+
num_last_layers_in_bf16: 0
275+
num_first_layers_in_bf16: 0
276+
enable_vllm_metrics_logger: true
277+
vllm_metrics_logger_interval: 0.5
278+
vllm_kwargs: {}
279+
colocated:
280+
enabled: false
281+
resources:
282+
gpus_per_node: 1
283+
num_nodes: 1
284+
285+
data:
286+
max_input_seq_length: ${policy.max_total_sequence_length}
287+
shuffle: true
288+
num_workers: 1
289+
use_multiple_dataloader: false
290+
train:
291+
dataset_name: OpenMathInstruct-2
292+
split_validation_size: 0.05
293+
seed: ${grpo.seed}
294+
validation: null
295+
default:
296+
prompt_file: "examples/prompts/cot.txt"
297+
system_prompt_file: null
298+
processor: "math_hf_data_processor"
299+
env_name: "math"
300+
301+
env:
302+
math:
303+
num_workers: 8
304+
math_verify_impl: "hf_math_verify"
305+
306+
logger:
307+
log_dir: "logs"
308+
num_val_samples_to_print: 0
309+
wandb_enabled: false
310+
tensorboard_enabled: false
311+
mlflow_enabled: false
312+
swanlab_enabled: false
313+
monitor_gpus: true
314+
wandb:
315+
project: "grpo-dev"
316+
name: "grpo-single-controller-dev"
317+
swanlab:
318+
project: "grpo-dev"
319+
name: "grpo-single-controller-dev"
320+
tensorboard: {}
321+
mlflow:
322+
experiment_name: "grpo-dev"
323+
run_name: "grpo-single-controller-dev"
324+
tracking_uri: "http://localhost:5000"
325+
gpu_monitoring:
326+
collection_interval: 10
327+
flush_interval: 10
328+
329+
# TransferQueue data plane — required by the SingleController path.
330+
data_plane:
331+
enabled: true
332+
impl: transfer_queue
333+
backend: "simple"
334+
storage_capacity: 1000000
335+
num_storage_units: 2
336+
claim_meta_poll_interval_s: 0.5
337+
global_segment_size: 549755813888
338+
local_buffer_size: 68719476736
339+
340+
# SC-specific async-RL runtime knobs.
341+
# One training step consumes grpo.num_prompts_per_step prompt groups.
342+
async_rl:
343+
batch_selection_strategy: "strict_on_policy" # or "staleness_window"
344+
max_weight_staleness_versions: 1
345+
min_prompt_groups_per_batch: 2
346+
max_inflight_prompts: 8
347+
# When over_sampling=false this must equal
348+
# grpo.num_prompts_per_step * (max_weight_staleness_versions + 1).
349+
max_buffered_rollouts: 8
350+
# True : over-generates and wastes rollouts that age past the staleness window;
351+
# False: enforces per-weight-version dispatch quota.
352+
over_sampling: true
353+
354+
cluster:
355+
gpus_per_node: 2
356+
num_nodes: 1
357+
master_port_range_low: 25000
358+
master_port_range_high: 28000

0 commit comments

Comments
 (0)