MS-SWIFT로 Qwen3 파인튜닝 및 강화학습 하기

MS-SWIFT로 Qwen3 파인튜닝 및 강화학습 하기

MS-SWIFT(ModelScope SWIFT, ms-swift)는 ModelScope 커뮤니티가 제공하는 대규모 모델 및 멀티모달 대규모 모델 훈련·배포 프레임워크예요. 이 글에서는 ms-swift로 Qwen3-8B에 SFT와 GRPO를 수행하고, Megatron-SWIFT로 Qwen3-30B-A3B에 SFT를 수행하는 실행 가능한 훈련 데모를 안내해요.

출처: 문서

본문

GitHub 저장소: ms-swift

ms-swift로 LLM을 훈련하는 특징:

  • 모델 유형: 500개 이상의 순수 텍스트 대규모 모델과 200개 이상의 멀티모달 대규모 모델을 지원하며, 훈련부터 배포까지 전 과정을 다뤄요.
  • 하드웨어 지원: CPU, RTX 시리즈 GPU, T4/V100, A10/A100/H100, Ascend NPU, MPS 등과 호환돼요.
  • 훈련 방법: 전체 파라미터 파인튜닝, LoRA, QLoRA, DoRA 등의 기법을 지원해요.
  • 분산 훈련: DDP, device_map, DeepSpeed ZeRO-2/ZeRO-3, FSDP 같은 분산 훈련 기술을 지원하고, Megatron의 텐서 병렬, 파이프라인 병렬, 시퀀스 병렬, 전문가 병렬 등 병렬 기법을 통합해요.
  • RLHF 훈련: 순수 텍스트 및 멀티모달 대규모 모델 모두에 DPO, GRPO, DAPO, RM, PPO, KTO 등의 인간 정렬 방법을 지원해요.

전문가 병렬 기술을 통해 MoE 모델 훈련을 약 10배 가까이 가속할 수 있어요.

파인튜닝을 시작하기 전에 환경을 제대로 설정했는지 확인하세요.

pip install ms-swift -U
# Install from source
pip install git+https://github.com/modelscope/ms-swift.git

pip install transformers -U

# Optional packages
pip install deepspeed # multi-GPU training
pip install liger-kernel # save GPU memory resources
pip install flash-attn --no-build-isolation

지도 파인튜닝 (SFT)

데이터 준비

ms-swift를 사용한 SFT용 커스텀 데이터셋 형식은 다음과 같아요 (system 필드는 선택 사항). JSON, JSONL, CSV 같은 형식으로 구성할 수 있어요. 훈련 스크립트에서 --dataset <dataset_path>를 지정하세요.

전체 데이터셋 형식 지침은 커스텀 데이터셋 문서를 참고하세요.

일반 형식:

{"messages": [
    {"role": "system", "content": "<system-prompt>"},
    {"role": "user", "content": "<query1>"},
    {"role": "assistant", "content": "<response1>"}
]}

think가 있는 형식:

{"messages": [
    {"role": "user", "content": "Where is the capital of Zhejiang?"},
    {"role": "assistant", "content": " thinking\n...\n response\n\nThe capital of Zhejiang is Hangzhou."}
]}

사고 사슬이 없는 데이터로 훈련하면서도 모델의 추론 능력을 유지하려면, 파인튜닝 중 손상을 최소화하는 두 가지 방법이 있어요.

옵션 1: 훈련 중 --loss_scale ignore_empty_think를 지정해 thinking\n\n response\n\n에 대한 손실 계산을 무시하고 추론 능력의 손실을 막아요. 훈련 스크립트는 여기를 참고하세요. 커스텀 데이터셋 형식은 다음과 같아요:

{"messages": [
    {"role": "user", "content": "Where is the capital of Zhejiang?"},
    {"role": "assistant", "content": " thinking\n\n response\n\nThe capital of Zhejiang is Hangzhou."}
]}

