Megatron-LM 可观测性配置指南:基于 OpenTelemetry 与 nemo-lens 的完整参数体系
【免费下载链接】Megatron-LMOngoing research training transformer models at scale项目地址: https://gitcode.com/GitHub_Trending/me/Megatron-LM
导读
Megatron-LM 通过 nemo-lens 为核心骨架,结合仓库源码,系统讲解 CLI 参数、MEGATRON_OTEL_*环境变量、导出秩策略、运行标识与资源属性的完整配置方式。读完后你将掌握从本地调试到生产环境多机训练的全部可观测性配置方案,并理解每个参数背后的源码处理逻辑。
可观测性配置的整体脉络
Megatron-LM 的遥测配置遵循"双入口、单一真相"的设计:
- CLI 入口:
--otel-enabled、--otel-service-name、--otel-span-groups三个参数,在 megatron/training/arguments.py 的opentelemetry参数组中注册; - 环境变量入口:
MEGATRON_OTEL_*前缀的环境变量,默认情况下才是配置主体; - 两类入口最终都在 megatron/training/global_vars.py 的
_set_telemetry()中汇合,由NemoLensConfig.from_env()统一加载。
值得注意的是,CLI 标志具有最高优先级——它们会覆盖对应的环境变量(源码中体现为if getattr(args, 'otel_enabled', False): config.enabled = True这样的覆盖逻辑)。
CLI 参数:三个开关直达遥测核心
原文档给出了三个 CLI 参数,源码中(megatron/training/arguments.py)的具体定义如下:
| Flag | 类型 | 说明 | 源码默认值 |
|---|---|---|---|
--otel-enabled | flag(布尔开关) | 启用 OTel 遥测(trace 与 metrics) | False |
--otel-service-name NAME | string | 覆盖OTEL_SERVICE_NAME环境变量 | None |
--otel-span-groups SPEC | string | 逗号分隔的 span-group 规格,见 Span Groups 文档 | None |
从源码注释可以看出参数组的默认语义:--otel-span-groups接受预设关键字(default、per_step、full、all)或单独的分组名(job、checkpoint、evaluate、model_init、load_checkpoint、step、forward_backward、optimizer、microbatch)或二者的混合;未设置时默认只产生粗粒度的 job/checkpoint/evaluate span。
这三个参数在_set_telemetry()中的处理逻辑为(megatron/training/global_vars.py):
if not os.environ.get('OTEL_SERVICE_NAME', '').strip(): config.service_name = 'megatron-lm' # 未指定服务名时的兜底 if getattr(args, 'otel_enabled', False): config.enabled = True # CLI 强制开启 if getattr(args, 'otel_service_name', None): config.service_name = args.otel_service_name # CLI 覆盖服务名 if getattr(args, 'otel_span_groups', None): config.span_groups = args.otel_span_groups # CLI 覆盖 span 分组这里还有一个容易忽略的细节:当OTEL_SERVICE_NAME未设置且未通过 CLI 指定时,Megatron 会自动把服务名兜底为megatron-lm。
Megatron 专属环境变量:MEGATRON_OTEL_*体系
每个MEGATRON_OTEL_*变量都是对应的NemoLensConfig字段的别名,以NEMO_LENS_*作为回退前缀。它们并非独立设置——设置MEGATRON_OTEL_ENABLED=1等价于设置NEMO_LENS_ENABLED=1,指向同一个底层配置。这种"前缀/回退"模型让 Megatron 可以管理自己的环境变量命名空间,同时继承共享环境中的 lens 默认值。源码中对应NemoLensConfig.from_env(prefix='MEGATRON_OTEL', fallback_prefix='NEMO_LENS', ...)的调用。
完整变量清单:
| 变量 | 默认值 | 说明 |
|---|---|---|
MEGATRON_OTEL_ENABLED | 0 | 总开关;必须设为1才激活遥测 |
MEGATRON_OTEL_RANK_STRATEGY | single_rank | 导出秩策略:single_rank、all_ranks、sampled、first_rank_per_node,或任何通过register_rank_strategy()注册的名称 |
MEGATRON_OTEL_EXPORT_RANK | -1 | 用于single_rank:指定哪个 rank 导出;-1表示最后一个 rank |
MEGATRON_OTEL_EXPORT_SAMPLE_RATE | 1.0 | 用于sampled:采样比例,取值[0.0, 1.0] |
MEGATRON_OTEL_SAMPLING_STRATEGY | (空) | rank_aware或任何通过register_sampling_strategy()注册的名称。为空时保留 OTel SDK 默认采样器 |
MEGATRON_OTEL_TRACES_ENABLED | 1 | 启用 trace span |
MEGATRON_OTEL_METRICS_ENABLED | 1 | 启用 metrics 仪表 |
MEGATRON_OTEL_LOGS_ENABLED | 0 | 启用 OTel 日志桥接(log bridge) |
MEGATRON_OTEL_SPAN_GROUPS | default | span 粒度规格,见 Span Groups 文档 |
MEGATRON_OTEL_EXPORTER | otlp | 导出后端:otlp或console |
NEMO_LENS_RUN_ID | (自动) | 唯一运行标识。自动从SLURM_JOB_ID检测或生成 UUID |
NEMO_LENS_USER_ID | (空) | 可选的用户/团队标签 |
几个需要强调的语义点:
- 总开关逻辑:
MEGATRON_OTEL_ENABLED=0时遥测完全关闭。源码中_set_telemetry()在config.enabled为假时不构建资源属性(resource_attrs = build_telemetry_resource_attrs(args) if config.enabled else {}),注释明确指出这是为了避免在遥测关闭时做nvmlInit()/nvmlShutdown()往返的 NVML 探测(megatron/training/global_vars.py)。 - 日志桥接是可选能力:仅当
config.enabled and config.logs_enabled且 handle 处于导出状态时,才通过setup_logging_bridge()把 Pythonlogging记录桥接到 OTel,使日志携带当前 span 的 trace ID。 - 无 lens 时优雅降级:如果未安装
nemo-lens,_set_telemetry()捕获ImportError后把全局 handle 置为None,遥测成为空操作,不会导致训练启动崩溃(megatron/training/global_vars.py)。
导出秩策略(Rank Strategy):控制谁真正发送遥测
大型分布式训练中,如果所有 rank 都导出遥测,会产生海量冗余数据。Megatron 通过MEGATRON_OTEL_RANK_STRATEGY提供四种内置策略:
| 策略 | 行为 |
|---|---|
single_rank(默认) | 只有单个 rank 导出;配合MEGATRON_OTEL_EXPORT_RANK指定具体 rank,-1表示最后一个 rank |
all_ranks | 所有 rank 都导出 |
sampled | 按MEGATRON_OTEL_EXPORT_SAMPLE_RATE([0.0, 1.0])采样部分 rank 导出 |
first_rank_per_node | 每个节点只由首个 rank 导出 |
此外还支持通过register_rank_strategy()注册自定义策略。官方文档明确说明默认只有一个 rank(最后一个)导出,这与 observability 总览页"By default, only one rank exports (the last rank)"的描述一致。
sampled策略与 OTel SDK 自带的采样器(如parentbased_traceidratio)是两个不同维度、可叠加使用的机制:前者决定"哪些 rank 导出",后者决定"导出 rank 的哪些 trace 被采样",两者通过MEGATRON_OTEL_SAMPLING_STRATEGY协调。
标准 OTel SDK 环境变量:直接透传
Megatron 不拦截标准 OTel SDK 变量,它们由 SDK 直接读取生效:
| 变量 | 示例 |
|---|---|
OTEL_SERVICE_NAME | megatron-training |
OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4317 |
OTEL_EXPORTER_OTLP_PROTOCOL | grpc或http/protobuf |
OTEL_EXPORTER_OTLP_HEADERS | Authorization=Bearer <token> |
OTEL_TRACES_SAMPLER | parentbased_traceidratio |
OTEL_TRACES_SAMPLER_ARG | 0.1 |
注意OTEL_SERVICE_NAME与前文 CLI 参数--otel-service-name的优先级关系:CLI 参数显式覆盖该环境变量;环境变量未设置时由 Megatron 兜底为megatron-lm。
运行标识(Run Identification):跨后端关联同一训练任务
每次训练运行都会被自动分配一个唯一的nemo.run.id资源属性,并流向所有后端(Jaeger、Grafana、Kibana 等),用于隔离特定运行。
优先级顺序:
NEMO_LENS_RUN_ID环境变量(显式指定,最高优先级);SLURM_JOB_ID环境变量(SLURM 集群上自动检测);- 自动生成的 12 字符 UUID(兜底)。
分布式语义:
- 分布式任务中的所有 rank 共享同一个
run_id; - 每个 rank 拥有唯一的
service.instance.id,格式为{run_id}-rank{rank}; - 在 Jaeger、Grafana、Kibana 中按
nemo.run.id过滤,即可把一次训练运行的所有 trace 与指标隔离出来。
在此基础上,源码 megatron/training/global_vars.py 还进一步补充了nemo.lens.job_uuid(逻辑训练任务,跨重启/重排队稳定)与nemo.lens.run_uuid(单次运行实例,每次重启递增)两个确定性 UUID 资源属性。它们的构造基于SLURM_ARRAY_JOB_ID/SLURM_JOB_ID、SLURM_RESTART_COUNT、TORCHELASTIC_RESTART_COUNT等环境变量,且刻意设计为"零通信"——所有 rank 和 checkpoint worker 都从同一份继承环境推导出一致的值,可扩展到上万 rank 的规模。
资源属性(Resource Attributes):把训练配置烙进每个 span
Megatron 的_set_telemetry()会把训练配置属性写入 OTelResource,使它们作为 Jaeger 的 "Process" 标签出现在运行中的每个 span 上。属性与 Megatron 参数来源的对应关系(源码实现在 megatron/training/global_vars.py 的build_telemetry_resource_attrs()):
| 属性 | Megatron 参数来源 |
|---|---|
dl.local_rank | args.local_rank |
dl.tensor_parallel.size | args.tensor_model_parallel_size |
dl.pipeline_parallel.size | args.pipeline_model_parallel_size |
dl.data_parallel.size | args.data_parallel_size |
dl.batch_size | args.global_batch_size |
dl.sequence_length | args.seq_length |
megatron.num_layers | args.num_layers |
megatron.hidden_size | args.hidden_size |
megatron.num_attention_heads | args.num_attention_heads |
megatron.train_iters | args.train_iters |
megatron.micro_batch_size | args.micro_batch_size |
megatron.ckpt_format | args.ckpt_format |
megatron.precision | fp16/bf16/fp32(由args.fp16、args.bf16标志推导) |
此外还有 lens 资源检测自动发现的属性(hostname、PID、GPU 数量、SLURM 元数据、Kubernetes 元数据),以及 Megatron 额外注入的 GPU 物理身份(dl.gpu.index、dl.gpu.name、dl.gpu.uuid、dl.gpu.serial、dl.gpu.pci_bus_id,通过_detect_gpu_identity()基于 NVML 探测,见 megatron/training/global_vars.py)和 SLURM 身份(slurm.job.id、slurm.sluid、slurm.cluster、slurm.array.job_id等)。
这里有一个源码层面的细节值得注意:build_telemetry_resource_attrs()被设计为"主进程与异步 checkpoint worker 共享"——megatron/training/async_utils.py 的build_otel_worker_bootstrap()会复用同一函数构造 worker 进程的资源属性字典,确保两边"按构造就一致",而不是两份独立实现随参数演进悄悄漂移。
典型配置:四种开箱即用的实战场景
原文档给出了四套可直接复制的配置,这里结合源码补充语义说明。
场景一:本地开发 + console 导出器
export MEGATRON_OTEL_ENABLED=1 export MEGATRON_OTEL_EXPORTER=console python examples/run_simple_mcore_train_loop.pyspan 与指标直接打印到 stdout,适合快速验证遥测是否生效。examples/run_simple_mcore_train_loop.py是仓库中的最小核心训练循环示例,无需完整参数体系即可跑通。
场景二:本地 Collector(localhost OTLP 端点)
export MEGATRON_OTEL_ENABLED=1 export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 torchrun --nproc_per_node=8 pretrain_gpt.py ...把遥测指向 localhost 的 OTLP 端点——可以是 OpenTelemetry Collector,也可以是直接接受 OTLP 的后端(如 Jaeger)。需要本地接收栈时,可参考 lens 文档中关于"把遥测发送到后端"的说明。
场景三:生产环境 + 远程 Collector
export MEGATRON_OTEL_ENABLED=1 export MEGATRON_OTEL_SPAN_GROUPS=default export OTEL_EXPORTER_OTLP_ENDPOINT=http://<collector-host>:4317 export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>" python pretrain_gpt.py ...defaultspan 分组开销最低、适合生产;Authorizationheader 用于远端鉴权(如 Grafana Cloud、Honeycomb 等托管后端)。
场景四:per-step 粒度 + trace 采样
export MEGATRON_OTEL_ENABLED=1 export MEGATRON_OTEL_SPAN_GROUPS=per_step export OTEL_TRACES_SAMPLER=parentbased_traceidratio export OTEL_TRACES_SAMPLER_ARG=0.1 # 只保留 10% 的 traceper_step提供每个训练迭代级的 span 细节,配合parentbased_traceidratio以 0.1 的比例采样,在"细节"与"开销"之间取得平衡——这是官方推荐的性能剖析组合。
源码视角:_set_telemetry()的完整处理流程
把以上配置串联起来,megatron/training/global_vars.py 中_set_telemetry()的完整流程是:
- 导入兜底:尝试导入
nemo.lens的NemoLensConfig与setup_telemetry,失败则全局 handle 置None、直接返回(遥测空操作,不阻塞启动); - 构造配置:
NemoLensConfig.from_env(prefix='MEGATRON_OTEL', fallback_prefix='NEMO_LENS', span_group_cls=MegatronSpanGroup)从环境变量加载配置,并注入 Megatron 自定义的 span 分组类MegatronSpanGroup(定义在 megatron/core/telemetry/span_groups.py,扩展了 lens 的基础分组,新增microbatch、layer、communication、activation_offload、data_loading、first_iteration、trace_region、inference等分组); - CLI 覆盖:依次应用
--otel-enabled、--otel-service-name、--otel-span-groups的覆盖逻辑; - 资源属性构建:仅在启用状态下调用
build_telemetry_resource_attrs()(避免遥测关闭时的 NVML 开销); - 初始化遥测:
setup_telemetry(config, rank=args.rank, world_size=args.world_size, resource_attributes=resource_attrs)创建全局 handle; - 可选日志桥接:启用且可导出时建立 logging → OTel 的桥接。
这套流程在训练初始化阶段由set_global_variables()调用(megatron/training/global_vars.py),与其他 logger(TensorBoard、W&B、one_logger)的初始化并列。
配置进阶:与 span 分组、指标体系的联动
配置 OTel 不只是开关遥测,还需要理解它与 span 粒度、指标命名空间的关系,才能设计出高效的观测方案。
- span 粒度三档:
default(job/checkpoint/evaluate/inference,开销最低、生产安全)→per_step(增加 model_init、load_checkpoint、step、forward_backward、optimizer、communication、data_loading,建议配合采样)→all(包含 microbatch、layer、activation_offload 等最细粒度,仅限开发/调试)。每个 span 都挂有控制其是否发射的 span 组,非导出 rank 的 span 组为frozenset(),is_span_group_enabled()处处返回False,根本不会创建 span 对象——关闭路径是一次 frozenset 查找后立即返回,而非仍然分配对象的空操作 span。详见 Span Groups 文档。 - 指标命名空间:训练指标统一挂在
megatron.training.*命名空间下(如megatron.training.loss、megatron.training.step_duration_ms、megatron.training.throughput_tflops),且只在导出 rank 上发射。这些指标与--log-interval同节奏,与 TensorBoard/W&B 日志保持一致。详见 Metrics 文档。 - 数据定位:指标每条数据点都携带
nemo.run.id资源属性,可在 Grafana 中用{nemo_run_id="<id>", __name__=~"megatron_training_.*"}过滤单个运行,或用{nemo_run_id=~"run-a|run-b", __name__="megatron_training_loss"}对比两个运行。
结语:从"开了遥测"到"可用的观测体系"
配置 Megatron-LM 的可观测性,本质上是四层决策:开关(MEGATRON_OTEL_ENABLED+--otel-enabled)、粒度(MEGATRON_OTEL_SPAN_GROUPS三档预设)、范围(MEGATRON_OTEL_RANK_STRATEGY决定谁导出、OTel SDK 采样器决定导出什么)、归属(NEMO_LENS_RUN_ID与资源属性让每次运行可检索、可对比)。本文涉及的 CLI 参数、环境变量、资源属性与源码实现均已可在当前仓库中直接核对,结合 observability 文档目录 中的 span 分组、指标、流水线并行关联与扩展指南,可以搭建一套从单机调试到万卡级生产训练都适用的观测体系。
【免费下载链接】Megatron-LMOngoing research training transformer models at scale项目地址: https://gitcode.com/GitHub_Trending/me/Megatron-LM
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考