歡迎來到 LLM Bootcamp!本教學將帶您完整體驗使用 NVIDIA NeMo 進行大型語言模型(LLM)的完整流程,從零開始學會模型轉換、預訓練、微調到部署的實戰技巧。
通過本 Bootcamp,您將學會:
- 🔄 模型轉換技能:掌握 Hugging Face 與 NeMo 格式間的轉換
- 📚 預訓練實踐:體驗大規模語言模型的持續預訓練
- 🛠️ 微調技術:學會針對特定任務進行模型微調、掌握 LoRA 等參數高效微調方法
- 📊 模型評估:學會評估和測試模型性能
- 🚀 模型部署:了解模型導出和部署流程
在開始訓練之前,您需要設定適合的 GPU 環境。我們提供詳細的環境設定指南:
設定步驟:詳見 📖 TWCC 環境設定指南
使用官方 NeMo 容器,包含所有必要的依賴套件:
docker run \
--gpus all -it --rm --shm-size=8g --ulimit memlock=-1 --ulimit stack=67108864 \
-v $PWD:$PWD -w $PWD -p 8888:8888 \
nvcr.io/nvidia/nemo:25.04
💡 提示:您可以在 NGC NeMo Catalog 查看最新版本
git clone https://github.com/wcks13589/LLM-Tutorial.git
cd LLM-Tutorial
pip install -U click
💡 提示:請確保在
LLM-Tutorial
專案目錄中執行後續指令。
申請並設定您的 Hugging Face Token:
- 申請 Token:前往 Hugging Face Settings 建立新的 Access Token
- 設定環境變數:
# 替換為您的實際 Token export HF_TOKEN="your_hf_token" huggingface-cli login --token $HF_TOKEN
📌 重要:請先在 Hugging Face 申請 Access Token
# 下載 Llama 3.1 8B Instruct 模型
huggingface-cli download meta-llama/Llama-3.1-8B-Instruct \
--local-dir Llama-3.1-8B-Instruct \
--exclude original/
# 設定變數
MODEL=llama3_8b
HF_MODEL_ID=Llama-3.1-8B-Instruct
OUTPUT_PATH=nemo_ckpt/Llama-3.1-8B-Instruct
OVERWRITE_EXISTING=false
# 執行轉換
nemo llm import -y \
model=${MODEL} \
source=hf://${HF_MODEL_ID} \
output_path=${OUTPUT_PATH} \
overwrite=${OVERWRITE_EXISTING}
✅ 檢查點:確認
nemo_ckpt/
目錄下成功生成了 NeMo 格式的模型檔案
下載中文資料集:
python data_preparation/download_pretrain_data.py \
--dataset_name erhwenkuo/wikinews-zhtw \
--output_dir data/custom_dataset/json/wikinews-zhtw.jsonl
# 建立預處理目錄
mkdir -p data/custom_dataset/preprocessed
# 使用 NeMo 的資料預處理工具
python /opt/NeMo/scripts/nlp_language_modeling/preprocess_data_for_megatron.py \
--input=data/custom_dataset/json/wikinews-zhtw.jsonl \
--json-keys=text \
--dataset-impl mmap \
--tokenizer-library=huggingface \
--tokenizer-type meta-llama/Llama-3.1-8B-Instruct \
--output-prefix=data/custom_dataset/preprocessed/wikinews \
--append-eod
設定基本參數:
JOB_NAME=llama31_pretraining
NUM_NODES=1
NUM_GPUS=1
HF_MODEL_ID=meta-llama/Llama-3.1-8B-Instruct
# 並行處理參數
TP=1 # Tensor Parallel
PP=1 # Pipeline Parallel
CP=1 # Context Parallel
# 訓練參數
GBS=4 # Global Batch Size
MAX_STEPS=20 # 最大訓練步數(模型權重更新次數)
DATASET_PATH=data/custom_dataset/preprocessed/
適用情況:當您想要從零開始訓練模型時使用。
特點:腳本會自動從基礎模型架構進行權重初始化
執行指令:
python pretraining/pretrain.py \
--executor local \
--experiment ${JOB_NAME} \
--num_nodes ${NUM_NODES} \
--num_gpus ${NUM_GPUS} \
--model_size 8B \
--hf_model_id ${HF_MODEL_ID} \
--hf_token ${HF_TOKEN} \
--max_steps ${MAX_STEPS} \
--global_batch_size ${GBS} \
--tensor_model_parallel_size ${TP} \
--pipeline_model_parallel_size ${PP} \
--context_parallel_size ${CP} \
--dataset_path ${DATASET_PATH}
重要提醒:本教學內容特別針對 V100 32GB GPU 進行配置優化
由於本教學內容預計使用 V100 32GB 的 GPU 來實作,為確保可以順利執行模型的訓練,我們在
pretrain.py
中特地將模型的層數與維度大幅降低:模型配置對比:
- 原始 Llama3.1 8B 模型:
num_layers = 32
hidden_size = 4096
- 參數量: 8B 個參數
- 調整後配置:
num_layers = 1
hidden_size = 128
- 參數量:大幅降低,適合單張 V100 GPU
調整原因:
- 確保在 V100 32GB 記憶體限制下能順利執行
- 降低訓練時間,提供更好的學習體驗
- 保持完整的訓練流程,讓學習者理解整個預訓練過程
程式碼位置:這些配置調整位於
pretrain.py
中的configure_recipe
函數內。具體修改的程式碼:
recipe.model.config.num_layers = 1 recipe.model.config.hidden_size = 128
📊 監控訓練:訓練過程中可以觀察 loss 變化來判斷模型學習狀況
⚠️ 注意:此方法在本 Bootcamp 實作中不會執行,由於資源限制,我們專注於方法一的實踐學習。此部分僅供參考和學習使用。
適用情況:當您想要從現有的 NeMo 格式模型開始,進行持續預訓練時使用。
前置條件:
- 需要先將 Hugging Face 模型轉換為 NeMo 格式
- 確保
${NEMO_MODEL}
路徑下存在有效的 NeMo 模型檔案
執行指令:
NEMO_MODEL=nemo_ckpt/Llama-3.1-8B-Instruct
python pretraining/pretrain.py \
--executor local \
--experiment ${JOB_NAME} \
--num_nodes ${NUM_NODES} \
--num_gpus ${NUM_GPUS} \
--model_size 8B \
--hf_model_id ${HF_MODEL_ID} \
--nemo_model ${NEMO_MODEL} \
--hf_token ${HF_TOKEN} \
--max_steps ${MAX_STEPS} \
--global_batch_size ${GBS} \
--tensor_model_parallel_size ${TP} \
--pipeline_model_parallel_size ${PP} \
--context_parallel_size ${CP} \
--dataset_path ${DATASET_PATH}
# 下載並準備 Alpaca 資料集
python data_preparation/download_sft_data.py
# 微調參數設定
JOB_NAME=llama31_finetuning
NUM_NODES=1
NUM_GPUS=1
HF_MODEL_ID=meta-llama/Llama-3.1-8B-Instruct
NEMO_MODEL=nemo_ckpt/Llama-3.1-8B-Instruct
# LATEST_CHECKPOINT=$(find nemo_experiments/llama31_pretraining/checkpoints/ -type d -name "*-last" | sort -r | head -n 1)
HF_TOKEN=$HF_TOKEN
# 並行處理參數
TP=1
PP=1
CP=1
# 微調參數
MAX_STEPS=10
GBS=4
DATASET_PATH=data/alpaca
# 執行 LoRA 微調
python finetuning/finetune.py \
--executor local \
--experiment ${JOB_NAME} \
--num_nodes ${NUM_NODES} \
--num_gpus ${NUM_GPUS} \
--model_size 8B \
--hf_model_id ${HF_MODEL_ID} \
--hf_token ${HF_TOKEN} \
--nemo_model ${NEMO_MODEL} \
--max_steps ${MAX_STEPS} \
--global_batch_size ${GBS} \
--tensor_model_parallel_size ${TP} \
--pipeline_model_parallel_size ${PP} \
--context_parallel_size ${CP} \
--dataset_path ${DATASET_PATH} \
--peft lora
🎯 全參數微調:若要進行全參數的微調,請移除
--peft lora
# 建立 Reasoning 資料集目錄
mkdir -p data/reasoning_dataset/
# 下載 NVIDIA Llama-Nemotron 後訓練資料集
wget https://huggingface.co/datasets/nvidia/Llama-Nemotron-Post-Training-Dataset/resolve/main/SFT/chat/chat.jsonl -P data/reasoning_dataset/
# 從資料集中選取樣本進行快速訓練
head -n 200 data/reasoning_dataset/chat.jsonl > data/reasoning_dataset/chat_subset.jsonl
export UCX_MEMTYPE_CACHE=n
export UCX_TLS=tcp
# 執行資料策展與預處理
python data_preparation/curate_reasoning_data.py \
--input-dir "data/reasoning_dataset" \
--filename-filter "chat_subset" \
--remove-columns "category" "generator" "license" "reasoning" "system_prompt" "used_in_training" "version" \
--json-files-per-partition 16 \
--tokenizer "meta-llama/Llama-3.1-8B-Instruct" \
--max-token-count 16384 \
--max-completion-token-count 8192 \
--output-dir data/reasoning_dataset/curated-data \
--device "gpu" \
--n-workers 1
💡 執行提示:此程式執行過程中可能會出現一些錯誤訊息,但只要輸出資料夾
data/reasoning_dataset/curated-data
內有檔案產生就算執行成功,可以忽略錯誤訊息繼續後續步驟。
# Reasoning 微調參數設定
JOB_NAME=llama31_reasoning_finetuning
NUM_NODES=1
NUM_GPUS=1
HF_MODEL_ID=meta-llama/Llama-3.1-8B-Instruct
NEMO_MODEL=nemo_ckpt/Llama-3.1-8B-Instruct
HF_TOKEN=$HF_TOKEN
# 並行處理參數
TP=1
PP=1
CP=1
# 微調參數
MAX_STEPS=10
GBS=4
DATASET_PATH=data/reasoning_dataset/curated-data
# 執行 Reasoning LoRA 微調
python finetuning/finetune.py \
--executor local \
--experiment ${JOB_NAME} \
--num_nodes ${NUM_NODES} \
--num_gpus ${NUM_GPUS} \
--model_size 8B \
--hf_model_id ${HF_MODEL_ID} \
--hf_token ${HF_TOKEN} \
--nemo_model ${NEMO_MODEL} \
--max_steps ${MAX_STEPS} \
--global_batch_size ${GBS} \
--tensor_model_parallel_size ${TP} \
--pipeline_model_parallel_size ${PP} \
--context_parallel_size ${CP} \
--dataset_path ${DATASET_PATH} \
--peft lora \
--seq_length 1024
🧠 Reasoning 微調特色:使用高品質的推理資料集,提升模型的邏輯推理和複雜問題解決能力
# 從測試集中選取樣本進行快速評估
head -n 30 data/alpaca/test.jsonl > data/alpaca/test_subset.jsonl
# 使用微調後的模型進行推理
# 找到最新的檢查點資料夾
LATEST_CHECKPOINT=$(find nemo_experiments/llama31_finetuning/checkpoints/ -type d -name "*-last" | sort -r | head -n 1)
python evaluation/inference.py \
--peft_ckpt_path ${LATEST_CHECKPOINT} \
--input_dataset data/alpaca/test_subset.jsonl \
--output_path data/alpaca/peft_prediction.jsonl
# 計算模型性能指標
python /opt/NeMo/scripts/metric_calculation/peft_metric_calc.py \
--pred_file data/alpaca/peft_prediction.jsonl \
--label_field "label" \
--pred_field "prediction"
⚠️ 重要提醒:如果您進行的是 LoRA 微調,請先執行步驟 6.1 合併 LoRA 權重,再進行步驟 6.2 的格式轉換。
如果您使用了 LoRA 進行微調(在微調指令中包含 --peft lora
),您需要先將 LoRA 權重合併回基底模型,然後再進行格式轉換:
# 找到最新的 LoRA checkpoint
LATEST_LORA_CHECKPOINT=$(find nemo_experiments/llama31_reasoning_finetuning/checkpoints/ -type d -name "*-last" | sort -r | head -n 1)
NEMO_MODEL=nemo_experiments/llama31_reasoning_finetuning/checkpoints/nemo_ckpt_merged
# 合併 LoRA 權重到基底模型
python finetuning/merge_lora.py \
--nemo_lora_model ${LATEST_LORA_CHECKPOINT} \
--output_path ${NEMO_MODEL}
💡 說明:
- 此步驟會將 LoRA 適配器的權重合併到原始的基底模型中
- 合併後的模型包含完整的權重,可以獨立使用
- 如果您進行的是全參數微調,請跳過此步驟
# 設定轉換參數
# 如果您完成了 LoRA 合併,請使用合併後的模型路徑:
NEMO_MODEL=nemo_experiments/llama31_reasoning_finetuning/checkpoints/nemo_ckpt_merged
#
# 如果您進行的是全參數微調,請使用:
# NEMO_MODEL=$(find nemo_experiments/llama31_reasoning_finetuning/checkpoints/ -type d -name "*-last" | sort -r | head -n 1)
OUTPUT_PATH=hf_ckpt/
# 執行轉換
nemo llm export -y \
path=${NEMO_MODEL} \
output_path=${OUTPUT_PATH} \
target=hf
使用 EleutherAI 的 lm-evaluation-harness 工具進行標準化模型評估:
# 下載並安裝 lm-evaluation-harness
git clone --depth 1 https://github.com/EleutherAI/lm-evaluation-harness
cd lm-evaluation-harness
pip install -e .
使用 LAMBADA OpenAI 任務評估模型的語言建模能力:
# 切換回主目錄
cd ..
# 執行 LAMBADA OpenAI 評估 (僅使用較少樣本進行快速評估)
lm_eval --model hf \
--model_args pretrained=hf_ckpt/ \
--tasks lambada_openai \
--device cuda:0 \
--batch_size 8 \
--limit 100
執行結果範例:
| Tasks |Version|Filter|n-shot| Metric | |Value | |Stderr|
|--------------|------:|------|-----:|----------|---|-----:|---|-----:|
|lambada_openai| 1|none | 0|acc |↑ |0.7100|± |0.0456|
| | |none | 0|perplexity|↓ |3.4032|± |0.5080|
結果指標說明:
- acc (準確率):模型正確預測句子最後一個詞的比例,本例為 71%
- perplexity (困惑度):衡量模型對文本的不確定性,數值越低越好
💡 結果分析:準確率 > 70% 通常表示模型具有良好的語言理解能力
您也可以嘗試其他常見的評估任務:
lm_eval --model hf \
--model_args pretrained=hf_ckpt/ \
--tasks arc_challenge \
--device cuda:0 \
--batch_size 8
📊 評估任務說明:
- LAMBADA OpenAI:測試語言建模和上下文理解能力,評估模型預測句子最後一個詞的準確性
- ARC (AI2 Reasoning Challenge):測試科學推理能力
🔧 調優提示:
- 可根據 GPU 記憶體調整
batch_size
參數- 使用
--limit
參數進行快速測試- 詳細的評估結果會顯示準確率和其他相關指標
- 多模態模型訓練
- 分散式訓練優化
- 模型壓縮與量化
- 自定義資料載入器
通過本教學,您已經掌握了:
- ✅ 大型語言模型的完整訓練流程
- ✅ NeMo 框架的核心功能
- ✅ 實際的 AI 模型開發技能
- ✅ 企業級 AI 應用開發基礎
下一步建議:
- 嘗試使用自己的資料集
- 探索不同的模型架構
- 學習模型部署與服務化
- 參與開源專案貢獻
💬 需要幫助? 歡迎在 Issues 中提出問題或建議!
Happy Learning! 🚀