系统健康检查和调试#
成功操作和管理集群的关键在于所有节点都针对其功能进行了相同的配置,并且它们运行一致。当出现问题时,需要测试系统以查看它们是否运行正常。
如果发现问题,应将其从批处理分区中删除以进行初步分类。
除非问题很明显,否则请遵循 GPU 系统调试指南流程,该流程位于 https://docs.nvda.net.cn/deploy/gpu-debug-guidelines/index.html
此外,运行 DGX A100 系统特有的工具。对于健康检查,这是 NVIDIA 系统管理工具 (nvsm)。
开发一组单节点和多节点测试也很有用,以帮助验证 DGX SuperPOD 的操作和性能(表 13)。通常,最好为此目的使用您自己的关键应用程序,因为这些应用程序以对用户最重要的的方式来锻炼系统。
表 13. DGX SuperPOD 验证工具
软件 |
用途 |
链接 |
---|---|---|
NCCL |
Fabric |
|
HPL |
具有网络通信的数学密集型应用程序 |
此外,还有一些标准应用程序可用于验证单节点和多节点性能。运行以下测试时,您应该期望在系统的不同部分上运行相同配置的性能应在相似的时间或相似的性能水平下运行。由于系统配置和现有作业负载,性能可能在运行之间有所不同。但是,如果在同一组硬件上的多次运行中发现差异,则可能表明该系统的某些组件存在问题。
收集日志文件#
重要的日志文件包括
/var/log/cmdaemon(最重要的一个 — CMDaemon 日志文件)。
/var/log/node-installer(节点安装程序日志文件)。
/var/spool/cmd/<slave-node-name>.rsync(配置日志)。
日志子系统#
每个日志消息都作为子系统的一部分发出,该子系统在每个翻译单元的基础上定义。示例子系统包括 CONFIG、MIC、GPU、CLOUD、PROV、SERVICE、WLM、DB、USER、JSON、HADOOP 和 CMD(可以在 logger.h 中找到)。示例日志输出 /var/log/cmdaemon
1Mar 30 03:38:02 headnodeName cmd: [ CLOUD ] DevDbg:
2Mar 30 03:38:02 headnodeName cmd: [ CMD ] Debug: [programrunner.cpp:797 ] ProgramRunner: /cm/local/apps/cmd/scripts/cloudproviders/openstack/openstackcommands.py [DONE] 0 0
3Mar 30 03:38:02 headnodeName cmd: [ CMD ] Warning: [magicmanager.cpp:1797 ] This is a warning.
子系统包含在 [ ] 中,后跟日志类型(debug、warning、info、error)、源代码中的位置(仅在 -D _DEBUG 编译中存在),然后是日志消息。
增加日志详细程度#
可以使用 /cm/local/apps/cmd/etc/logging.cmd.conf 配置文件更改各个子系统的详细程度。修改 logging.cmd.conf 后,必须重新启动 CMDaemon 或运行 service cmd logconf 以重新加载日志配置文件。此文件中的默认设置如下
1Severity {
2 info: *
3 warning: *
4 debug:
5 error: *
6}
这意味着始终记录所有详细程度级别(“debug”除外)中来自所有子系统的消息。当专注于仅为特定子系统开发功能时,修改 logging.cmd.conf 非常有用,因为它可以用于静默来自其余子系统的日志,而仅关注必要的日志。
也就是说,可以启用来自 CLOUD 子系统的所有日志消息,同时仅允许来自所有其他剩余子系统的 WARNING 和 ERROR 消息。
1Severity {
2 info: CLOUD
3 warning: *
4 debug: CLOUD
5 error: *
6 }
还可以选择使用 logging.cmd.conf 在时间戳中启用 ThreadID、子系统名称和微秒分辨率的日志记录。
全局调试模式#
可以通过 service cmd debug{on|off} 或通过使用 -d 标志启动 cmd 来切换所谓的全局调试模式。在此模式下,来自 logging.cmd.conf 的自定义设置将被忽略,而是始终以最大详细程度记录来自所有子系统的所有日志消息。全局调试模式等效于使用以下 logging.cmd.conf
1Severity {
2 info: *
3 warning: *
4 debug: *
5 error: *
6}
LOGPREFIX#
使用 LOGPREFIX(“DeviceManager”) 宏为所有后续的 log{i,d,dd,e,w}() 调用预先添加额外的文本,例如
1Manager::someFun() {
2 LOGPREFIX("SomeFunction:");
3 logdd("entered function");
4 ...
5 logdd("left function");
6}
将产生以下日志
1"SomeFunction: entered function"
2"SomeFunction: left function"