歡迎來到 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 = 32hidden_size = 4096- 參數量: 8B 個參數
- 調整後配置:
num_layers = 1hidden_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.jsonlexport 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! 🚀