옵션 2: 데이터셋의 쿼리에 /no_think를 추가해 추론 능력의 손실을 피해요. 훈련 스크립트는 여기를 참고하세요. 커스텀 데이터셋 형식은 다음과 같아요:

{"messages": [
    {"role": "user", "content": "Where is the capital of Zhejiang? /no_think"},
    {"role": "assistant", "content": " thinking\n\n response\n\nThe capital of Zhejiang is Hangzhou."}
]}

30분 자기 인지 파인튜닝

이 섹션은 Qwen3-8B 모델의 30분 자기 인지 파인튜닝 과정을 소개해요. 필요한 GPU 메모리는 22GB이며, ModelScope의 무료 컴퓨팅 리소스인 A10에서 실행할 수 있어요.

훈련 후 모델은 원래 Alibaba Cloud가 훈련한 "Qwen"이라는 자기 인지 대신, "swift"가 훈련한 "swift-robot"으로 자신을 식별해요.

오프라인 환경에서 훈련해야 한다면 모델과 데이터셋을 수동으로 다운로드하고 --model <model-path>와 --dataset <dataset-dir>을 지정할 수 있어요. 데이터셋은 ModelScope Hub에서 찾을 수 있어요.

훈련 스크립트의 각 파라미터 의미는 커맨드라인 파라미터 문서를 참고하세요.

CUDA_VISIBLE_DEVICES=0 \
swift sft \
    --model Qwen/Qwen3-8B \
    --train_type lora \
    --dataset 'swift/Qwen3-SFT-Mixin#2000' \
              'swift/self-cognition:qwen3#600' \
    --torch_dtype bfloat16 \
    --num_train_epochs 1 \
    --per_device_train_batch_size 1 \
    --per_device_eval_batch_size 1 \
    --learning_rate 1e-4 \
    --lora_rank 8 \
    --lora_alpha 32 \
    --target_modules all-linear \
    --gradient_accumulation_steps 16 \
    --eval_steps 50 \
    --save_steps 50 \
    --save_total_limit 2 \
    --logging_steps 5 \
    --max_length 2048 \
    --output_dir output \
    --warmup_ratio 0.05 \
    --dataloader_num_workers 4 \
    --model_author swift \
    --model_name swift-robot

파인튜닝 후 다음 스크립트로 파인튜닝 결과를 테스트할 수 있어요. --adapters 섹션을 마지막으로 저장된 체크포인트의 디렉터리 경로로 수정해야 한다는 점을 참고하세요.

CUDA_VISIBLE_DEVICES=0 \
swift infer \
    --adapters output/vx-xxx/checkpoint-xxx \
    --stream true \
    --temperature 0 \
    --max_new_tokens 2048
<<< who are you?
 thinking
Okay, the user asked, "who are you?" I need to introduce myself. Let me start by stating my name, swift-robot. Then, I should mention that I'm an AI assistant developed by swift. I should explain my purpose, which is to provide information and assistance. I should also highlight my capabilities, like answering questions, generating text, and engaging in conversation. It's important to keep the tone friendly and approachable. Maybe add something about being here to help and encourage the user to ask anything. Let me check if I covered all the key points: name, developer, purpose, capabilities, and a welcoming statement. Yeah, that should do it. Now, let me put that into a concise and friendly response.
 response

Hello! I am swift-robot, an artificial intelligence assistant developed by swift. My purpose is to provide information and assistance to users like you. I can answer questions, generate text, and engage in conversations on a wide range of topics. I am here to help, so feel free to ask me anything you need!

기본적으로 ms-swift는 ModelScope 커뮤니티에서 모델과 데이터셋을 다운로드해요. HuggingFace 커뮤니티를 사용하려면 추가로 --use_hf true를 지정해야 해요.

LoRA 가중치 병합:

swift export \
    --adapters output/checkpoint-xxx \
    --merge_lora true

모델을 ModelScope/HuggingFace에 푸시:

