# Multi-node distributed training with Verl (Volcano Engine Reinforcement Learning) framework.## Verl is a flexible and efficient reinforcement learning framework designed for# training large language models with RLHF (Reinforcement Learning from Human Feedback).# This example demonstrates multi-node training using PPO on the GSM8K dataset.## Prerequisites:# - Access to Hugging Face models (Qwen/Qwen2.5-0.5B-Instruct in this example)## Usage:# # Launch a 2-node training cluster:# $ konduktor launch examples/verl/multinode.yaml## # Stream logs:# $ konduktor logs verl-cluster-*## # Cleanup:# $ konduktor down verl-cluster-*# Known Issues: Need to set GLOO_SOCKET_IFNAME to primary network IF which changes# per platformname: verl-multinode-trainingresources: accelerators: H200:8 image_id: verlai/verl:app-verl0.5-transformers4.55.4-vllm0.10.0-mcore0.13.0-te2.2 cpus: 180 memory: 1000 labels: kueue.x-k8s.io/queue-name: user-queue maxRunDurationSeconds: "320000"num_nodes: 2 # Number of nodes for distributed training# Environment variablesenvs: HF_HUB_ENABLE_HF_TRANSFER: "1" TORCH_NCCL_AVOID_RECORD_STREAMS: "1" # Optional: Add your W&B API key for experiment tracking WANDB_API_KEY: <YOUR_WANDB_KEY> # Training configuration MODEL_NAME: Qwen/Qwen2.5-0.5B-Instruct TOTAL_EPOCHS: 3 ACTOR_LR: 1e-6 CRITIC_LR: 1e-5run: | set -x export PIP_CONSTRAINT="" mkdir -p $HOME/checkpoints apt update -y apt install -y iputils-ping git clone https://github.com/volcengine/verl.git cd verl # Install Verl and its dependencies (skip Megatron for this example) #USE_MEGATRON=0 bash scripts/install_vllm_sglang_mcore.sh pip install --no-deps -e . #pip install "ray[default]" # For Ray dashboard # Set up distributed training environment echo "Head IP: $MASTER_ADDR" echo "Number of nodes: $NUM_NODES" # Create custom runtime environment configuration cat > runtime_env_custom.yaml <<EOF working_dir: ./ excludes: ["/.git/", "*.whl", "**/*.whl"] env_vars: TORCH_NCCL_AVOID_RECORD_STREAMS: "1" CUDA_DEVICE_MAX_CONNECTIONS: "1" HF_HUB_ENABLE_HF_TRANSFER: "1" EOF # Ray cluster configuration HEAD_PORT=6385 DASH_PORT=8280 # Function to check if Ray is already running is_ray_alive () { ray status --address="$1:$HEAD_PORT" >/dev/null 2>&1 } if [ "$RANK" == "0" ]; then # Head node: prepare data, download model, start Ray head, and submit training job echo "Setting up head node..." # Install additional dependencies for data processing pip install datasets transformers # Prepare GSM8K dataset python3 examples/data_preprocess/gsm8k.py --local_dir ~/data/gsm8k # Download model to cache python3 -c "import transformers; transformers.pipeline('text-generation', model='Qwen/Qwen2.5-0.5B-Instruct')" # Start Ray head node if not already running if ! is_ray_alive "$MASTER_ADDR"; then echo "Starting Ray head node..." ray start --head --node-ip-address="$MASTER_ADDR" \ --port $HEAD_PORT --dashboard-port $DASH_PORT \ --dashboard-host=0.0.0.0 \ --dashboard-agent-listen-port=52366 \ --disable-usage-stats \ --num-gpus=$NUM_GPUS_PER_NODE sleep 10 else echo "Ray is already running at $MASTER_ADDR:$HEAD_PORT, reusing existing instance" ray status --address="$MASTER_ADDR:$HEAD_PORT" fi ray status ibdev2netdev # Submit the training job to Ray export RAY_ADDRESS="http://localhost:$DASH_PORT" echo "Submitting training job to Ray cluster..." HYDRA_FULL_ERROR=1 ray job submit --address="$RAY_ADDRESS" --working-dir=. \ --runtime-env=runtime_env_custom.yaml \ -- python3 -m verl.trainer.main_ppo \ data.train_files=$HOME/data/gsm8k/train.parquet \ data.val_files=$HOME/data/gsm8k/test.parquet \ data.train_batch_size=128 \ data.max_prompt_length=512 \ data.max_response_length=256 \ actor_rollout_ref.model.path=$MODEL_NAME \ actor_rollout_ref.actor.optim.lr=$ACTOR_LR \ actor_rollout_ref.actor.ppo_mini_batch_size=64 \ actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=4 \ actor_rollout_ref.rollout.name=vllm \ actor_rollout_ref.rollout.log_prob_micro_batch_size_per_gpu=8 \ actor_rollout_ref.rollout.tensor_model_parallel_size=1 \ actor_rollout_ref.rollout.gpu_memory_utilization=0.4 \ actor_rollout_ref.ref.log_prob_micro_batch_size_per_gpu=4 \ critic.optim.lr=$CRITIC_LR \ critic.model.path=$MODEL_NAME \ critic.ppo_micro_batch_size_per_gpu=4 \ critic.ppo_mini_batch_size=64 \ algorithm.kl_ctrl.kl_coef=0.001 \ trainer.project_name=ppo_training \ trainer.experiment_name=qwen-2.5-0.5B \ trainer.val_before_train=False \ trainer.n_gpus_per_node=$NUM_GPUS_PER_NODE \ trainer.nnodes=$NUM_NODES \ trainer.default_local_dir=$HOME/checkpoints \ trainer.save_freq=10 \ trainer.test_freq=10 \ trainer.total_epochs=$TOTAL_EPOCHS \ trainer.logger=['console'] \ trainer.resume_mode=auto 2>&1 | tee verl_training.log # To enable W&B logging: # 1. Set WANDB_API_KEY in envs or pass via --secret WANDB_API_KEY # 2. Change trainer.logger to: trainer.logger=['console', 'wandb'] # 3. Add: trainer.wandb_project='verl-rlhf' exit 1 # this forces the other workers to shutdown else # Worker nodes: connect to Ray head echo "Setting up worker node..." echo "Head IP: $MASTER_ADDR" echo "HEAD_PORT: $HEAD_PORT" echo "NUM_GPUS: $NUM_GPUS_PER_NODE" # Get this worker's IP address worker_ip=$(hostname -I | awk '{print $1}') echo "Worker IP: $worker_ip" echo "Checking if worker $worker_ip is already in Ray cluster at $MASTER_ADDR:$HEAD_PORT" if ray list nodes --address=$MASTER_ADDR:$HEAD_PORT 2>/dev/null | grep -q "$worker_ip"; then echo "Worker $worker_ip already connected to Ray cluster" ray status --address=$MASTER_ADDR:$HEAD_PORT else echo "Worker not connected, waiting for head node to start" sleep 20 echo "Starting Ray worker" ray start --address $MASTER_ADDR:$HEAD_PORT --disable-usage-stats --num-gpus=$NUM_GPUS_PER_NODE echo "Ray start exit code: $?" # Verify connection after starting sleep 5 ray status --address=$MASTER_ADDR:$HEAD_PORT fi while ping -c 1 ${MASTER_ADDR}; do sleep 5 done fi
and launch with
konduktor launch verl.yaml
While the job is running you should see a sample output like in the following
(job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [prompt] system (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) You are Qwen, created by Alibaba Cloud. You are a helpful assistant. (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) user (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) Janetβs ducks lay 16 eggs per day. She eats three for breakfast every morning and bakes muffins for her friends every day with four. She sells the remainder at the farmers' market daily for $2 per fresh duck egg. How much in dollars does she make every day at the farmers' market? Let's think step by step and output the final answer after "####". (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) assistant (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [response] First, we calculate the number of eggs Janet's ducks lay in a day. Since she lays 16 eggs per day, the number of eggs she eats in a day is 16 - 3 - 4 = 10 eggs. This means she sells 10 eggs daily at the farmers' market. Since each egg sells for $2, the daily earnings are 10 * 2 = $20. Therefore, the amount of money Janet makes every day at the farmers' market is $20. (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) #### 20 (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) #### 20 (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [ground_truth] 18 (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [score] 0.0 (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) len reward_extra_infos_dict['reward']: 1319 (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) local_global_step_folder: /root/checkpoints/global_step_174 (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=1498, ip=172.17.1.94) INFO:2025-08-25 23:17:09,357:[Rank 0] Saved model to /root/checkpoints/global_step_174/actor/model_world_size_16_rank_0.pt (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=1499, ip=172.17.1.94) INFO:2025-08-25 23:17:09,336:[Rank 1] Saved model to /root/checkpoints/global_step_174/actor/model_world_size_16_rank_1.pt (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=24109) INFO:2025-08-25 23:17:09,614:[Rank 10] Saved optim to /root/checkpoints/global_step_174/actor/optim_world_size_16_rank_10.pt (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=24109) INFO:2025-08-25 23:17:09,615:[Rank 10] Saved extra_state to /root/checkpoints/global_step_174/actor/extra_state_world_size_16_rank_10.pt (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=1498, ip=172.17.1.94) INFO:2025-08-25 23:17:10,020:[Rank 0] Saved model config and tokenizer class to /root/checkpoints/global_step_174/actor/huggingface (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) step:174 - global_seqlen/min:1756 - global_seqlen/max:2241 - global_seqlen/minmax_diff:485 - global_seqlen/balanced_min:1974 - global_seqlen/balanced_max:1977 - global_seqlen/mean:1976.0 - actor/entropy:0.10149244964122772 - critic/vf_loss:0.051519379019737244 - critic/vf_clipfrac:0.0 - critic/vpred_mean:0.8081025183200836 - critic/grad_norm:36.863529205322266 - perf/mfu/critic:0.01831457949805057 - critic/lr:1e-05 - actor/pg_loss:-0.5662342011928558 - actor/pg_clipfrac:0.0051369862630963326 - actor/ppo_kl:-0.0011725000804290175 - actor/pg_clipfrac_lower:0.0 - actor/grad_norm:4.237640619277954 - perf/mfu/actor:0.0185783582944669 - perf/max_memory_allocated_gb:56.59689235687256 - perf/max_memory_reserved_gb:59.7578125 - perf/cpu_memory_used_gb:58.61131286621094 - actor/lr:1e-06 - val-core/openai/gsm8k/reward/mean@1:0.4890068233510235 - training/global_step:174 - training/epoch:2 - critic/score/mean:0.609375 - critic/score/max:1.0 - critic/score/min:0.0 - critic/rewards/mean:0.609375 - critic/rewards/max:1.0 - critic/rewards/min:0.0 - critic/advantages/mean:1.1653965792390863e-08 - critic/advantages/max:2.7394912242889404 - critic/advantages/min:-2.5047049522399902 - critic/returns/mean:0.5375215411186218 - critic/returns/max:1.0 - critic/returns/min:0.0 - critic/values/mean:0.73046875 - critic/values/max:1.2421875 - critic/values/min:0.01556396484375 - critic/vf_explained_var:0.3024832606315613 - response_length/mean:145.125 - response_length/max:256.0 - response_length/min:75.0 - response_length/clip_ratio:0.0546875 - response_length_non_aborted/mean:145.125 - response_length_non_aborted/max:256.0 - response_length_non_aborted/min:75.0 - response_length_non_aborted/clip_ratio:0.0546875 - response/aborted_ratio:0.0 - prompt_length/mean:101.875 - prompt_length/max:169.0 - prompt_length/min:73.0 - prompt_length/clip_ratio:0.0 - timing_s/start_profile:5.1025766879320145e-05 - timing_s/generate_sequences:0.6771697402000427 - timing_s/reshard:0.5008471012115479 - timing_s/generation_timing/max:0.7759467363357544 - timing_s/generation_timing/min:0.49384644627571106 - timing_s/generation_timing/topk_ratio:0.125 - timing_s/gen:1.8636266626417637 - timing_s/reward:0.017636850010603666 - timing_s/old_log_prob:0.2443925621919334 - timing_s/values:0.14951528888195753 - timing_s/adv:0.01702857529744506 - timing_s/update_critic:0.44504289515316486 - timing_s/update_actor:0.43918753834441304 - timing_s/step:3.178868151269853 - timing_s/testing:3.8995088669471443 - timing_s/save_checkpoint:1.738096852786839 - timing_s/stop_profile:5.9116631746292114e-05 - timing_per_token_ms/update_actor:0.01389130624824181 - timing_per_token_ms/adv:0.0005386062530821439 - timing_per_token_ms/update_critic:0.014076508576453848 - timing_per_token_ms/gen:0.10032443274341966 - timing_per_token_ms/values:0.004729102001580134 - perf/total_num_tokens:31616 - perf/time_per_step:3.178868151269853 - perf/throughput:621.6048939339158 (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) ("Final validation metrics: {'val-core/openai/gsm8k/reward/mean@1': " (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) '0.4890068233510235}') (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) (job_name=verl-multinode-training-7550 worker_id=0) Training Progress: 100%|ββββββββββ| 174/174 [14:01<00:00, 5.33s/it]
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Trainy Konduktor","colors":{"primary":"#F07900","light":"#F8A145","dark":"#D35100"},"logo":{"light":"https://mintcdn.com/trainy/l_Z-YzGUiwLATp8A/trainy.svg?fit=max\u0026auto=format\u0026n=l_Z-YzGUiwLATp8A\u0026q=85\u0026s=a69ed11bf7bc11900bbf4631c26f5b72","dark":"https://mintcdn.com/trainy/l_Z-YzGUiwLATp8A/trainy.svg?fit=max\u0026auto=format\u0026n=l_Z-YzGUiwLATp8A\u0026q=85\u0026s=a69ed11bf7bc11900bbf4631c26f5b72"},"favicon":"https://mintcdn.com/trainy/l_Z-YzGUiwLATp8A/trainy.svg?fit=max\u0026auto=format\u0026n=l_Z-YzGUiwLATp8A\u0026q=85\u0026s=a69ed11bf7bc11900bbf4631c26f5b72","navbar":{"links":[{"href":"mailto:support@trainy.ai","label":"Support"},{"href":"https://trainy.teleport.sh","label":"Konduktor Login","type":"button"}],"primary":{"type":"button","label":"Pluto","href":"https://pluto.trainy.ai"}},"footer":{"socials":{"github":"https://github.com/Trainy-ai","linkedin":"https://www.linkedin.com/company/trainy-ai"}},"banner":{"content":"π Pluto PRO promo: academic users and early-stage startups can email \u003ca href='mailto:founders@trainy.ai'>founders@trainy.ai\u003c/a> for a PROMO code.","dismissible":true},"styling":{"latex":false},"navigation":{"global":{"anchors":[{"anchor":"Community","icon":"discord","href":"https://discord.com/invite/HQUBJSVgAP"},{"anchor":"Blog","icon":"newspaper","href":"https://trainy.ai/blog"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"trainy","hasAudioNarration":false,"actualSubdomain":"trainy","customDomains":["docs.trainy.ai"],"gitSource":{"type":"github","owner":"trainy-ai","repo":"konduktor","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae188e69b7d807c2d28ec7f","collectionId":"cf8cf953-69b5-4cd8-8395-d1eb9ebc7457","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae188e69b7d807c2d28ec7f"},"feedback":{"thumbs":true},"entitlements":{},"buildId":"6ae188e69b7d807c2d28ec7f","clientVersion":"0.0.4044","searchFilterCounts":[{"language":"default","tag":"Konduktor","count":68},{"language":"default","tag":"Pluto","count":56},{"language":"default","tag":"Core","count":24},{"language":"default","tag":"API Reference","count":22},{"language":"default","tag":"Examples","count":20},{"language":"default","tag":"Get Started","count":19},{"language":"default","tag":"Runs","count":19},{"language":"default","tag":"Example Task Yamls","count":13},{"language":"default","tag":"Visualizations","count":7},{"language":"default","tag":"Cloud Storage","count":5}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"pytorch/verl","slug":"/pytorch/verl","pageMetadata":{"title":"Ray/VeRL - LLM Reinforcement Learning","description":"Production-ready RL training library for large language models (LLMs) by VeRL.","href":"/pytorch/verl"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Production-ready RL training library for large language models (LLMs) by VeRL.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,..._provideComponents(),...props.components},{Accordion,CodeBlock}=_components;if(!Accordion)_missingMdxReference(`Accordion`,true);if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`This example shows how to train multinode a large language model via Reinforcement Learning using `,_jsx(_components.a,{href:`https://verl.readthedocs.io/en/latest/`,children:_jsx(_components.strong,{children:`verl: Volcano Engine Reinforcement Learning for LLMs.`})})]}),`\n`,_jsxs(_components.p,{children:[`Define the following `,_jsx(_components.code,{children:`verl.yaml`})]}),`\n`,_jsx(Accordion,{title:`verl.yaml`,description:`job definition yaml for verl multinode`,defaultOpen:true,icon:`robot`,id:`verl-yaml`,children:_jsx(CodeBlock,{numberOfLines:`185`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`185`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# Multi-node distributed training with Verl (Volcano Engine Reinforcement Learning) framework.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`#`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# Verl is a flexible and efficient reinforcement learning framework designed for`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# training large language models with RLHF (Reinforcement Learning from Human Feedback).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# This example demonstrates multi-node training using PPO on the GSM8K dataset.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`#`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# Prerequisites:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# - Access to Hugging Face models (Qwen/Qwen2.5-0.5B-Instruct in this example)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`#`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# Usage:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# # Launch a 2-node training cluster:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# $ konduktor launch examples/verl/multinode.yaml`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`#`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# # Stream logs:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# $ konduktor logs verl-cluster-*`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`#`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# # Cleanup:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# $ konduktor down verl-cluster-*`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# Known Issues: Need to set GLOO_SOCKET_IFNAME to primary network IF which changes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# per platform`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`name: verl-multinode-training`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`resources:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` accelerators: H200:8`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` image_id: verlai/verl:app-verl0.5-transformers4.55.4-vllm0.10.0-mcore0.13.0-te2.2 `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` cpus: 180`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` memory: 1000`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` labels:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` kueue.x-k8s.io/queue-name: user-queue`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` maxRunDurationSeconds: \"320000\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`num_nodes: 2 # Number of nodes for distributed training`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# Environment variables`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`envs:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` HF_HUB_ENABLE_HF_TRANSFER: \"1\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` TORCH_NCCL_AVOID_RECORD_STREAMS: \"1\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Optional: Add your W\u0026B API key for experiment tracking`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` WANDB_API_KEY: \u003cYOUR_WANDB_KEY> `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Training configuration`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` MODEL_NAME: Qwen/Qwen2.5-0.5B-Instruct`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` TOTAL_EPOCHS: 3`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ACTOR_LR: 1e-6`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` CRITIC_LR: 1e-5`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`run: |`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` set -x`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` export PIP_CONSTRAINT=\"\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` mkdir -p $HOME/checkpoints`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` apt update -y`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` apt install -y iputils-ping `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` git clone https://github.com/volcengine/verl.git`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` cd verl`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Install Verl and its dependencies (skip Megatron for this example)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` #USE_MEGATRON=0 bash scripts/install_vllm_sglang_mcore.sh`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` pip install --no-deps -e .`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` #pip install \"ray[default]\" # For Ray dashboard`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Set up distributed training environment`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Head IP: $MASTER_ADDR\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Number of nodes: $NUM_NODES\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Create custom runtime environment configuration`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` cat > runtime_env_custom.yaml \u003c\u003cEOF`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` working_dir: ./`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` excludes: [\"/.git/\", \"*.whl\", \"**/*.whl\"]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` env_vars:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` TORCH_NCCL_AVOID_RECORD_STREAMS: \"1\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` CUDA_DEVICE_MAX_CONNECTIONS: \"1\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` HF_HUB_ENABLE_HF_TRANSFER: \"1\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` EOF`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Ray cluster configuration`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` HEAD_PORT=6385`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` DASH_PORT=8280`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Function to check if Ray is already running`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` is_ray_alive () {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ray status --address=\"$1:$HEAD_PORT\" >/dev/null 2>\u00261`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` if [ \"$RANK\" == \"0\" ]; then`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Head node: prepare data, download model, start Ray head, and submit training job`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Setting up head node...\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Install additional dependencies for data processing`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` pip install datasets transformers`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Prepare GSM8K dataset`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` python3 examples/data_preprocess/gsm8k.py --local_dir ~/data/gsm8k`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Download model to cache`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` python3 -c \"import transformers; transformers.pipeline('text-generation', model='Qwen/Qwen2.5-0.5B-Instruct')\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Start Ray head node if not already running`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` if ! is_ray_alive \"$MASTER_ADDR\"; then`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Starting Ray head node...\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ray start --head --node-ip-address=\"$MASTER_ADDR\" \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` --port $HEAD_PORT --dashboard-port $DASH_PORT \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` --dashboard-host=0.0.0.0 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` --dashboard-agent-listen-port=52366 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` --disable-usage-stats \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` --num-gpus=$NUM_GPUS_PER_NODE`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` sleep 10`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` else`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Ray is already running at $MASTER_ADDR:$HEAD_PORT, reusing existing instance\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ray status --address=\"$MASTER_ADDR:$HEAD_PORT\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` fi`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ray status`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ibdev2netdev`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Submit the training job to Ray`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` export RAY_ADDRESS=\"http://localhost:$DASH_PORT\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Submitting training job to Ray cluster...\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` HYDRA_FULL_ERROR=1 ray job submit --address=\"$RAY_ADDRESS\" --working-dir=. \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` --runtime-env=runtime_env_custom.yaml \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` -- python3 -m verl.trainer.main_ppo \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` data.train_files=$HOME/data/gsm8k/train.parquet \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` data.val_files=$HOME/data/gsm8k/test.parquet \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` data.train_batch_size=128 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` data.max_prompt_length=512 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` data.max_response_length=256 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.model.path=$MODEL_NAME \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.actor.optim.lr=$ACTOR_LR \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.actor.ppo_mini_batch_size=64 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=4 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.rollout.name=vllm \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.rollout.log_prob_micro_batch_size_per_gpu=8 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.rollout.tensor_model_parallel_size=1 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.rollout.gpu_memory_utilization=0.4 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` actor_rollout_ref.ref.log_prob_micro_batch_size_per_gpu=4 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` critic.optim.lr=$CRITIC_LR \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` critic.model.path=$MODEL_NAME \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` critic.ppo_micro_batch_size_per_gpu=4 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` critic.ppo_mini_batch_size=64 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` algorithm.kl_ctrl.kl_coef=0.001 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.project_name=ppo_training \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.experiment_name=qwen-2.5-0.5B \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.val_before_train=False \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.n_gpus_per_node=$NUM_GPUS_PER_NODE \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.nnodes=$NUM_NODES \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.default_local_dir=$HOME/checkpoints \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.save_freq=10 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.test_freq=10 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.total_epochs=$TOTAL_EPOCHS \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.logger=['console'] \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` trainer.resume_mode=auto 2>\u00261 | tee verl_training.log`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # To enable W\u0026B logging:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # 1. Set WANDB_API_KEY in envs or pass via --secret WANDB_API_KEY`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # 2. Change trainer.logger to: trainer.logger=['console', 'wandb']`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # 3. Add: trainer.wandb_project='verl-rlhf'`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` exit 1 # this forces the other workers to shutdown`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` else`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Worker nodes: connect to Ray head`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Setting up worker node...\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Head IP: $MASTER_ADDR\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"HEAD_PORT: $HEAD_PORT\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"NUM_GPUS: $NUM_GPUS_PER_NODE\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Get this worker's IP address`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` worker_ip=$(hostname -I | awk '{print $1}')`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Worker IP: $worker_ip\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Checking if worker $worker_ip is already in Ray cluster at $MASTER_ADDR:$HEAD_PORT\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` if ray list nodes --address=$MASTER_ADDR:$HEAD_PORT 2>/dev/null | grep -q \"$worker_ip\"; then`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Worker $worker_ip already connected to Ray cluster\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ray status --address=$MASTER_ADDR:$HEAD_PORT`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` else`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Worker not connected, waiting for head node to start\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` sleep 20`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Starting Ray worker\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ray start --address $MASTER_ADDR:$HEAD_PORT --disable-usage-stats --num-gpus=$NUM_GPUS_PER_NODE`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` echo \"Ray start exit code: $?\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` # Verify connection after starting`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` sleep 5`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ray status --address=$MASTER_ADDR:$HEAD_PORT`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` fi`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:\" while ping -c 1 ${MASTER_ADDR}; do\"})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` sleep 5`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` done`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` fi`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})})}),`\n`,_jsx(_components.p,{children:`and launch with`}),`\n`,_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`konduktor launch verl.yaml`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.p,{children:`While the job is running you should see a sample output like in the following`}),`\n`,_jsx(CodeBlock,{numberOfLines:`25`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`25`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [prompt] system`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) You are Qwen, created by Alibaba Cloud. You are a helpful assistant.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) user`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) Janetβs ducks lay 16 eggs per day. She eats three for breakfast every morning and bakes muffins for her friends every day with four. She sells the remainder at the farmers' market daily for $2 per fresh duck egg. How much in dollars does she make every day at the farmers' market? Let's think step by step and output the final answer after \"####\".`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) assistant`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [response] First, we calculate the number of eggs Janet's ducks lay in a day. Since she lays 16 eggs per day, the number of eggs she eats in a day is 16 - 3 - 4 = 10 eggs. This means she sells 10 eggs daily at the farmers' market. Since each egg sells for $2, the daily earnings are 10 * 2 = $20. Therefore, the amount of money Janet makes every day at the farmers' market is $20.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) #### 20`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) #### 20`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [ground_truth] 18`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) [score] 0.0`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) len reward_extra_infos_dict['reward']: 1319`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) local_global_step_folder: /root/checkpoints/global_step_174`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=1498, ip=172.17.1.94) INFO:2025-08-25 23:17:09,357:[Rank 0] Saved model to /root/checkpoints/global_step_174/actor/model_world_size_16_rank_0.pt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=1499, ip=172.17.1.94) INFO:2025-08-25 23:17:09,336:[Rank 1] Saved model to /root/checkpoints/global_step_174/actor/model_world_size_16_rank_1.pt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=24109) INFO:2025-08-25 23:17:09,614:[Rank 10] Saved optim to /root/checkpoints/global_step_174/actor/optim_world_size_16_rank_10.pt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=24109) INFO:2025-08-25 23:17:09,615:[Rank 10] Saved extra_state to /root/checkpoints/global_step_174/actor/extra_state_world_size_16_rank_10.pt`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (WorkerDict pid=1498, ip=172.17.1.94) INFO:2025-08-25 23:17:10,020:[Rank 0] Saved model config and tokenizer class to /root/checkpoints/global_step_174/actor/huggingface`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) step:174 - global_seqlen/min:1756 - global_seqlen/max:2241 - global_seqlen/minmax_diff:485 - global_seqlen/balanced_min:1974 - global_seqlen/balanced_max:1977 - global_seqlen/mean:1976.0 - actor/entropy:0.10149244964122772 - critic/vf_loss:0.051519379019737244 - critic/vf_clipfrac:0.0 - critic/vpred_mean:0.8081025183200836 - critic/grad_norm:36.863529205322266 - perf/mfu/critic:0.01831457949805057 - critic/lr:1e-05 - actor/pg_loss:-0.5662342011928558 - actor/pg_clipfrac:0.0051369862630963326 - actor/ppo_kl:-0.0011725000804290175 - actor/pg_clipfrac_lower:0.0 - actor/grad_norm:4.237640619277954 - perf/mfu/actor:0.0185783582944669 - perf/max_memory_allocated_gb:56.59689235687256 - perf/max_memory_reserved_gb:59.7578125 - perf/cpu_memory_used_gb:58.61131286621094 - actor/lr:1e-06 - val-core/openai/gsm8k/reward/mean@1:0.4890068233510235 - training/global_step:174 - training/epoch:2 - critic/score/mean:0.609375 - critic/score/max:1.0 - critic/score/min:0.0 - critic/rewards/mean:0.609375 - critic/rewards/max:1.0 - critic/rewards/min:0.0 - critic/advantages/mean:1.1653965792390863e-08 - critic/advantages/max:2.7394912242889404 - critic/advantages/min:-2.5047049522399902 - critic/returns/mean:0.5375215411186218 - critic/returns/max:1.0 - critic/returns/min:0.0 - critic/values/mean:0.73046875 - critic/values/max:1.2421875 - critic/values/min:0.01556396484375 - critic/vf_explained_var:0.3024832606315613 - response_length/mean:145.125 - response_length/max:256.0 - response_length/min:75.0 - response_length/clip_ratio:0.0546875 - response_length_non_aborted/mean:145.125 - response_length_non_aborted/max:256.0 - response_length_non_aborted/min:75.0 - response_length_non_aborted/clip_ratio:0.0546875 - response/aborted_ratio:0.0 - prompt_length/mean:101.875 - prompt_length/max:169.0 - prompt_length/min:73.0 - prompt_length/clip_ratio:0.0 - timing_s/start_profile:5.1025766879320145e-05 - timing_s/generate_sequences:0.6771697402000427 - timing_s/reshard:0.5008471012115479 - timing_s/generation_timing/max:0.7759467363357544 - timing_s/generation_timing/min:0.49384644627571106 - timing_s/generation_timing/topk_ratio:0.125 - timing_s/gen:1.8636266626417637 - timing_s/reward:0.017636850010603666 - timing_s/old_log_prob:0.2443925621919334 - timing_s/values:0.14951528888195753 - timing_s/adv:0.01702857529744506 - timing_s/update_critic:0.44504289515316486 - timing_s/update_actor:0.43918753834441304 - timing_s/step:3.178868151269853 - timing_s/testing:3.8995088669471443 - timing_s/save_checkpoint:1.738096852786839 - timing_s/stop_profile:5.9116631746292114e-05 - timing_per_token_ms/update_actor:0.01389130624824181 - timing_per_token_ms/adv:0.0005386062530821439 - timing_per_token_ms/update_critic:0.014076508576453848 - timing_per_token_ms/gen:0.10032443274341966 - timing_per_token_ms/values:0.004729102001580134 - perf/total_num_tokens:31616 - perf/time_per_step:3.178868151269853 - perf/throughput:621.6048939339158`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) (\"Final validation metrics: {'val-core/openai/gsm8k/reward/mean@1': \"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513) '0.4890068233510235}')`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) (TaskRunner pid=14513)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (job_name=verl-multinode-training-7550 worker_id=0) Training Progress: 100%|ββββββββββ| 174/174 [14:01\u003c00:00, 5.33s/it]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Ray/VeRL - LLM Reinforcement Learning","description":"Production-ready RL training library for large language models (LLMs) by VeRL.","href":"/pytorch/verl"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"subdomain":"trainy","siteName":"Trainy Konduktor","title":"Ray/VeRL - LLM Reinforcement Learning - Trainy Konduktor","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-01-28T01:24:24.838Z","originalFileLocation":"pytorch/verl.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Production-ready RL training library for large language models (LLMs) by VeRL.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Trainy Konduktor\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Ray/VeRL - LLM Reinforcement Learning - Trainy Konduktor\">\u003cmeta data-mint-head property=\"og:description\" content=\"Production-ready RL training library for large language models (LLMs) by VeRL.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Trainy Konduktor\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.trainy.ai/pytorch/verl\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://trainy.mintlify.app/_mintlify/api/og/v2?division=PyTorch\u0026amp;title=Ray%2FVeRL+-+LLM+Reinforcement+Learning\u0026amp;description=Production-ready+RL+training+library+for+large+language+models+%28LLMs%29+by+VeRL.\u0026amp;theme=3d9c285da33ee525cd476c3d\u0026amp;signature=e324cb01ca8195157c9bf321bccbf0bd82082a38f8e7cb012f359ecd49a4ecc0\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Ray/VeRL - LLM Reinforcement Learning - Trainy Konduktor\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Production-ready RL training library for large language models (LLMs) by VeRL.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://trainy.mintlify.app/_mintlify/api/og/v2?division=PyTorch\u0026amp;title=Ray%2FVeRL+-+LLM+Reinforcement+Learning\u0026amp;description=Production-ready+RL+training+library+for+large+language+models+%28LLMs%29+by+VeRL.\u0026amp;theme=3d9c285da33ee525cd476c3d\u0026amp;signature=e324cb01ca8195157c9bf321bccbf0bd82082a38f8e7cb012f359ecd49a4ecc0\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/trainy/rockd6CB-Yto9fqu/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Trainy Konduktor\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#F07900\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.trainy.ai/pytorch/verl\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/pytorch/verl.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.trainy.ai/#organization\",\"name\":\"Trainy Konduktor\",\"url\":\"https://docs.trainy.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/trainy/l_Z-YzGUiwLATp8A/trainy.svg?fit=max\u0026auto=format\u0026n=l_Z-YzGUiwLATp8A\u0026q=85\u0026s=a69ed11bf7bc11900bbf4631c26f5b72\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.trainy.ai#website\",\"name\":\"Trainy Konduktor\",\"url\":\"https://docs.trainy.ai\",\"publisher\":{\"@id\":\"https://docs.trainy.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.trainy.ai/pytorch/verl#webpage\",\"url\":\"https://docs.trainy.ai/pytorch/verl\",\"name\":\"Ray/VeRL - LLM Reinforcement Learning\",\"description\":\"Production-ready RL training library for large language models (LLMs) by VeRL.\",\"dateModified\":\"2026-01-28T01:24:24.838Z\",\"isPartOf\":{\"@id\":\"https://docs.trainy.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.trainy.ai/pytorch/verl#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.trainy.ai/pytorch/verl#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Example Task Yamls\",\"item\":\"https://docs.trainy.ai/storage/single-file-upload\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PyTorch\",\"item\":\"https://docs.trainy.ai/pytorch/torchrun\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Ray/VeRL - LLM Reinforcement Learning\",\"item\":\"https://docs.trainy.ai/pytorch/verl\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.trainy.ai/pytorch/verl#article\",\"headline\":\"Ray/VeRL - LLM Reinforcement Learning\",\"name\":\"Ray/VeRL - LLM Reinforcement Learning\",\"description\":\"Production-ready RL training library for large language models (LLMs) by VeRL.\",\"url\":\"https://docs.trainy.ai/pytorch/verl\",\"mainEntityOfPage\":{\"@id\":\"https://docs.trainy.ai/pytorch/verl#webpage\"},\"dateModified\":\"2026-01-28T01:24:24.838Z\",\"publisher\":{\"@id\":\"https://docs.trainy.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.trainy.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Trainy Konduktor\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Trainy Konduktor","nav":{"global":{"anchors":[{"anchor":"Community","icon":"discord","href":"https://discord.com/invite/HQUBJSVgAP"},{"anchor":"Blog","icon":"newspaper","href":"https://trainy.ai/blog"}]},"products":[{"product":"Konduktor","tabs":[{"tab":"Konduktor","pages":[{"title":"Konduktor","href":"/overview"}]},{"tab":"Examples","groups":[{"group":"Schemas","pages":[{"title":"Konduktor Config Yamls","href":"/config-schema"},{"title":"Konduktor Launch Task Yamls","href":"/task-schema"},{"title":"Konduktor Serve Launch Deployment Yamls","href":"/deployment-schema"}]},{"group":"Example Task Yamls","pages":[{"group":"Cloud Storage","pages":[{"title":"Single File Upload","href":"/storage/single-file-upload"},{"title":"Directory Upload","href":"/storage/directory-upload"},{"title":"File + Directory Upload","href":"/storage/file-directory-upload"},{"title":"Workdir File Upload","href":"/storage/workdir-file-upload"},{"title":"Git SSH Key Upload","href":"/storage/private-repo-ssh"}]},{"group":"Secrets","pages":[{"title":"Default Secrets","href":"/secrets/default"},{"title":"Git-SSH Secrets","href":"/secrets/git-ssh"},{"title":"Env Secrets","href":"/secrets/env"}]},{"group":"Environment Variables","pages":[{"title":"Environment Variables","href":"/env"}]},{"group":"MPI","pages":[{"title":"MPI","href":"/MPI"}]},{"group":"PyTorch","pages":[{"title":"Torchrun","href":"/pytorch/torchrun"},{"title":"MosaicML Composer","description":"Train with MosaicML composer","href":"/pytorch/composer"},{"title":"Ray/VeRL - LLM Reinforcement Learning","href":"/pytorch/verl"}]}]},{"group":"Example Deployment Yamls","pages":[{"group":"General Deployments","pages":[{"title":"Simple General","description":"Example deployment yamls for general deployments with `konduktor serve`","href":"/deployments/simple-general"},{"title":"Complex General","href":"/deployments/complex-general"}]},{"group":"vLLM Deployments","pages":[{"title":"Simple vLLM","href":"/deployments/simple-vllm"},{"title":"Complex vLLM","href":"/deployments/complex-vllm"}]}]}]}]},{"product":"Pluto","pages":[{"title":"Pluto","href":"/pluto/overview"}]}]},"basePath":"","title":"Ray/VeRL - LLM Reinforcement Learning - Trainy Konduktor","buildId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","deploymentId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","dynamics":["10e4515597"],"chunks":["BannerMarkdown-CX_qQQOL.js","dist-BTZUMDnx.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-xpJZXxdP.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js"]}