![[从零训练一个500B大语言模型] 14/25:第一台服务器上,软件怎么装?](/_next/image?url=%2Fblog%2Ftraining-500b-part-14-cover.webp&w=3840&q=75&dpl=dpl_2aGB3e3YAHxaAeRNNTJVAfDWDj7C)
[从零训练一个500B大语言模型] 14/25:第一台服务器上,软件怎么装?
前一篇,我们把教材和训练进度安排好了。现在挑出第一台装有8张B200的服务器,登录进去,准备让它开始学习。
第一天的目标很小:读一小份材料,在GPU上训练几步,保存进度,再从保存的位置接着跑。等这件事做通,我们才把同一套环境搬到其他机器。最终,640台服务器上的5,120张GPU要一起训练一个500B稠密模型。
我们就沿着这个过程装软件。每装一部分,都看它解决了什么问题,以及怎样判断它已经可以工作。
先让这台机器认得8张GPU
本计划选择服务器厂商支持的Ubuntu软件组合,包括操作系统、内核、GPU驱动和机内连接管理服务。Ubuntu是这台机器的操作系统,负责管理硬件和运行程序;其余软件让它能够正确使用B200和卡之间的连接。我们把这个组合固定下来,作为640台机器共同的起点。
为什么从厂商支持的组合开始?因为我们需要知道哪些版本可以搭配,以及遇到硬件问题时按什么路径维护。自己定制Linux可以更自由地选择系统组件和更新节奏,同时也要自己验证这些改变与服务器硬件的兼容性。对这批统一硬件,本计划接受厂商的版本约束,把主要精力放在训练和批量运维上。
例如,NVIDIA为DGX机器提供DGX OS,官方支持表列出了DGX B200的系统要求。我们采购的8卡B200服务器,也要取得对应型号的支持清单、安装介质和重装说明。具体版本在采购验收时确认。
机器已经预装好,就按清单核对。需要重装,就按同一清单安装。Ubuntu上的安装工具叫apt:把它指向厂商或NVIDIA的官方软件仓库,指定需要的软件及版本,它就负责下载、安装和记录依赖。后面给640台机器装软件时,这些步骤会写进自动化配方。
NVIDIA的驱动部署文档也推荐这种包管理器路径,便于管理驱动分支、升级和配套软件。官方还提供独立的.run安装器,适合自行管理安装过程的环境。本计划选择固定仓库和软件包,方便重复安装和检查记录。
驱动装好并重启后,运行nvidia-smi,先给GPU点名:8张B200应当都在,状态正常。这说明操作系统能看到它们。机器里的GPU还通过NVSwitch交换数据,B200使用的是第四代NVSwitch,因此还要检查管理这些连接的服务。B200对应的两个服务是Fabric Manager和NVLink Subnet Manager,按官方文档和服务器支持组合安装,再检查服务与链路状态。
这一步做完,我们要得到的结果很明确:操作系统认得8张卡,卡之间的连接也已经准备好。接下来,才轮到训练程序。
内核:操作系统中直接管理硬件资源、协调程序运行的核心部分。
GPU驱动:让操作系统与GPU交互的软件,负责显存、计算任务和设备管理等工作。
包管理器:下载、安装和更新软件,并记录软件依赖关系的工具。
apt是Ubuntu使用的包管理器。
Fabric Manager:管理服务器内GPU互连的软件服务,在B200系统上与NVLink Subnet Manager配合工作。
NVLink Subnet Manager:参与管理B200服务器中NVSwitch连接的软件服务。
再给训练程序准备一套工具
现在假设我们要让模型读一批token,算出预测,再根据预测的误差调整参数。研究员用Python写下这个过程,但计算最终要交给GPU执行。
本计划用PyTorch完成模型计算和梯度计算。它再调用CUDA运行时和计算库,把运算交给GPU。例如,矩阵乘法可以使用cuBLAS提供的实现。可以先记住这条顺序:
训练程序 → PyTorch和GPU计算库 → 驱动 → B200
这些工具可以逐个安装,但要自己处理版本之间的配合。我们选择官方训练容器作为起点,把已经配好的一套工具带到服务器上。容器可以理解为程序启动时使用的一套独立软件环境;镜像则是创建这套环境的模板。同一份镜像可以交给另一台机器使用。
PyTorch:帮助我们定义模型、执行计算并求出梯度的基础框架。
CUDA:NVIDIA的GPU计算平台。这里主要使用它的运行时和计算库,让程序在GPU上完成计算。
容器镜像:包含程序及其依赖软件的模板,启动容器时用它创建运行环境。
第一台参考服务器用Docker启动容器。它需要一个连接GPU的配套工具,叫NVIDIA Container Toolkit。按照官方安装指南,先准备好驱动和Docker,再安装这个工具并配置GPU访问。随后启动测试容器,检查里面是否也能看到8张卡。
这里有一条分工很有用:服务器上的操作系统和驱动负责硬件,容器里面的Python、PyTorch和计算库负责训练程序。以后训练代码更新,主要更换容器镜像;底下的系统仍按已经确认的组合维护。
我们还要把第十三篇准备的教材目录和检查点目录接进容器,让程序能够读取和保存文件。这样,即使容器关闭或换了新版本,教材和训练进度仍然留在外部存储里。
Docker:构建容器镜像和启动容器的工具。本计划用它构建镜像,并在参考服务器上排查问题。
NVIDIA Container Toolkit:帮助容器使用服务器上的NVIDIA GPU设备和驱动能力的工具。
把我们的训练代码也装进去
PyTorch提供基础计算,500B训练还需要模型构造、保存进度、恢复训练和多卡协作等实现。本计划用Megatron Core及同一版本Megatron-LM中的训练代码来组织这些工作,再加入项目需要的代码和配置。
具体做法是从Megatron官方发布版本附带的构建配方开始,保留它选定的基础容器与依赖,在上面加入我们的改动。完成后,生成一个属于项目的训练镜像。这样既能沿用官方组合,也能清楚记录自己改了什么。
开发时,临时装一个Python包很方便。要交给640台机器运行时,我们把这项改动写进构建配方,再生成新镜像。项目沿用官方配方中的uv和锁定文件来记录依赖选择。比如,uv sync --locked会按锁定文件准备环境;声明与锁定结果不一致,就报错,由我们先把版本关系确认清楚。
逐个手动安装的自由度更高;统一构建的收益是各台机器拿到同一份产物。我们选择后者,并承担构建记录、版本更新和验收的维护工作。
Megatron Core:用于大模型训练的组件库。训练程序把其中的模型、并行计算和检查点等组件连起来,完成一次训练。
锁定文件:记录项目实际选择了哪些依赖版本的文件,用来重新建立相同的依赖组合。
展开看:这次采用的版本与构建方法
截至2026年10月29日,本计划保留已发布的Megatron Core 0.19.2,使用同一标签下的官方容器构建文件。该文件以nvcr.io/nvidia/pytorch:26.06-py3为基础镜像,并提供锁定依赖。
26.06容器说明列出的组合是Ubuntu 24.04、CUDA 13.3.0和PyTorch 2.13.0a0+8145d630e8。Ubuntu在这里指镜像内的用户空间,宿主机仍按服务器厂商支持列表选择。Megatron的配方把NCCL设为2.30.7-1+cuda13.3,并处理其他依赖。
具体做法是取回Megatron-LM仓库,切换到core_v0.19.2,记录git rev-parse HEAD的完整结果,使用该版本docker/Dockerfile.ci.dev中名为main的阶段构建依赖环境,再把同一提交的训练代码加入最终项目镜像。项目镜像可以命名为shan-training:mc0.19.2-cu13.3。NVIDIA的基础镜像名称保持原样。
安装前按容器发布说明核对CUDA的驱动要求、服务器厂商支持范围与已知问题。构建时保存基础镜像摘要、构建参数、锁定文件、构建日志和最终镜像摘要。这里选定的是待验收基线;完成单机计算、通信和恢复测试后,再把它推广到其他服务器。
展开看:pip、venv、Conda和源码安装分别做什么?
pip负责安装Python包;venv为项目建立独立环境,让不同项目的包分开保存。Conda也能按环境定义管理软件。这些工具都能用于项目开发。我们的正式构建沿用上游的uv和锁定文件,集中维护一套依赖定义。
增加一个包时,要检查它会不会连带替换官方组合中的PyTorch或其他核心依赖。驱动仍由服务器的系统安装流程管理。
如果需要修改训练实现,或编译自己的GPU算子,就取回指定版本的源码,用匹配的CUDA Toolkit和编译工具构建,再把产物加入项目镜像。安装步骤写进Dockerfile,源代码记录完整提交号,这样另一位同事可以找到相同代码和构建方法。
Python虚拟环境:为一个项目单独保存Python包的环境。
算子:程序中的一项计算,例如矩阵乘法。它的GPU实现通常称为kernel。
CUDA Toolkit:NVIDIA的GPU开发工具集,包含编译器、运行时和相关工具与库。
Dockerfile:记录容器镜像构建步骤的文件。
代码提交号:标识代码仓库某次修改的唯一编号。
跑一小段训练,看看能不能接着学
软件装好以后,最有用的检查是让它们一起做一次真实的工作。我们用一个小模型和一小份固定材料,按顺序回答四个问题。
第一个问题,GPU能不能用?先在服务器上确认8张B200正常,再进容器检查一次。两边看到的设备应当对应得上。
第二个问题,能不能算对?先在一张卡上做一个已知答案的计算,再让小模型完成预测、计算梯度和更新参数。检查数值正常、梯度已经生成、参数按预期改变。正式训练要用的BF16计算方式,以及注意力和融合算子,也放进这个小样例一起检查。
BF16:一种每个数占2字节的浮点格式。本计划用它完成一部分训练计算,同时保留需要更高精度的状态。
第三个问题,8张卡能不能交换结果?我们给第1张卡数字1,第2张卡数字2,一直到第8张卡数字8,让它们求和,再让每张卡都拿到结果。正确答案是36。
这个操作叫AllReduce,由训练环境里的NCCL通信库执行。训练程序提出需要交换的数据,NCCL负责完成交换。它既支持机内通信,也支持跨机器通信,具体能力见NCCL官方说明。小数字通过以后,再测几种更大的数据量,把耗时和日志保存下来,供其他机器验收时比较。
AllReduce:合并各个参与设备上的数值,再让每个设备得到合并结果。这里使用求和。
NCCL:NVIDIA的GPU通信库,负责求和、广播和收集等数据交换操作。
第四个问题,训练停下来以后,能不能接着学?我们从第十三篇安排的存储位置读取真实格式的token文件,先安排100步训练,在第50步保存检查点。随后启动一个新进程,从这个检查点继续到第100步。
特意换一个进程,是为了确认恢复依靠的是存档。新进程要恢复模型参数、优化器、步数、随机状态和数据读取位置。这样,教材从正确的地方继续,学习率也接着原来的安排走。PyTorch保存与加载教程解释了模型权重与可恢复训练状态的区别。
我们再连续跑一次100步,作为对照。两次使用相同的环境、材料顺序和计算设置,比较关键状态及数值误差。测试前先约定允许的误差;浮点计算和部分GPU算子会影响逐位一致性,具体条件见PyTorch可复现性说明。
这四项都通过,才能把第一台机器当作参考。这里检查的是设备、计算、通信和训练恢复。500B模型的实际吞吐,以及完整7TB检查点的写入速度,留到后面的规模验收。
放大到640台,先统一安排,再复制环境
第一台机器上,我们可以直接启动程序。到了640台,就需要先决定哪些机器交给哪个任务,什么时候开始,以及机器出问题后怎样处理。
本计划用Slurm统一安排主训练服务器。提交训练时,先申请所需的整组节点;资源分配好以后,再在这些节点上启动和监控训练进程。小测试也经过队列申请资源,并按账户记录使用量。这正对应Slurm官方说明中的资源分配、并行任务管理和排队职责。
我们选择它,是因为这640台的主要工作是长时间运行的500B同步训练:很多GPU一起算,并持续交换结果。Slurm围绕这类并行作业组织资源,符合本项目的需要。我们会把控制服务、节点服务、记账和故障处理纳入运维交付与培训。
另一个选择是Kubernetes。它也能组织分布式训练,并且适合把训练、在线推理和多个团队的应用放进统一平台。已经有成熟Kubernetes团队的组织,可以复用这些能力。我们的640台定位为专用主训练资源,混合在线服务的收益较小,因此选定Slurm,集中维护这条路线。实际训练速度仍通过计算和通信测试验证。
Slurm:给集群任务分配计算资源,并负责排队、启动和监控的调度系统。
Kubernetes:管理容器化工作负载的平台,可以组合服务、批处理和分布式训练能力。
Slurm确定了“在哪些机器上跑”,还需要把容器真正启动起来。本计划使用Pyxis把容器任务接入Slurm,再由Enroot提供运行环境。这样,用户提交任务后,就能在分配到的机器上运行项目镜像。
前面用Docker,是为了构建镜像和在参考机上排错。正式推广前,我们还要通过Slurm、Pyxis和Enroot重跑同一套验收,检查GPU、文件目录、通信和恢复。源镜像按摘要固定,导入后的产物另存校验值,再统一分发给节点。
Pyxis:把容器任务接入Slurm的插件。
Enroot:将容器镜像导入并运行成用户空间环境的工具。
镜像摘要:根据镜像内容生成的标识,用来确认取回的是同一份镜像。
展开看:其他平台怎样做,我们要维护什么?
Kubernetes可以配合Kueue管理队列和配额,用Kubeflow Trainer组织分布式训练。GPU Operator可以自动管理GPU驱动、Container Toolkit、设备插件和监控等组件。管理员还需要安排这些组件的配套升级,以及共享集群的权限、配额和隔离。
这条路线的收益是复用统一的应用平台;维护范围也包括所选的队列、训练控制器、网络和设备集成。本计划选Slurm,并把主机软件交给统一装机配方管理。
Apptainer也是支持GPU的容器运行工具,适合采用它作为统一运行环境的计算中心。我们的生产环境使用Pyxis和Enroot,集中维护一种启动方式。Pyxis官方说明要求它匹配部署的Slurm版本,这项关系也要进入版本清单。
Kueue:Kubernetes上的排队与配额管理系统,决定任务何时获得运行资格。
Kubeflow Trainer:在Kubernetes上组织分布式模型训练的组件。
GPU Operator:在Kubernetes上自动管理GPU相关软件组件的工具。
让每台机器按同一份配方安装
统一安排任务之前,各台机器还得准备成相同的样子。我们需要复制两份成果:服务器的系统环境,以及项目训练镜像。
容器镜像从团队仓库取得。系统环境则由一份自动装机配方建立。这里沿用前面选定的厂商支持Ubuntu组合,本计划使用PXE、Ubuntu autoinstall、cloud-init和Ansible完成安装。它们按顺序接手,每一步的结果都很具体:
| 装机过程 | 使用的工具 | 做完得到什么 |
|---|---|---|
| 机器从网络取得启动程序 | PXE | 空盘机器也能进入安装流程 |
| 按配置安装Ubuntu | Ubuntu autoinstall | 磁盘和操作系统准备好 |
| 设置每台机器自己的信息 | cloud-init | 机器名、网络和用户准备好 |
| 安装固定软件与配置服务 | Ansible | 同一套驱动、服务及运行工具,并留下执行记录 |
Ubuntu autoinstall、cloud-init和Ansible都有对应的官方说明。通用配方保存一份,每台机器的地址和身份信息单独提供。验证过的系统镜像和软件包也归档,供重装和回退使用。
另一种做法是使用集成平台,例如NVIDIA Base Command Manager,把节点、系统镜像、分发和更新放在同一个系统里。这样可以减少自行连接工具的工作,同时要维护这套平台和集成关系。
本计划选前面的独立工具组合。20人团队中的基础设施人员与集成商共同交付、维护装机配方,把系统版本、配置和验收步骤放在一起审查。代价是我们要整合安装编排、日志收集和版本记录,因此把这些也列入交付验收。这样,每台机器按照一份权威配方准备,出了问题也能沿同一份记录追查。
PXE:让服务器通过网络取得启动程序的方法。
cloud-init:按配置完成系统初始化的工具。
Ansible:按配置批量安装软件、设置服务和管理服务器的工具。
以后升级,也沿着同一条路走
第一台参考服务器通过以后,先推广到一小批机器,再逐批扩展。每台都检查设备、计算和机内通信,失败的节点修好并复验后再加入。跨机器通信和整体性能进入后续集群验收。
升级时也一样。改训练代码或依赖,就构建一个新镜像,先在参考服务器跑短训练和恢复测试。通过以后,再让一小批机器使用,最后逐批切换。旧镜像保留在仓库里,方便回到已经验证的版本。
这里要记住镜像的摘要。Docker文档说明,镜像标签可以指向更新后的内容。标签方便人识别,摘要用于固定具体内容。我们给新环境一个新产物,记录新摘要,验证后再使用,这就是不可变镜像的做法。
如果更新的是操作系统内核或驱动,就安排维护窗口,保留可恢复的系统镜像和软件包,重启后重新验收。回退训练环境时,还要确认旧版本能读取计划用于恢复的检查点。
最后交给同事的,应该是一套能重新执行的流程:按记录装系统,取回指定镜像,接上教材和检查点目录,运行相同测试,再判断是否通过。
展开看:环境交接时留下哪些记录?
| 记录 | 用来做什么 |
|---|---|
| 硬件、固件、操作系统、内核和驱动版本 | 确认机器与底层软件条件 |
| 配套管理服务、容器运行工具、软件包与配置 | 重装相同的系统和生产运行环境 |
| 训练代码提交号、依赖锁定文件和构建配方 | 找回当时的程序及构建方法 |
| 源镜像摘要、导入产物校验值 | 取回同一份训练环境 |
| 训练配置、分词器、样例数据及校验值 | 重跑相同的训练样例 |
| 启动命令、目录位置、通过条件和测试日志 | 让同事重新执行并判断结果 |
| 上一版环境、检查点兼容性记录 | 在更新出现问题时恢复训练 |
我们用这些结果判断安装方法是否适合2026年的大规模训练:能重复安装,能确认软件内容,能自动验收,也能在更新后恢复到已知可用的状态。
现在,从第一台机器到640台的安装与运行路线已经选定。下一篇再看训练本身:一个500B模型放不进一张卡,怎样把它分给很多张卡,并让这些部分一起完成训练?
新文章,直接发到你的邮箱。
AI、工程与实验,每月 1–2 封。
无垃圾邮件,随时取消。