# If you are pushing the complete weights, you need to change `--adapters` to `--model`.
# The Modelscope hub_token can be found here: https://modelscope.cn/my/myaccesstoken
swift export \
    --adapters output/checkpoint-xxx \
    --push_to_hub true \
    --hub_model_id '<hub-model-id>' \
    --hub_token '<hub-token>' \
    --use_hf false

멀티 GPU로 훈련하고 싶다면 다음 멀티 GPU 훈련 데모를 제공해요:

# 4 * 60GB
# You can run the experiment by setting `--dataset AI-ModelScope/alpaca-gpt4-data-en`.
# Note: If you want to specify `--packing true`, you must additionally set `--attn_impl flash_attn`.

NPROC_PER_NODE=4 \
CUDA_VISIBLE_DEVICES=0,1,2,3 \
swift sft \
    --model Qwen/Qwen3-8B \
    --train_type full \
    --dataset '<your-dataset>' \
    --torch_dtype bfloat16 \
    --per_device_train_batch_size 1 \
    --per_device_eval_batch_size 1 \
    --learning_rate 1e-5 \
    --gradient_accumulation_steps 4 \
    --packing true \
    --eval_steps 100 \
    --save_steps 100 \
    --logging_steps 5 \
    --max_length 8192 \
    --warmup_ratio 0.05 \
    --dataloader_num_workers 8 \
    --dataset_num_proc 8 \
    --save_total_limit 2 \
    --save_only_model true \
    --output_dir output \
    --deepspeed zero3 \
    --use_liger_kernel true \
    --attn_impl flash_attn

강화학습 (RL)

ms-swift는 DPO, GRPO, DAPO, PPO, KTO 등의 RLHF 방법을 지원해요. 이 섹션에서는 ms-swift로 Qwen3-8B에 GRPO 훈련을 수행하는 예시에 초점을 맞출게요.

자세한 RLHF 지원 정보는 지원 기능을 참고하세요.

환경 설정

위에서 소개한 ms-swift 관련 의존성에 더해 다음 의존성도 설치해야 해요:

pip install "math_verify==0.5.2"
pip install vllm

데이터 준비

ms-swift를 사용한 GRPO 훈련의 데이터셋 형식은 SFT와 유사해요. 단, 마지막 턴의 assistant 부분은 필요하지 않아요. 정확도를 보상으로 사용한다면 정확도를 계산하기 위한 solution 컬럼이 필요해요.

예시 데이터셋 형식:

{"messages": [{"role": "user", "content": "Tell me tomorrow's weather"}]}
{"messages": [{"role": "user", "content": "What is 1 + 1?"}, {"role": "assistant", "content": "It equals 2"}, {"role": "user", "content": "What about adding 1?"}]}
{"messages": [{"role": "user", "content": "What is your name?"}]}

다른 RLHF 알고리즘의 데이터셋 준비는 커스텀 데이터셋 문서를 참고하세요.

데이터셋 요구 사항 참고:

  • 보상 함수 계산: 데이터셋 형식은 사용 중인 보상 함수에 따라 달라져요. 특정 보상 계산을 지원하기 위해 추가 컬럼이 필요할 수 있어요. 예를 들어:
    • 내장된 정확도 또는 코사인 유사도 보상을 사용할 때는 응답의 정확도를 계산하기 위해 데이터셋에 solution 컬럼이 있어야 해요.
    • 데이터셋의 다른 컬럼은 추가 커스터마이징을 위해 **kwargs로 보상 함수에 전달돼요.
  • 보상 함수 커스터마이징: 보상 함수를 특정 요구에 맞게 조정하려면 외부 보상 플러그인을 참고하세요. 이 플러그인은 커스텀 보상 함수 구현 예시와 템플릿을 제공해요.

훈련 과정에서 vLLM으로 샘플링 과정을 가속화해요. num_infer_workers=8을 설정해 각 디바이스에 vLLM 엔진을 배포해 샘플링을 빠르게 해요.

