环境说明 本文记录在一台单机 4 卡 RTX 4090 服务器上,通过 Docker 部署 NVIDIA Megatron-LM,并完成从环境安装、NCCL 通信验证到 GPT 小模型训练测试的完整流程。
本机环境如下:
1 2 3 4 5 6 操作系统:Ubuntu 24 Desktop GPU:4 × NVIDIA GeForce RTX 4090 NVIDIA Driver:595.71.05 容器运行环境:Docker + NVIDIA Container Toolkit Megatron 路线:NVIDIA/Megatron-LM 主线版本 基础镜像:nvcr.io/nvidia/pytorch:26.01-py3
Megatron-LM 主要用于大模型训练和并行训练实验,和 vLLM 的定位不同:vLLM 更偏推理部署,Megatron-LM 更偏训练、预训练、继续预训练、模型并行和分布式训练验证。
停止已有 vLLM 容器 如果机器上正在运行的占用存的服务,需要先停止,释放GPU。
如果看到正在运行的 vLLM 容器,例如 qwen36-vllm,执行:
确认 GPU 空闲:
创建 Megatron-LM 工作目录 在宿主机上创建统一目录:
1 mkdir -p ~/megatron/{code,data,checkpoints,logs,scripts}
目录含义如下:
1 2 3 4 5 6 ~/megatron/code # Megatron-LM 源码 ~/megatron/data # 训练数据 ~/megatron/checkpoints # 训练产生的 checkpoint ~/megatron/logs # 训练日志 ~/megatron/scripts # 启动脚本与环境脚本 ~/model # 已有模型目录,可只读挂载进容器
拉取 NGC PyTorch 镜像 Megatron-LM 推荐使用 NVIDIA NGC PyTorch 容器,因为其中已经预装 PyTorch、CUDA、cuDNN、NCCL、Transformer Engine 等训练相关依赖。
1 docker pull nvcr.io/nvidia/pytorch:26.01-py3
如果拉取失败,可以登录 NGC:
用户名通常填写:
密码填写自己的 NGC API Key。
下载 Megatron-LM 源码 考虑到部分服务器容器内网络不稳定,推荐在宿主机下载源码,再挂载进容器。
1 2 cd ~/megatron/codegit clone https://github.com/NVIDIA/Megatron-LM.git
如果 GitHub 访问较慢,可以使用镜像代理:
1 2 cd ~/megatron/codegit clone https://gh-proxy.com/https://github.com/NVIDIA/Megatron-LM.git
检查源码目录:
1 ls -lh ~/megatron/code/Megatron-LM
应能看到类似内容:
1 2 3 4 5 6 7 megatron examples tools tests docs pretrain_gpt.py pyproject.toml
启动 Megatron-LM 开发容器 执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 docker run -it \ --name megatron-dev \ --gpus all \ --ipc=host \ --network host \ --shm-size=64g \ --ulimit memlock=-1 \ --ulimit stack=67108864 \ -v "$HOME /megatron/code:/workspace/code" \ -v "$HOME /megatron/data:/workspace/data" \ -v "$HOME /megatron/checkpoints:/workspace/checkpoints" \ -v "$HOME /megatron/logs:/workspace/logs" \ -v "$HOME /megatron/scripts:/workspace/scripts" \ -v "$HOME /model:/workspace/model:ro" \ -e PIP_CONSTRAINT= \ -e PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \ -e PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn \ nvcr.io/nvidia/pytorch:26.01-py3 \ bash
关键参数说明:
1 2 3 4 5 6 7 --gpus all # 允许容器使用全部 GPU --ipc=host # 避免多进程训练时共享内存不足 --network host # 使用宿主机网络 --shm-size=64g # 增大共享内存 --ulimit memlock=-1 # 解除内存锁限制 -v ~/megatron/... # 挂载源码、数据、checkpoint、日志 -v ~/model:/workspace/model:ro # 只读挂载已有模型目录
容器内检查 PyTorch 和 GPU 进入容器后执行:
1 2 3 4 5 6 7 8 9 10 python - <<'PY' import torch print ("Torch:" , torch.__version__)print ("CUDA available:" , torch.cuda.is_available())print ("GPU count:" , torch.cuda.device_count())for i in range(torch.cuda.device_count()): print (i, torch.cuda.get_device_name(i)) PY
正常应看到 4 张 RTX 4090。
创建 Python 虚拟环境 由于新版 Python 对系统环境有 externally managed 保护,不建议直接向系统 Python 安装 Megatron-LM。因此在容器内创建虚拟环境,并继承 NGC 容器已有的 PyTorch/CUDA 依赖。
1 2 3 4 5 cd /workspace/code/Megatron-LMpython3 -m venv /workspace/megatron-venv --system-site-packages source /workspace/megatron-venv/bin/activate
确认 Python 路径:
应显示:
1 2 /workspace/megatron-venv/bin/python /workspace/megatron-venv/bin/pip
安装基础工具和 uv 1 python -m pip install -U pip setuptools wheel uv
为了避免和 NGC 容器自带包冲突,固定部分依赖版本:
1 2 3 4 5 cat > /workspace/megatron-constraints.txt <<'EOF' packaging==25.0 numpy==2.3.5 click==8.4.1 EOF
设置 GitHub 代理和 PyPI 镜像源 如果服务器访问 GitHub 或 PyPI 较慢,可以配置:
1 git config --global url."https://gh-proxy.com/https://github.com/" .insteadOf "https://github.com/"
设置 uv 镜像源:
1 2 export UV_DEFAULT_INDEX=https://pypi.tuna.tsinghua.edu.cn/simpleexport UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
安装 Megatron-LM 进入源码目录:
1 2 cd /workspace/code/Megatron-LMsource /workspace/megatron-venv/bin/activate
安装 build 依赖:
1 2 3 4 uv pip install \ --default-index https://pypi.tuna.tsinghua.edu.cn/simple \ -c /workspace/megatron-constraints.txt \ --group build
安装 Megatron-LM 训练和开发依赖:
1 2 3 4 5 MAX_JOBS=4 uv pip install \ --default-index https://pypi.tuna.tsinghua.edu.cn/simple \ -c /workspace/megatron-constraints.txt \ --no-build-isolation \ -e ".[training,dev]"
安装完成后,应能看到类似:
1 2 3 Built megatron-core Installed xxx packages megatron-core==0.19.0
如果看到如下 warning,可以暂时忽略:
1 warning: The package `nvidia-modelopt==0.44.0` does not have an extra named `torch`
创建 Megatron 环境脚本 为了后续不用重复设置环境变量,创建统一环境脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 cat > /workspace/scripts/megatron_env.sh <<'EOF' source /workspace/megatron-venv/bin/activateexport PYTHONPATH=/workspace/code/Megatron-LM:$PYTHONPATH export UV_DEFAULT_INDEX=https://pypi.tuna.tsinghua.edu.cn/simpleexport UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simpleexport NCCL_DEBUG=WARNexport NCCL_IB_DISABLE=1export NCCL_P2P_DISABLE=1export NCCL_NET=Socketexport NCCL_SOCKET_IFNAME=loexport CUDA_DEVICE_MAX_CONNECTIONS=1cd /workspace/code/Megatron-LMEOF chmod +x /workspace/scripts/megatron_env.sh
以后进入容器后,只需要执行:
1 source /workspace/scripts/megatron_env.sh
执行:
1 source /workspace/scripts/megatron_env.sh
检查 Megatron-LM:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 python - <<'PY' import torch import megatron import megatron.core print ("Megatron import OK" )print ("Megatron Core import OK" )print ("Torch:" , torch.__version__)print ("CUDA available:" , torch.cuda.is_available())print ("GPU count:" , torch.cuda.device_count())for i in range(torch.cuda.device_count()): print (i, torch.cuda.get_device_name(i)) PY
检查 Transformer Engine:
1 2 3 4 5 6 7 8 python - <<'PY' try: import transformer_engine print ("Transformer Engine import OK" ) except Exception as e: print ("Transformer Engine import FAILED:" ) print (e) PY
如果都能正常 import,说明 Python 环境基本正常。
编写 NCCL 多卡通信测试脚本 创建脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 cat > /workspace/scripts/nccl_test.py <<'PY' import os import datetime import torch import torch.distributed as dist local_rank = int(os.environ["LOCAL_RANK" ]) rank = int(os.environ["RANK" ]) world_size = int(os.environ["WORLD_SIZE" ]) torch.cuda.set_device(local_rank) print ( f"[before init] rank={rank}, local_rank={local_rank}, " f"world_size={world_size}, device={torch.cuda.get_device_name(local_rank)}" , flush=True, ) dist.init_process_group( backend="nccl" , timeout =datetime.timedelta(seconds=60), ) print (f"[after init] rank={rank}, local_rank={local_rank}" , flush=True)x = torch.ones(1, device="cuda" ) * (rank + 1) dist.all_reduce(x) torch.cuda.synchronize() print (f"[after all_reduce] rank={rank}, result={x.item()}" , flush=True)dist.destroy_process_group() PY
先测试 2 卡:
1 2 3 4 5 6 7 source /workspace/scripts/megatron_env.shCUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=2 \ /workspace/scripts/nccl_test.py
2 卡成功时,结果应为:
再测试 4 卡:
1 2 3 4 5 CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=4 \ /workspace/scripts/nccl_test.py
4 卡成功时,结果应为:
说明 4 卡 NCCL 通信正常。
运行 Megatron Core 最小训练测试 注意:这里不要直接使用系统里的 torchrun,而是使用:
1 python -m torch.distributed.run
这样可以确保使用虚拟环境中的 Python。
执行 2 卡测试:
1 2 3 4 5 6 7 source /workspace/scripts/megatron_env.shCUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=2 \ examples/run_simple_mcore_train_loop.py
如果看到:
1 Successfully loaded the model
说明 Megatron Core 最小训练闭环成功。
可以继续测试 4 卡:
1 2 3 4 5 CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=4 \ examples/run_simple_mcore_train_loop.py
准备 GPT 小模型训练数据 创建数据目录:
1 2 3 4 mkdir -p /workspace/data/gpt2_rawmkdir -p /workspace/data/gpt2_mmapmkdir -p /workspace/checkpoints/gpt2_tinymkdir -p /workspace/logs/gpt2_tiny
创建一个小 JSONL 数据集:
1 2 3 4 5 6 7 8 9 cat > /workspace/data/gpt2_raw/tiny_gpt.jsonl <<'EOF' {"text" : "Megatron-LM is a framework for training large transformer language models." } {"text" : "Tensor parallelism splits matrix operations across multiple GPUs." } {"text" : "Pipeline parallelism splits model layers across different GPU stages." } {"text" : "Data parallelism replicates the model and splits input batches." } {"text" : "This is a small dataset for testing GPT pretraining with Megatron-LM." } {"text" : "NCCL is used for communication between GPUs during distributed training." } {"text" : "This test verifies data preprocessing, model training, and checkpoint saving." } EOF
复制多份,生成测试数据:
1 2 3 4 5 rm -f /workspace/data/gpt2_raw/tiny_gpt_repeat.jsonlfor i in $(seq 1 2000); do cat /workspace/data/gpt2_raw/tiny_gpt.jsonl >> /workspace/data/gpt2_raw/tiny_gpt_repeat.jsonl done
检查:
1 wc -l /workspace/data/gpt2_raw/tiny_gpt_repeat.jsonl
下载 GPT-2 tokenizer 文件 需要两个文件:
可以使用 Hugging Face 镜像下载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 export HF_ENDPOINT=https://hf-mirror.compython - <<'PY' from huggingface_hub import hf_hub_download target_dir = "/workspace/data/gpt2_raw" for filename in ["vocab.json" , "merges.txt" ]: path = hf_hub_download( repo_id="openai-community/gpt2" , filename=filename, local_dir=target_dir, ) print (path) PY
检查:
1 ls -lh /workspace/data/gpt2_raw
应看到:
1 2 3 4 vocab.json merges.txt tiny_gpt.jsonl tiny_gpt_repeat.jsonl
预处理数据 当前版本的 tools/preprocess_data.py 不需要 --dataset-impl mmap 参数。直接执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 source /workspace/scripts/megatron_env.shrm -f /workspace/data/gpt2_mmap/tiny_gpt*python tools/preprocess_data.py \ --input /workspace/data/gpt2_raw/tiny_gpt_repeat.jsonl \ --output-prefix /workspace/data/gpt2_mmap/tiny_gpt \ --tokenizer-type GPT2BPETokenizer \ --vocab-file /workspace/data/gpt2_raw/vocab.json \ --merge-file /workspace/data/gpt2_raw/merges.txt \ --json-keys text \ --append-eod \ --workers 4
检查输出:
1 ls -lh /workspace/data/gpt2_mmap
应看到:
1 2 tiny_gpt_text_document.bin tiny_gpt_text_document.idx
2 卡 TP=2 GPT tiny 训练 创建训练脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 cat > /workspace/scripts/train_gpt_tiny_tp2.sh <<'EOF' source /workspace/scripts/megatron_env.shexport CUDA_VISIBLE_DEVICES=0,1export CUDA_DEVICE_MAX_CONNECTIONS=1DATA_PATH=/workspace/data/gpt2_mmap/tiny_gpt_text_document CHECKPOINT_PATH=/workspace/checkpoints/gpt2_tiny_tp2 TOKENIZER_DIR=/workspace/data/gpt2_raw LOG_PATH=/workspace/logs/gpt2_tiny/train_tp2.log mkdir -p $CHECKPOINT_PATH mkdir -p /workspace/logs/gpt2_tinypython -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=2 \ pretrain_gpt.py \ --use-mcore-models \ --transformer-impl transformer_engine \ --tensor-model-parallel-size 2 \ --pipeline-model-parallel-size 1 \ --num-layers 4 \ --hidden-size 256 \ --ffn-hidden-size 1024 \ --num-attention-heads 4 \ --seq-length 128 \ --max-position-embeddings 128 \ --micro-batch-size 2 \ --global-batch-size 8 \ --train-iters 50 \ --lr-decay-iters 50 \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATA_PATH \ --vocab-file $TOKENIZER_DIR /vocab.json \ --merge-file $TOKENIZER_DIR /merges.txt \ --tokenizer-type GPT2BPETokenizer \ --split 949,50,1 \ --distributed-backend nccl \ --lr 1.0e-4 \ --min-lr 1.0e-5 \ --lr-decay-style cosine \ --weight-decay 1e-2 \ --clip-grad 1.0 \ --lr-warmup-fraction 0.01 \ --log-interval 1 \ --save-interval 25 \ --eval-interval 25 \ --eval-iters 5 \ --bf16 2>&1 | tee $LOG_PATH EOF chmod +x /workspace/scripts/train_gpt_tiny_tp2.sh
运行:
1 bash /workspace/scripts/train_gpt_tiny_tp2.sh
成功标志:
1 2 3 4 5 6 using world size: 2 tensor-model-parallel size: 2 data-parallel size: 1 iteration ... lm loss ... saving checkpoint ...
4 卡 TP=4 GPT tiny 训练 创建脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 cat > /workspace/scripts/train_gpt_tiny_tp4.sh <<'EOF' source /workspace/scripts/megatron_env.shexport CUDA_VISIBLE_DEVICES=0,1,2,3export CUDA_DEVICE_MAX_CONNECTIONS=1DATA_PATH=/workspace/data/gpt2_mmap/tiny_gpt_text_document CHECKPOINT_PATH=/workspace/checkpoints/gpt2_tiny_tp4 TOKENIZER_DIR=/workspace/data/gpt2_raw LOG_PATH=/workspace/logs/gpt2_tiny/train_tp4.log mkdir -p $CHECKPOINT_PATH mkdir -p /workspace/logs/gpt2_tinypython -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=4 \ pretrain_gpt.py \ --use-mcore-models \ --transformer-impl transformer_engine \ --tensor-model-parallel-size 4 \ --pipeline-model-parallel-size 1 \ --num-layers 4 \ --hidden-size 256 \ --ffn-hidden-size 1024 \ --num-attention-heads 4 \ --seq-length 128 \ --max-position-embeddings 128 \ --micro-batch-size 2 \ --global-batch-size 8 \ --train-iters 50 \ --lr-decay-iters 50 \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATA_PATH \ --vocab-file $TOKENIZER_DIR /vocab.json \ --merge-file $TOKENIZER_DIR /merges.txt \ --tokenizer-type GPT2BPETokenizer \ --split 949,50,1 \ --distributed-backend nccl \ --lr 1.0e-4 \ --min-lr 1.0e-5 \ --lr-decay-style cosine \ --weight-decay 1e-2 \ --clip-grad 1.0 \ --lr-warmup-fraction 0.01 \ --log-interval 1 \ --save-interval 25 \ --eval-interval 25 \ --eval-iters 5 \ --bf16 2>&1 | tee $LOG_PATH EOF chmod +x /workspace/scripts/train_gpt_tiny_tp4.sh
运行:
1 bash /workspace/scripts/train_gpt_tiny_tp4.sh
成功标志:
1 2 3 4 5 6 using world size: 4 tensor-model-parallel size: 4 data-parallel size: 1 iteration ... lm loss ... saving checkpoint ...
4 卡 TP=2 + DP=2 GPT tiny 训练 创建脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 cat > /workspace/scripts/train_gpt_tiny_tp2_dp2.sh <<'EOF' source /workspace/scripts/megatron_env.shexport CUDA_VISIBLE_DEVICES=0,1,2,3export CUDA_DEVICE_MAX_CONNECTIONS=1DATA_PATH=/workspace/data/gpt2_mmap/tiny_gpt_text_document CHECKPOINT_PATH=/workspace/checkpoints/gpt2_tiny_tp2_dp2 TOKENIZER_DIR=/workspace/data/gpt2_raw LOG_PATH=/workspace/logs/gpt2_tiny/train_tp2_dp2.log mkdir -p $CHECKPOINT_PATH mkdir -p /workspace/logs/gpt2_tinypython -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=4 \ pretrain_gpt.py \ --use-mcore-models \ --transformer-impl transformer_engine \ --tensor-model-parallel-size 2 \ --pipeline-model-parallel-size 1 \ --num-layers 4 \ --hidden-size 256 \ --ffn-hidden-size 1024 \ --num-attention-heads 4 \ --seq-length 128 \ --max-position-embeddings 128 \ --micro-batch-size 2 \ --global-batch-size 16 \ --train-iters 50 \ --lr-decay-iters 50 \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATA_PATH \ --vocab-file $TOKENIZER_DIR /vocab.json \ --merge-file $TOKENIZER_DIR /merges.txt \ --tokenizer-type GPT2BPETokenizer \ --split 949,50,1 \ --distributed-backend nccl \ --lr 1.0e-4 \ --min-lr 1.0e-5 \ --lr-decay-style cosine \ --weight-decay 1e-2 \ --clip-grad 1.0 \ --lr-warmup-fraction 0.01 \ --log-interval 1 \ --save-interval 25 \ --eval-interval 25 \ --eval-iters 5 \ --bf16 2>&1 | tee $LOG_PATH EOF chmod +x /workspace/scripts/train_gpt_tiny_tp2_dp2.sh
运行:
1 bash /workspace/scripts/train_gpt_tiny_tp2_dp2.sh
成功标志:
1 2 3 4 5 6 using world size: 4 tensor-model-parallel size: 2 data-parallel size: 2 iteration ... lm loss ... saving checkpoint ...
查看训练结果 查看 checkpoint:
1 2 3 4 5 6 7 8 echo "=== TP2 ===" find /workspace/checkpoints/gpt2_tiny_tp2 -maxdepth 5 -type f | head -10 echo "=== TP4 ===" find /workspace/checkpoints/gpt2_tiny_tp4 -maxdepth 5 -type f | head -10 echo "=== TP2_DP2 ===" find /workspace/checkpoints/gpt2_tiny_tp2_dp2 -maxdepth 5 -type f | head -10
查看日志:
1 2 grep -E "world size|data-parallel size|tensor-model-parallel size|iteration|lm loss" \ /workspace/logs/gpt2_tiny/train_tp4.log | head -40
1 2 grep -E "world size|data-parallel size|tensor-model-parallel size|iteration|lm loss" \ /workspace/logs/gpt2_tiny/train_tp2_dp2.log | head -40
至此,单机 4×RTX 4090 上的 Megatron-LM 基础训练环境已经完整验证通过。
重启电脑后如何再次进入运行环境 如果电脑重启,容器不会自动进入,需要按以下步骤恢复。
检查 Docker 服务 宿主机执行:
1 sudo systemctl status docker
如果 Docker 没启动:
1 sudo systemctl start docker
如果希望开机自启:
1 sudo systemctl enable docker
检查 GPU 状态 宿主机执行:
确认 4 张 RTX 4090 正常显示。
启动已有 Megatron 容器 查看容器:
如果能看到 megatron-dev,启动并进入:
1 docker start -ai megatron-dev
或者后台启动后进入:
1 2 docker start megatron-dev docker exec -it megatron-dev bash
进入 Megatron 环境 进入容器后执行:
1 source /workspace/scripts/megatron_env.sh
确认环境:
1 2 which pythonpython -c "import megatron; import megatron.core; print('Megatron OK')"
正常情况下,which python 应显示:
1 /workspace/megatron-venv/bin/python
重新运行测试或训练 重新运行 4 卡 NCCL 测试:
1 2 3 4 5 CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.run \ --standalone \ --nnodes=1 \ --nproc_per_node=4 \ /workspace/scripts/nccl_test.py
重新运行训练:
1 2 3 bash /workspace/scripts/train_gpt_tiny_tp2.sh bash /workspace/scripts/train_gpt_tiny_tp4.sh bash /workspace/scripts/train_gpt_tiny_tp2_dp2.sh
如果容器不存在,需要重新创建 如果重启后发现容器被删除了,但宿主机的 ~/megatron 目录还在,可以重新创建容器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 docker run -it \ --name megatron-dev \ --gpus all \ --ipc=host \ --network host \ --shm-size=64g \ --ulimit memlock=-1 \ --ulimit stack=67108864 \ -v "$HOME /megatron/code:/workspace/code" \ -v "$HOME /megatron/data:/workspace/data" \ -v "$HOME /megatron/checkpoints:/workspace/checkpoints" \ -v "$HOME /megatron/logs:/workspace/logs" \ -v "$HOME /megatron/scripts:/workspace/scripts" \ -v "$HOME /model:/workspace/model:ro" \ -e PIP_CONSTRAINT= \ -e PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \ -e PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn \ nvcr.io/nvidia/pytorch:26.01-py3 \ bash
进入后重新加载环境:
1 source /workspace/scripts/megatron_env.sh
如果 /workspace/megatron-venv 不存在,说明 venv 在旧容器内部丢失,需要重新创建 venv 并安装依赖。如果容器只是停止而没有删除,则不需要重新安装。
补充:方案二,将已有容器内 venv 复制到宿主机并重新挂载 上面的流程中,/workspace/megatron-venv 默认位于容器内部。如果容器只是 docker stop,虚拟环境不会丢;但如果执行 docker rm 删除容器,容器内部的 venv 会随之消失。
为了避免以后重建容器时重新安装 Megatron 依赖,可以把已经安装好的 venv 从旧容器复制到宿主机,然后在新容器中重新挂载到同一个路径 /workspace/megatron-venv。
从旧容器复制 venv 到宿主机 先确保旧容器 megatron-dev 仍然存在。即使它已经停止,只要没有被删除,也可以复制文件。
宿主机执行:
1 2 3 mkdir -p ~/megatrondocker cp megatron-dev:/workspace/megatron-venv ~/megatron/venv
执行后,宿主机上通常会出现:
1 ~/megatron/venv/megatron-venv
也就是说,docker cp 会把容器中的目录作为一个子目录复制出来。
为了后续挂载路径更简洁,建议整理为:
1 2 3 4 5 6 if [ -d "$HOME /megatron/venv/megatron-venv" ]; then rm -rf "$HOME /megatron/venv_fixed" mv "$HOME /megatron/venv/megatron-venv" "$HOME /megatron/venv_fixed" rm -rf "$HOME /megatron/venv" mv "$HOME /megatron/venv_fixed" "$HOME /megatron/venv" fi
整理后,宿主机目录结构应为:
1 2 3 ~/megatron/venv/bin/activate ~/megatron/venv/bin/python ~/megatron/venv/lib/...
可以检查:
1 2 ls -lh ~/megatron/venv/bin/activatels -lh ~/megatron/venv/bin/python
删除旧容器 确认 venv 已经复制到宿主机后,可以删除旧容器:
1 docker rm -f megatron-dev
这不会删除宿主机上的源码、数据、checkpoint、日志和刚刚复制出来的 venv。
用 venv 挂载方式重建容器 新建容器时增加一行挂载:
1 -v "$HOME /megatron/venv:/workspace/megatron-venv" \
完整命令如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 docker run -it \ --name megatron-dev \ --gpus all \ --ipc=host \ --network host \ --shm-size=64g \ --ulimit memlock=-1 \ --ulimit stack=67108864 \ -v "$HOME /megatron/code:/workspace/code" \ -v "$HOME /megatron/data:/workspace/data" \ -v "$HOME /megatron/checkpoints:/workspace/checkpoints" \ -v "$HOME /megatron/logs:/workspace/logs" \ -v "$HOME /megatron/scripts:/workspace/scripts" \ -v "$HOME /megatron/venv:/workspace/megatron-venv" \ -v "$HOME /model:/workspace/model:ro" \ -e PIP_CONSTRAINT= \ -e PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \ -e PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn \ nvcr.io/nvidia/pytorch:26.01-py3 \ bash
进入容器后执行:
1 source /workspace/scripts/megatron_env.sh
验证:
1 2 which pythonpython -c "import megatron; import megatron.core; print('Megatron OK')"
如果输出:
说明复制到宿主机的 venv 可以正常使用。
使用方案二后的重启恢复方式 采用方案二后,宿主机上需要保留以下目录:
1 2 3 4 5 6 7 ~/megatron/code ~/megatron/data ~/megatron/checkpoints ~/megatron/logs ~/megatron/scripts ~/megatron/venv ~/model
重启电脑后,执行:
1 2 docker start megatron-dev docker exec -it megatron-dev bash
进入容器后:
1 source /workspace/scripts/megatron_env.sh
验证:
1 python -c "import megatron; import megatron.core; print('Megatron OK')"
如果容器不存在,则用 24.3 中的完整 docker run 命令重新创建。只要 ~/megatron/venv 仍然存在,就不需要重新创建虚拟环境,也不需要重新安装 Megatron-LM 依赖。
总结 本文完成了在 Ubuntu 24 + Docker + 4×RTX 4090 环境下安装 NVIDIA Megatron-LM,并完成以下验证:
1 2 3 4 5 6 7 8 9 10 11 12 13 1. NGC PyTorch 容器启动 2. Megatron-LM 源码安装 3. Python venv 隔离环境配置 4. Transformer Engine import 验证 5. 2 卡 NCCL 通信测试 6. 4 卡 NCCL 通信测试 7. Megatron Core 最小训练测试 8. GPT tiny 数据预处理 9. 2 卡 TP=2 GPT 训练 10. 4 卡 TP=4 GPT 训练 11. 4 卡 TP=2 + DP=2 GPT 训练 12. checkpoint 保存验证 13. 容器内 venv 复制到宿主机并持久化挂载
至此,这台 4×RTX 4090 服务器已经可以作为 Megatron-LM 单机多卡训练实验环境使用。