はじめに
先日、松尾研LLMコンペ決勝戦RAMENチームででms-swiftというライブラリを使用しQwen3-235B-A22B-thinkingをGRPOすることを目的として、まずはQwen3-30B-A3B-Instruct-2507を回し始めました。
なんとか学習に到達しシーケンスバーまで見ることができたのですが、何故か途中でエラーになってしまったのです。
この原因は、vLLMという頭を抱えてしまうライブラリなのです。
アジェンダ
- ms-swiftとは
- GRPOのコード
- 実際のエラー
- vLLMとは
- 原因の仮説
- おわりに
ms-swiftとは
ms-swift(ModelScope Swift)は、ModelScopeが提供する大規模言語モデルと多モーダル大規模モデルのトレーニングとデプロイのための包括的なフレームワークです。
主な特徴として、LoRAのPEFT(Parameter-Efficient Fine-Tuning)手法や全パラメータファインチューニングに対応しています。特にRLHF(Reinforcement Learning from Human Feedback)トレーニングにおいて、DPO、GRPO、PPO、などの強化学習手法をサポートしているのが特徴です。
さらにDeepSpeed ZeRO-2/ZeRO-3、FSDP、そしてMegatronのTensor Parallelism、Pipeline Parallelism、Sequence Parallelismなどの分散トレーニング技術にも対応しています。
今回のコンペではms-swiftにおいて、SFT/DFT/DPOは構築し、GRPO/GSPOを挑戦しました。
GRPOのコード
ms-swiftにおいてGRPOの構築例を参考にし、作成しました。
GRPOの動きとしては以下のような流れで学習が進んでいきます。
1. 現在のモデルで複数の応答を生成(vLLMサーバー)
↓
2. 応答に対して報酬を計算(トレーニングノード)
↓
3. 報酬に基づいてLoRAパラメータを更新(トレーニングノード)
↓
4. 更新されたパラメータをvLLMに送信
↓
5. 1に戻る
以下実際のコードです。
swift_grpo.sh
#!/bin/bash
#SBATCH --job-name=swift-grpo-qwen3
#SBATCH -p P05
#SBATCH --nodelist=osk-gpu59
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --gpus-per-node=8
#SBATCH --cpus-per-task=64
#SBATCH --time=6-00:00:00
#SBATCH --mem=0
#SBATCH --output=./logs/slurm-%j.out
#SBATCH --error=./logs/slurm-%j.err
mkdir -p output
############## Slurm pre-amble finished ##############
set -eo pipefail
######## 1. Modules and Conda environments ########
# モジュールシステムの初期化
source /etc/profile.d/modules.sh
module reset
module load hpcx/2.18.1-gcc-cuda12/hpcx-mt
module load miniconda/24.7.1-py311
# Condaの初期化(conda initは使わない)
source /home/appli/miniconda3/24.7.1-py311/etc/profile.d/conda.sh
# Conda環境のアクティベート
export CONDA_PATH="/home/Competition2025/P05/shareP05/train/envs/hara_msswift"
conda activate $CONDA_PATH
# 環境が正しくアクティベートされたか確認
echo "Python path: $(which python)"
echo "Conda env: $CONDA_DEFAULT_ENV"
export VLLM_ENABLE_V1_MULTIPROCESSING=0 # V1 multiprocessingを無効化(重要)
export VLLM_WORKER_MULTIPROC_METHOD=spawn # メソッドは新しいPythonインタープリタプロセスを起動
export PYTORCH_CUDA_ALLOC_CONF="expandable_segments:True"
export NCCL_P2P_DISABLE=0 # P2P通信有効(NVLink使用)
export NCCL_IB_DISABLE=0 # RoCE有効化
# XXX 端末ごとに異なる設定であるため要確認
export NCCL_IB_HCA=mlx5_0,mlx5_1,mlx5_2,mlx5_3,mlx5_5,mlx5_6,mlx5_7,mlx5_11 # 利用可能なHCA
export NCCL_IB_GID_INDEX=3 # RoCE v2用GIDインデックス
export NCCL_IB_ROCE_VERSION_NUM=2 # RoCE v2使用
export NCCL_IB_CUDA_SUPPORT=1 # GPUDirect RDMA有効
export NCCL_NET_GDR_LEVEL=5 # 最大GDRレベル
export NCCL_NET_GDR_READ=1 # GDR読み取り有効
export NCCL_IB_QPS_PER_CONNECTION=4 # Queue Pair数
export NCCL_IB_TC=0 # Traffic Class
export NCCL_IB_SL=0 # Service Level
export NCCL_IB_TIMEOUT=22 # タイムアウト値(大規模向け)
export NCCL_IB_RETRY_CNT=7 # リトライ回数
export NCCL_IB_AR_THRESHOLD=0 # RoCEではアダプティブルーティング無効
# ===== Socket通信設定(バックアップ)=====
# XXX 端末ごとに異なる設定であるため要確認
export NCCL_SOCKET_IFNAME=enp25s0np0,enp41s0np0,enp59s0np0,enp86s0np0,enp155s0np0,enp170s0np0,enp187s0np0,enp210s0np0,enp218s0np0
export NCCL_SOCKET_NTHREADS=8 # 8GPU用に増加
export NCCL_NSOCKS_PERTHREAD=8 # ソケット数
export NCCL_SOCKET_FAMILY=AF_INET # IPv4使用
# ulimit設定
ulimit -v unlimited
ulimit -m unlimited
ulimit -c unlimited
ulimit -n 65535
export WANDB_ENTITY='ken05-matuo-llm-88_llm_2025_suzuki'
export WANDB_PROJECT="swift-grpo-qwen3"
export WANDB_RUN_NAME="grpo-${SLURM_JOB_ID}"
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
NPROC_PER_NODE=8 \
swift rlhf \
--rlhf_type grpo \
--model Qwen/Qwen3-30B-A3B-Instruct-2507 \
--reward_funcs external_countdown format \
--use_vllm true \
--vllm_mode server \
--vllm_server_host 192.168.11.58 \
--vllm_server_port 8000 \
--train_type lora \
--lora_rank 4 \
--lora_alpha 4 \
--torch_dtype bfloat16 \
--dataset 'zouxuhong/Countdown-Tasks-3to4#16' \
--max_length 1024 \
--max_completion_length 512 \
--num_train_epochs 4 \
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 1 \
--learning_rate 1e-5 \
--gradient_accumulation_steps 4 \
--eval_steps 500 \
--save_steps 100 \
--save_total_limit 20 \
--logging_steps 1 \
--output_dir ./output/GRPO_COUNTDOWN \
--warmup_ratio 0.01 \
--dataloader_num_workers 16 \
--num_generations 2 \
--temperature 1.0 \
--system 'You are a helpful assistant. You first thinks about the reasoning process in the mind and then provides the user with the answer.' \
--deepspeed zero3 \
--gc_collect_after_offload true \
--log_completions true \
--beta 0.001 \
--num_iterations 2 \
--move_model_batches 8 \
--gradient_checkpointing_kwargs '{"use_reentrant": false}' \
--report_to wandb \
--log_completions true \
実際のエラー
コードを実行すると、5時間以上ずっと動き続け何もログが更新されず気づいたときには経過し落ちてしまいました。
以下は実際のエラーログ(一部)です。
error_log.txt
NFO: 192.168.11.64:37426 - "POST /init_communicator/ HTTP/1.1" 200 OK
(VllmWorker rank=0 pid=817102) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=0 pid=817102) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=0 pid=817102) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=0 pid=817102) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=0 pid=817102) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=0 pid=817102) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=0 pid=817102) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
(VllmWorker rank=3 pid=817105) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=3 pid=817105) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=3 pid=817105) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=3 pid=817105) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=3 pid=817105) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=3 pid=817105) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=3 pid=817105) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
(VllmWorker rank=6 pid=817108) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=6 pid=817108) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=6 pid=817108) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=6 pid=817108) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=6 pid=817108) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=6 pid=817108) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=6 pid=817108) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
(VllmWorker rank=7 pid=817109) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=7 pid=817109) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=7 pid=817109) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=7 pid=817109) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=7 pid=817109) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=7 pid=817109) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=7 pid=817109) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
(VllmWorker rank=4 pid=817106) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=4 pid=817106) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=4 pid=817106) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=4 pid=817106) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=4 pid=817106) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=4 pid=817106) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=4 pid=817106) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
(VllmWorker rank=5 pid=817107) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=5 pid=817107) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=5 pid=817107) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=5 pid=817107) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=5 pid=817107) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=5 pid=817107) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=5 pid=817107) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
(VllmWorker rank=2 pid=817104) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=2 pid=817104) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=2 pid=817104) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=2 pid=817104) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=2 pid=817104) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=2 pid=817104) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=2 pid=817104) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
(VllmWorker rank=1 pid=817103) ERROR 09-13 17:09:21 [multiproc_executor.py:546] WorkerProc hit an exception.
(VllmWorker rank=1 pid=817103) ERROR 09-13 17:09:21 [multiproc_executor.py:546] Traceback (most recent call last):
(VllmWorker rank=1 pid=817103) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 541, in worker_busy_loop
(VllmWorker rank=1 pid=817103) ERROR 09-13 17:09:21 [multiproc_executor.py:546] output = func(*args, **kwargs)
(VllmWorker rank=1 pid=817103) ERROR 09-13 17:09:21 [multiproc_executor.py:546] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/trl/scripts/vllm_serve.py", line 108, in init_communicator
(VllmWorker rank=1 pid=817103) ERROR 09-13 17:09:21 [multiproc_executor.py:546] raise RuntimeError("Weight update group already initialized. Call close_communicator first.")
(VllmWorker rank=1 pid=817103) ERROR 09-13 17:09:21 [multiproc_executor.py:546] RuntimeError: Weight update group already initialized. Call close_communicator first.
ERROR 09-13 17:09:21 [core.py:700] Invocation of collective_rpc method failed
ERROR 09-13 17:09:21 [core.py:700] Traceback (most recent call last):
ERROR 09-13 17:09:21 [core.py:700] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/engine/core.py", line 697, in _handle_client_request
ERROR 09-13 17:09:21 [core.py:700] output.result = method(
ERROR 09-13 17:09:21 [core.py:700] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/engine/core.py", line 388, in collective_rpc
ERROR 09-13 17:09:21 [core.py:700] return self.model_executor.collective_rpc(method, timeout, args,
ERROR 09-13 17:09:21 [core.py:700] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 237, in collective_rpc
ERROR 09-13 17:09:21 [core.py:700] result = get_response(w, dequeue_timeout)
ERROR 09-13 17:09:21 [core.py:700] File "/home/Competition2025/P05/shareP05/train/envs/hara_msswift/lib/python3.10/site-packages/vllm/v1/executor/multiproc_executor.py", line 224, in get_response
ERROR 09-13 17:09:21 [core.py:700] raise RuntimeError(
ERROR 09-13 17:09:21 [core.py:700] RuntimeError: Worker failed with error 'Weight update group already initialized. Call close_communicator first.', please check the stack trace above for the root cause
vllm_log.txt
INFO: 192.168.11.59:37840 - "POST /update_named_param/ HTTP/1.1" 200 OK
INFO: 192.168.11.59:37840 - "POST /update_named_param/ HTTP/1.1" 200 OK
INFO: 192.168.11.59:37840 - "POST /update_named_param/ HTTP/1.1" 200 OK
INFO 09-13 15:21:13 [block_pool.py:321] Successfully reset prefix cache
INFO: 192.168.11.59:38136 - "POST /reset_prefix_cache/ HTTP/1.1" 200 OK
INFO: 192.168.11.59:38136 - "POST /infer/ HTTP/1.1" 200 OK
INFO: 192.168.11.64:37424 - "GET /health/ HTTP/1.1" 200 OK
INFO: 192.168.11.64:37426 - "GET /get_world_size/ HTTP/1.1" 200 OK
INFO: 192.168.11.64:37426 - "POST /init_communicator/ HTTP/1.1" 200 OK
このエラーを分析したところ、際のエラーのセクションでも提示しているようにvLLMサーバー側に更新をupdate_named_param やreset_prefix_cacheなどでログが出ているためどうやらGRPOの動きとして4番と5番の間でどうやらスタックしているようです。
vllmサーバー側に更新されたパラメータは送られていることはログとして確認できています。しかしそれからのログが全く出力されなくなっております。
改めてvLLMのことを振り返ってみましょう。
vLLMとは
vLLMは、カリフォルニア大学バークレー校のSky Computing Labで開発された、LLMの推論のための高速で使いやすいオープンソースライブラリです。
vLLMサーバーが複数の応答を高速に生成する役割を担っており、効率的にメモリに割り当て推論を行います。
しかしvLLMでは多くのエラーが起きており、単純な推論でもサーバーが立ち上がるのに何度も実行しなければ完全に立ち上がらなかったり、推論していたとしても途中でエラーとなったり、単純にvLLMライブラリのエラーハンドリングが適当で原因特定しにくいというものも存在します。(評価班の知見)
個人的にvLLMライブラリを使い込んでライブラリを修正したくなりましたね・・・w
それから原因をエラーからvLLMの観点から分析します。とはいえ仮説なので、参考程度に見ていただけるとありがたいです。
原因の仮説
エラーログから分析したところ、実確認できているため、vLLMサーバーで重み更新用の通信グループが既に初期化されているのに、再度初期化しようとしてエラーが発生ということによりスタックしていたようです。
おそらくms-swiftのライブラリ上でGRPOが動いている部分でclose_communicator()が呼ばれておらずスタックしたのではないかと考えております。
またvLLM自体起動したとしても適切に以前起動したものが残っておりcleanupが行われておらず引っかかった可能性があります。
おわりに
ms-swiftにおいてGRPOが(GSPOも同じ)エラーになってしまった原因はおそらくvLLMに起因したもので、初期化部分でうまくイテレーションが分散処理になった瞬間にうまくいかなかったものと思われます。(シングルノードMoEでなければできました。)
vLLMは評価班側でも多くの問題が起こった原因らしく、とはいったもののvLLMの推論速度や分散は効率が良かったり多くのライブラリで標準で使用されていることが多いためvLLMを使いこなすまたvLLMライブラリ中身自体を知っておく必要があるのかなと思います。(もしかしたらある時にバージョンが有るとすべてが解決されている可能性はありますが、マルチノードでMoEで使用者が少ないとすると・・・可能性は低いかもですね・・・)
参考文献
プロジェクトのクレジット
本プロジェクトは、国立研究開発法人新エネルギー・産業技術開発機構(NEDO)の「日本語版医療特化型LLMの社会実装に向けた安全性検証・実証」における基盤モデルの開発プロジェクトの一環として行われました。