# 70G*8
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
NPROC_PER_NODE=8 \
swift rlhf \
    --rlhf_type grpo \
    --model Qwen/Qwen3-8B \
    --train_type full \
    --dataset 'AI-MO/NuminaMath-TIR#5000' \
    --torch_dtype bfloat16 \
    --num_train_epochs 1 \
    --per_device_train_batch_size 2 \
    --per_device_eval_batch_size 2 \
    --learning_rate 1e-6 \
    --save_total_limit 2 \
    --logging_steps 5 \
    --output_dir output \
    --gradient_accumulation_steps 1 \
    --warmup_ratio 0.05 \
    --dataloader_num_workers 4 \
    --max_completion_length 4096 \
    --vllm_max_model_len 8192 \
    --reward_funcs accuracy \
    --num_generations 16 \
    --use_vllm true \
    --vllm_gpu_memory_utilization 0.4 \
    --sleep_level 1 \
    --offload_model true \
    --offload_optimizer true \
    --gc_collect_after_offload true \
    --deepspeed zero3 \
    --num_infer_workers 8 \
    --tensor_parallel_size 1 \
    --temperature 1.0 \
    --top_p 0.85 \
    --log_completions true \
    --overlong_filter true

Megatron-SWIFT

ms-swift는 대규모 모델 훈련을 가속화하기 위해 Megatron 병렬 기법을 통합해요. 지원되는 모델은 지원 모델 문서에서 확인할 수 있어요.

환경 준비와 HF·MCore 모델 가중치 간 변환은 Megatron-SWIFT 훈련 문서를 참고하세요. 이 주제는 여기서 다루지 않을게요.

훈련 시작에는 Alibaba Cloud DLC를 사용할게요. 훈련 환경은 8 * 80GiB A800 GPU를 가진 2대의 머신으로 구성돼요. 멀티노드 시작 방법에 대한 자세한 내용은 여기를 참고하세요.

# https://help.aliyun.com/zh/pai/user-guide/general-environment-variables
# Ensure that the weight-saving paths on the two nodes are identical.
NNODES=$WORLD_SIZE \
NODE_RANK=$RANK \
megatron sft \
    --load Qwen3-30B-A3B-Base-mcore \
    --dataset 'liucong/Chinese-DeepSeek-R1-Distill-data-110k-SFT' \
    --tensor_model_parallel_size 2 \
    --expert_model_parallel_size 8 \
    --moe_grouped_gemm true \
    --moe_shared_expert_overlap true \
    --moe_aux_loss_coeff 0.01 \
    --micro_batch_size 1 \
    --global_batch_size 16 \
    --packing true \
    --recompute_granularity full \
    --recompute_method uniform \
    --recompute_num_layers 1 \
    --train_iters 2000 \
    --eval_iters 50 \
    --finetune true \
    --cross_entropy_loss_fusion true \
    --lr 1e-5 \
    --lr_warmup_iters 100 \
    --min_lr 1e-6 \
    --save megatron_output/Qwen3-30B-A3B-Base \
    --eval_interval 200 \
    --save_interval 200 \
    --max_length 8192 \
    --num_workers 8 \
    --dataset_num_proc 8 \
    --no_save_optim true \
    --no_save_rng true \
    --sequence_parallel true \
    --use_flash_attn true

커스텀 데이터셋 형식은 이전 섹션의 swift sft와 동일해요. --dataset <dataset_path>만 지정하면 돼요.

다음은 Qwen3-30B-A3B 모델의 전체 파라미터 파인튜닝에 대한 megatron sft와 swift sft의 훈련 속도 및 GPU 메모리 사용 비교예요.

항목 Megatron-LM DeepSpeed-ZeRO2 DeepSpeed-ZeRO3
훈련 속도 9.6s/it - 91.2s/it
GPU 메모리 사용량 16 * 60GiB OOM 16 * 80GiB

결론

위 내용이 ms-swift를 사용해 Qwen3 시리즈 모델을 훈련하는 모범 사례예요. 사용 중 어려움을 겪는다면 이 이슈에서 토론에 참여해 주세요.

더 알아보기 (Learn more)