# 基于ModelArts训练平台对接SwanLab和WandB
#### 场景描述
SwanLab和WandB是两款常用的机器学习实验管理工具，可用于记录模型训练过程中的超参数、Loss、Accuracy、Learning Rate、Reward 等训练指标，并提供实验管理、可视化分析及多次实验对比等能力，帮助开发者更加高效地完成模型开发与调优。
ModelArts自定义训练作业及强化学习训练作业均支持用户在训练代码中集成SwanLab或WandB SDK，实现训练过程中的实验数据记录。结合 ModelArts的训练任务运行机制，本实践提供以下两种实验数据管理方式：
● **实验文件导出方式**：训练过程中产生的实验数据保存至训练输出目录，并通过OBS持久化存储。训练结束后，用户可将实验文件下载至本地，通过 SwanLab或WandB提供的工具查看和分析实验结果。
● **实时监控方式**：用户可在ECS上部署SwanLab或WandB服务，并与训练容器建立网络连接。训练过程中，实验数据将实时上传至部署的服务，用户可通过Web页面实时查看训练指标变化及实验状态，实现在线监控和管理。
本文将介绍在ModelArts自定义训练任务及强化学习训练作业中集成SwanLab和WandB的环境准备、SDK接入、训练任务配置，以及上述两种实验数据管理方式的实现方法，帮助用户根据不同业务场景选择合适的实验管理方案。
#### 方案介绍
ModelArts自定义训练作业及强化学习训练作业支持通过集成SwanLab或WandB SDK，对训练过程中的实验数据进行记录和管理。根据实验数据的查看方式不同，本实践提供以下两种集成方案。
- **方案一：实验文件导出与本地查看。**
  训练过程中，SwanLab或WandB SDK将实验数据输出至训练结果目录。结合 ModelArts训练输出目录与OBS存储能力，实验数据将在训练结束后自动保存至指定的OBS路径。用户可将实验文件下载至本地，并通过本地环境查看实验结果。
  对于SwanLab，可直接使用本地查看功能对实验数据进行可视化展示，无需额外部署服务；对于WandB，可在本地部署WandB Local服务后导入实验数据进行查看。
  该方案无需在云上部署实验管理服务，部署成本较低，适用于实验归档、离线分析及网络受限等场景。
  

- **方案二：ECS 实时实验监控**
  用户可在ECS上部署SwanLab或WandB服务，并与ModelArts训练容器建立网络连接。训练过程中，SDK将实验数据实时上传至部署的服务，用户可通过Web页面实时查看训练进度、Loss、Accuracy、Learning Rate、Reward等训练指标，并统一管理历史实验。
  该方案支持训练过程实时监控、多实验统一管理，更适用于长时间训练任务、模型调优及多人协同开发等场景。
  两种方案的对比如[表1]。
   表1方案对比 
  | 方案对比项            | **方案一：实验文件导出与本地查看** | **方案二：ECS 实时实验监控** |
  |:---|:---|:---|
  | **数据存储方式**      | 保存至训练输出目录，并同步至OBS。   | 实时上传至ECS服务。      |
  | **查看方式**         | 下载到本地后查看          | Web 页面实时查看        |
  | **是否需要云端部署服务** | 否                    | 是                  |
  | **是否支持实时监控**     | 否                    | 是                |
  | **网络要求**       | 训练结束后下载实验文件。       | 训练容器与 ECS 网络互通。    |
  | **适用场景**        | 实验归档、离线分析、个人开发。    | 实时监控、实验管理。        |
     
  用户可根据业务需求选择合适的方案。若仅需保存实验结果并在本地进行分析，推荐采用方案一；若需要实时监控训练过程或统一管理多个实验，推荐采用方案二。
  
 
#### 环境准备
在 ModelArts 自定义训练任务中使用SwanLab或WandB，需要确保训练环境已安装对应的SDK。根据实际业务需求，可选择以下两种方式准备训练环境。
- **方式一：使用预置镜像，在启动命令中安装SDK** 。
  该方式无需制作和维护自定义镜像，可直接使用ModelArts提供的预置镜像。在训练任务启动时，通过启动命令安装SwanLab或 WandB SDK，然后自动执行训练脚本。
  **适用场景**
  ● 偶发或少量训练任务；
  ● 使用ModelArts预置镜像即可满足训练环境需求；
  ● 对训练启动时间要求不高。
  **注意事项**
  由于SDK安装命令会在每次训练作业启动时执行，因此会增加一定的环境准备时间。当频繁提交训练任务时，不建议采用该方式。
  安装命令如下：
  ● 安装 SwanLab SDK
  ```
  pip install swanlab
  ```
  ● 安装 WandB SDK
  ```
  pip install wandb
  ```
  图1安装软件命令   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749702102.png) 
- **方式二：使用自定义镜像预装 SDK** 。
  该方式基于ModelArts预置镜像制作自定义镜像，在镜像构建阶段完成SwanLab或WandB SDK的安装，并将镜像上传至SWR镜像仓库。后续创建训练任务时直接使用该镜像，无需在每次训练作业启动时重复安装 SDK。
  **适用场景**
  ● 需要频繁启动训练任务；
  ● 训练环境需要预装第三方依赖或自定义运行环境；
  ● 对训练启动效率有较高要求。
  **注意事项**
  ● 制作镜像时，应根据训练资源选择对应架构的预置镜像（如 x86 或 ARM）。
  ● 当本地开发环境与目标镜像架构不一致时（例如本地主机为 x86，而目标镜像为 ARM），可能无法完成镜像构建。建议在与目标架构一致的环境中制作镜像，例如使用对应架构的 ECS 实例。
  ● 在制作自定义镜像时，仅需将官方示例中的 dockerfile 依赖安装命令替换为对应的 SDK 安装命令即可：
  ```
  FROM {ModelArts提供的训练基础镜像地址} # 参考网站 https://support.huaweicloud.com/docker-modelarts/docker-modelarts_6022.html
  # 配置pip
  RUN mkdir -p /home/ma-user/.pip/
  COPY --chown=ma-user:ma-group pip.conf /home/ma-user/.pip/pip.conf
  # 设置容器镜像预置环境变量
  # 将python解释器路径加入到PATH环境变量中
  # 请务必设置PYTHONUNBUFFERED=1, 以免日志丢失
  ENV PATH=${ANACONDA_DIR}/envs/${ENV_NAME}/bin:$PATH \
      PYTHONUNBUFFERED=1
  RUN /home/ma-user/anaconda/bin/pip install --no-cache-dir swanlab # 或 wandb
  ```
  ● 制作完成镜像发送到 SWR 上供训练使用
  ● 制作镜像过程可以参考文章：[使用预置镜像制作自定义镜像用于训练模型_制作自定义镜像用于训练模型_镜像管理_魔坊（ModelArts）模型训推平台-华为云](https://support.huaweicloud.com/docker-modelarts/docker-modelarts_0118.html)
  图2加载镜像   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002779141135.png)
  完成训练环境准备后，即可根据实际需求选择实验文件导出或实时实验监控方案，实现训练实验数据的记录、管理与可视化展示。
  
 
#### 使用SwanLab和WandB查看训练指标
- **方案一：实验文件导出与本地查看。**
  **方案说明**
  本方案适用于训练结束后查看实验结果的场景。训练过程中，SwanLab或WandB SDK将实验数据保存至ModelArts训练输出目录，并随训练输出同步至OBS。训练完成后，用户可将实验数据下载至本地主机，通过SwanLab或WandB提供的本地查看方式进行实验分析和管理。
  相比实时监控方案，本方案无需在云上部署实验管理服务，实现简单，适用于实验归档、离线分析以及网络受限等场景。
  整体流程如下：
  图3训练数据处理流程   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002779141133.png)
  **集成SwanLabSDK**
  完成训练环境准备后，需要在训练代码中集成SwanLab SDK，以记录训练过程中的实验数据。主要包括实验初始化和训练指标记录两部分。
  下面以一个简单的PyTorch训练示例说明SwanLab的基本使用方式。
  ```
  import torch
  import torch.nn as nn
  import torch.optim as optim
  import swanlab
  # 初始化实验
  swanlab.init(
      project="modelarts-demo",
      experiment_name="exp-001",
      config={
          "learning_rate": 0.001,
          "batch_size": 32,
          "epochs": 5
      },
      mode="local",
      logdir="./swanlog"
  )
  # 定义简单模型
  model = nn.Linear(10, 2)
  criterion = nn.CrossEntropyLoss()
  optimizer = optim.SGD(model.parameters(), lr=0.001)
  # 模拟训练
  for epoch in range(5):
      inputs = torch.randn(32, 10)
      labels = torch.randint(0, 2, (32,))
      outputs = model(inputs)
      loss = criterion(outputs, labels)
      optimizer.zero_grad()
      loss.backward()
      optimizer.step()
      # 记录训练指标
      swanlab.log({
          "epoch": epoch + 1,
          "loss": loss.item(),
          "learning_rate": optimizer.param_groups[0]["lr"]
      })
  # 结束实验
  swanlab.finish()
  ```
  上述示例中，swanlab.init()用于初始化实验，常用参数如下表。
  表2参数说明 
  | 参数               | 说明                                                                  |
  |:---|:---|
  | project          | 实验所属项目名称。建议多次训练保持相同的project，并使用不同的experiment_name区分不同实验，便于后续统一对比分析。 |
  | experiment_name | 实验名称，用于区分不同训练任务。                                                   |
  | config           | 实验配置，用于记录Learning Rate、Batch Size、Epoch等超参数。                         |
  | mode              | 实验运行模式，可选择local或offline。                                            |
  | logdir            | 实验数据保存目录，建议配置为ModelArts训练输出目录。                                       |
     
  训练过程中，可通过swanlab.log()持续记录Loss、Accuracy、Learning Rate、Reward等训练指标，也可以根据实际业务需求记录其他自定义指标。训练结束后，调用swanlab.finish()完成实验并保存实验数据。
  **配置训练任务**
  建议将ModelArts训练输入目录与训练输出目录配置为同一个OBS路径，使多次训练产生的实验数据能够持续保存和累积。
  训练代码中，可将输入目录中的历史实验数据复制至输出目录，避免训练结束后覆盖已有实验数据。
  启动命令示例如下：
  ```
  python ${MA_JOB_DIR}/train.py --data_url=${data_url} --train_url=${train_url}
  ```
  其中：
  ● ${MA_JOB_DIR}为训练代码目录；
  ● data_url为 ModelArts自动挂载的输入目录；
  ● train_url为 ModelArts自动挂载的输出目录。
  图4设置训练输入输出路径   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002778981291.png)
  训练结束后，可在配置的OBS路径中查看生成的swanlog目录。
  **查看实验结果**
  训练任务完成后，SwanLab会将实验数据保存至训练输出目录，并同步至配置的OBS路径。用户可根据配置的运行模式，在本地主机查看实验结果。请按如下步骤操作：
  1. 前往训练作业配置的OBS输出路径，下载生成的swanlog目录至本地主机（建议使用OBS Browser+工具下载）。 ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002779141137.png)
     
  
  
  
  2. 在本地主机准备Python运行环境，并安装SwanLab。 ● Local 模式：
     ```
     pip install swanlab swanlab[dashboard]
     ```
     ● Offline 模式：
     ```
     pip install swanlab
     ```
     
  
  3. 启动可视化服务。
     - **Local 模式**
       进入下载后的swanlog目录，执行以下命令启动本地可视化服务：
       ```
       swanlab watch
       ```
       命令执行成功后，浏览器会自动打开SwanLab Dashboard（或根据终端输出的地址访问），即可查看训练过程中记录的Loss、Accuracy、Learning Rate、Reward等实验指标。
       若多次训练使用相同的project、不同的experiment_name，所有实验将自动聚合至同一个Project中，可直接进行实验对比和可视化分析。
       图5SwanLab Dashboard   
       ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749542208.png) 
     
     
     
     - **Offline 模式**
       首次使用前，需要完成SwanLab账号登录。
       ```
       swanlab login
       ```
       根据终端提示输入API Key完成认证。登录成功后，在下载后的实验数据目录执行以下命令：
       ```
       swanlab sync /path/to/swanlog
       ```
       其中，/path/to/swanlog为下载后的实验数据目录。
       实验数据同步完成后，即可登录SwanLab Web页面查看和管理实验结果，并支持对多个实验进行统一分析和对比。
       图6SwanLab Dashboard   
       ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002778981287.png) 
      
  
  
  **集成 WandB SDK**
  完成训练环境准备后，需要在训练代码中集成WandB SDK，以记录训练过程中的实验数据。主要包括实验初始化和训练指标记录两部分。
  下面以一个简单的PyTorch训练示例说明WandB的基本使用方式。
  ```
  import torch
  import torch.nn as nn
  import torch.optim as optim
  import wandb
  # 初始化实验
  wandb.init(
      project="modelarts-demo",
      name="exp-001",
      config={
          "learning_rate": 0.001,
          "batch_size": 32,
          "epochs": 5
      },
      mode="offline"
  )
  # 定义简单模型
  model = nn.Linear(10, 2)
  criterion = nn.CrossEntropyLoss()
  optimizer = optim.SGD(model.parameters(), lr=0.001)
  # 模拟训练
  for epoch in range(5):
      inputs = torch.randn(32, 10)
      labels = torch.randint(0, 2, (32,))
      outputs = model(inputs)
      loss = criterion(outputs, labels)
      optimizer.zero_grad()
      loss.backward()
      optimizer.step()
      # 记录训练指标
      wandb.log({
          "epoch": epoch + 1,
          "loss": loss.item(),
          "learning_rate": optimizer.param_groups[0]["lr"]
      })
  wandb.finish()
  ```
  上述示例中，wandb.init()用于初始化实验，常用参数如下。
  
  | 参数       | 说明                                            |
  |:---|:---|
  | project | 实验所属项目名称。建议多次训练保持相同的project，便于统一管理实验。           |
  | name     | 实验名称，用于区分不同训练任务。                               |
  | config    | 实验配置，用于记录Learning Rate、Batch Size、Epoch等超参数。 |
  | mode        | 建议配置为offline，训练过程中仅将实验数据保存至本地目录，不实时上传至WandB服务。 |
     
  训练过程中，可通过wandb.log() 持续记录Loss、Accuracy、Learning Rate、Reward等训练指标，也可以根据实际业务需求记录其他自定义指标。训练结束后，调用wandb.finish()完成实验并保存实验数据。
  **配置训练任务**
  WandB的训练任务配置方式与SwanLab保持一致，可参考**实验数据导出** 中的**SwanLab 配置训练任务**章节。建议将训练输出目录配置为 ModelArts 输出路径，并同步保存至 OBS，以便统一管理多次训练产生的实验数据。
  训练完成后，可在配置的OBS路径中查看生成的WandB实验数据目录，并下载至本地主机。
  **查看实验结果**
  与SwanLab不同，WandB不提供类似swanlab watch的本地实验查看功能。使用offline模式时，训练过程中仅会生成离线实验文件，无法直接通过本地Dashboard查看实验结果。
  训练任务完成后，前往训练作业配置的OBS输出路径，下载生成的WandB实验数据目录至本地主机。在本地主机安装WandB后，首次使用需完成账号登录。
  ```
  wandb login
  ```
  根据提示输入对应服务的API Key，完成身份认证。
  随后执行以下命令，将离线实验数据同步至WandB服务。
  ```
  wandb sync /path/to/wandb
  ```
  其中，/path/to/wandb为下载后的WandB实验数据目录。
  实验数据同步完成后，即可登录WandB Dashboard查看训练过程中记录的实验指标，并对多个实验进行统一管理、对比分析和可视化展示。
  若使用WandB官方Cloud 服务，实验数据将同步至官方平台；若使用自部署的WandB Server，则可通过指定服务地址将实验数据同步至本地部署的服务。Offline模式的数据同步方式与SwanLab基本一致，均需要在训练结束后将离线实验数据上传至对应服务，再通过Web页面查看实验结果。
  
 
- **方案二：ECS 实时实验监控**
  **方案说明**
  对于需要实时监控训练过程、统一管理实验的场景，可在华为云ECS上部署SwanLab或WandB服务，并与ModelArts训练容器建立网络连接。训练过程中，SDK将实验数据实时上传至部署的服务，用户无需等待训练结束即可通过Web页面查看 Loss、Accuracy、Learning Rate、Reward等训练指标，以及训练日志和实验配置等信息。
  相比实验数据导出方案，本方案支持训练过程实时可视化、多实验统一管理，更适用于长时间训练任务、模型调优及持续迭代开发等场景。
  整体流程如下：
  图7操作流程   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002779141143.png)
  **准备ECS资源**
  部署SwanLab或WandB服务前，需要准备一台用于运行实验管理服务的ECS实例。
  创建ECS时，建议注意以下配置：
  ●ECS与ModelArts训练任务选择相同Region，以减少网络时延并便于网络配置。
  ● ECS所在VPC建议与ModelArts训练专属资源池使用的VPC保持一致。若ECS与训练资源池不在同一VPC，需要通过VPC对等连接、云连接等方式打通网络，否则训练容器可能无法访问部署在ECS上的实验管理服务。
  ● 根据实验规模选择合适的实例规格。对于个人开发及功能验证场景，普通规格即可满足部署需求；若需支持多人同时访问或管理大量实验，可根据实际情况提升实例规格。
  ● 操作系统建议选择支持Docker和Python环境的Linux Ubuntu发行版，以便后续部署SwanLab或WandB服务。
  ● 为ECS绑定弹性公网IP（EIP），便于通过浏览器访问实验管理页面，以及通过SSH登录ECS进行服务部署和运维。
  ● 配置安全组规则，放行实验管理服务端口。例如SwanLab默认使用8000端口，WandB本地服务端口以实际部署配置为准。同时需要放行SSH端口22，便于登录ECS进行运维。若仅允许训练资源池访问，建议将入方向源地址限制为训练资源池所在网段，避免端口暴露范围过大。
  完成ECS创建后，即可进行网络连通配置，并部署实验管理服务。
  **配置网络连通**
  完成ECS创建后，需要确保ModelArts训练资源能够访问部署在ECS上的SwanLab或WandB服务。
  开始部署前，建议确认以下网络配置：
  ● ECS与ModelArts专属资源池位于同一VPC；若不在同一VPC，请完成VPC对等连接或其他网络打通配置。
  图8配置VPC   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749542210.png)
  ●ECS安全组需放行实验管理服务使用的端口（例如SwanLab默认**8000** ，wandb默认**8080**）以及SSH（22）端口；若部署时修改了端口映射，则需放行实际对外提供服务的端口。
  ● 路由表配置正确，训练资源能够访问**ECS私有IP**。
  ● 在训练容器中可通过curl或其他网络工具访问实验管理服务地址，确认网络连通正常。
  确认以上配置无误后，即可开始部署SwanLab或WandB服务，并在训练任务中实时上传实验数据。
  **部署 SwanLab 服务**
  完成网络配置后，可在ECS中部署SwanLab服务，用于接收训练过程中上传的实验数据，并提供实验管理及可视化能力。操作步骤如下：
  1. 准备部署环境。部署SwanLab服务前，需要准备一台可正常运行Docker的Linux ECS，并确保已安装以下基础软件： ● Python
     ● pip
     ● Docker
     ● Docker Compose
     ● Git（可选）
     ![](https://support.huaweicloud.com/bestpractice-modelarts/public_sys-resources/note_3.0-zh-cn.png)
     若 ECS 无法使用Git，也可以在本地下载SwanLab Self-Hosted部署文件，解压后上传至ECS。
     
  
  2. 获取部署文件。推荐通过Git获取SwanLab Self-Hosted官方部署仓库：
     ```
     git clone https://github.com/SwanHubX/self-hosted.git
     cd self-hosted/docker
     ```
     若ECS无法访问GitHub，可在本地下载仓库压缩包，上传至ECS后解压，并进入self-hosted/docker目录。
     
  
  3. 部署 SwanLab 服务。
     - **在线部署**
       如果ECS可以访问镜像仓库，可直接执行官方安装脚本：
       ```
       ./install.sh
       ```
       该脚本会自动拉取 SwanLab 服务所需镜像，并完成初始化配置。
       
     
     - **离线部署**
       若ECS无法访问镜像仓库，可在能够访问公网的环境中提前拉取镜像，并导入至ECS。
       在本地执行：
       ```
       docker pull swanhubx/self-hosted:latest
       docker save swanhubx/self-hosted:latest -o swanlab.tar
       ```
       若镜像文件较大，可拆分后上传：
       ```
       split -b 500M swanlab.tar swanlab.tar.
       ```
       将所有分片上传至ECS后，在ECS中执行：
       ```
       cat swanlab.tar.* > swanlab.tar
       docker load -i swanlab.tar
       ```
       完成镜像导入后，即可按照正常方式启动服务。
       
      
  
  4. 启动服务。进入部署目录后，执行以下命令启动SwanLab服务：
     ```
     docker-compose -f docker-compose.yaml up -d
     ```
     启动完成后，可查看容器运行状态：
     ```
     docker ps
     ```
     当相关容器状态均为**Up**时，表示SwanLab服务已成功启动。
     
  
  5. 验证服务。服务启动成功后，可通过浏览器访问：
     ```
     http://<ECS公网IP>:8000
     ```
     首次登录，需要输入个人license注册，个人账户的单个license只能拥有一个账号：
     图9SwanLab Dashboard   
     ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749542206.png) 
  
  6. 修改训练代码。完成SwanLab服务部署后，需要在训练代码中接入SwanLab SDK，使训练任务能够将实验指标上传至ECS中部署的SwanLab服务。
  
  
  ![](https://support.huaweicloud.com/bestpractice-modelarts/public_sys-resources/note_3.0-zh-cn.png)
  训练镜像准备、依赖安装、代码上传、OBS 挂载及训练启动脚本配置，可参考前文训练任务配置步骤，本节不再重复展开。
  **配置SwanLab服务地址**
  本实践中，训练容器通过ECS的私有IP访问SwanLab服务，因此需要在训练代码中指定SwanLab服务地址和API Key。
  ```
  SWANLAB_API_HOST = "http://<ECS私有IP>:8000"
  SWANLAB_API_KEY = "<Your SwanLab API Key>"
  ```
  其中：
  ● \<ECS私有IP\>：部署SwanLab服务的ECS私有IP。
  ● \<Your SwanLab API Key\>：在SwanLab页面中获取的API Key。
  为避免在代码中明文写入API Key，实际使用时建议通过环境变量或启动脚本传入。
  图10设置API Key   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002778981285.png)
  ● **SWANLAB_API_KEY**：用于身份认证，SDK通过该API Key登录并将实验数据上传至SwanLab服务。
  ● **SWANLAB_API_HOST**：指定SwanLab服务的API地址，SDK通过该地址与部署在ECS上的SwanLab服务进行通信推荐配置为ECS私有IP，训练容器可通过VPC私有网络上传实验数据。
  ● **SWANLAB_WEB_HOST**：指定SwanLab Web页面访问地址，用于生成实验链接及页面跳转。推荐配置为ECS 弹性公网IP（EIP），便于用户在本地浏览器直接访问实验管理页面。
  **接入SwanLab SDK**
  完成环境变量配置后，无需在训练代码中显式调用swanlab.login()，SDK会自动读取环境变量中的认证信息并连接部署在ECS上的SwanLab 服务。训练代码可直接参考前文 **"集成SwanLab SDK"** 章节中的示例，仅需保证调用swanlab.init()、swanlab.log()和swanlab.finish()完成实验初始化、指标记录及实验结束即可。
  **提交训练任务**
  完成代码修改后，按照前文训练任务提交方式创建自定义训练任务即可。
  本实践中，训练容器通过ECS的私有ip访问SwanLab服务，因此需确保训练任务运行时能够访问：
  ```
  http://<ECS私有IP>:8000
  ```
  浏览器前往 http://\<ECS公网IP\>:8000 查看训练过程中的参数：
  图11查看swanlab数据   
  ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749542212.png)
  
  **部署 WandB 服务**
  部署WandB服务步骤如下：
  1. ECS环境要求，同**SwanLab部署方案**。
  
  2. 获取WandB镜像。WandB本地部署主要依赖wandb/local镜像。 如果ECS可以访问Docker Hub，可直接拉取镜像：
     ```
     docker pull wandb/local:latest
     ```
     当前WandB Local官方Docker镜像仅支持x86_64（AMD64）架构，暂不支持ARM64架构。因此部署WandB Local服务时，建议选择x86架构的ECS。
     如果 ECS 无法访问Docker Hub，可参考**SwanLab离线镜像导入方案**，先在可访问公网的环境中拉取镜像并导出：
     ```
     docker pull wandb/local:latest
     docker save wandb/local:latest -o wandb-local.tar
     ```
     若导出的镜像文件较大，可参考**SwanLab离线镜像导入方案** 对镜像进行拆分、上传、合并后再导入ECS。
     拆分镜像：
     ```
     split -b 500M wandb-local.tar wandb-local.tar.
     ```
     在ECS上合并镜像：
     ```
     cat wandb-local.tar.* > wandb-local.tar
     ```
     导入镜像：
     ```
     docker load -i wandb-local.tar
     ```
     
  
  3. 启动WandB服务。 镜像导入完成后，执行以下命令启动WandB Local服务：
     ```
     docker run -d \
       --name wandb-local \
       -p 8080:8080 \
       wandb/local:latest
     ```
     启动完成后，可通过以下命令查看容器状态：
     ```
     docker ps
     ```
     若容器状态显示为**Up**，则表示WandB服务已成功启动。
     
  
  4. 访问服务。WandB默认使用**8080** 端口提供 Web 服务，可通过浏览器访问：
     ```
     http://<ECS公网IP>:8080
     ```
     访问前需确保：
     ● ECS已绑定弹性公网IP（EIP）。
     ● ECS安全组已放通**8080**端口。
     ● 操作系统防火墙已允许**8080**端口访问（如启用了防火墙）。
     完成以上配置后，即可通过浏览器访问WandB管理页面。
     图12访问WandB   
     ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749702096.png) 
  
  5. 训练代码设计。WandB 的训练代码集成方式与前文SwanLab基本一致，包括SDK安装、训练代码上传、启动脚本配置以及ModelArts训练任务创建等操作，可直接参考SwanLab训练代码设计，本节仅介绍WandB的差异配置。 为避免在代码中明文写入API Key，建议通过环境变量或启动脚本传入认证信息。WandB SDK启动后会自动读取相关环境变量完成认证，无需在代码中显式调用wandb.login()。其中：
     ● **WANDB_API_KEY**：用于身份认证，SDK通过该API Key登录部署在ECS上的WandB服务。
     ● **WANDB_BASE_URL**：指定WandB服务地址，SDK通过该地址连接部署在ECS上的WandB服务。推荐配置为ECS私有IP，训练容器可通过VPC私有网络上传实验数据。
     ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749702098.png)
     完成环境变量配置后，即可像使用WandB官方云服务一样，在训练过程中记录实验信息和训练指标。
     训练代码运行后，WandB SDK将自动把训练过程中记录的超参数、指标及日志上传至部署在ECS上的WandB服务。训练结束后，可通过浏览器访问http://\<ECS公网IP\>:8080查看实验运行情况、训练曲线及相关日志。
     图13在WandB上查看训练指标   
     ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749702100.png)
     ![](https://support.huaweicloud.com/bestpractice-modelarts/public_sys-resources/note_3.0-zh-cn.png)
     本文示例截图使用**8888** 端口进行部署，这是由于测试环境中**8080** 端口已被其他服务占用。WandB Local默认使用**8080**端口，实际部署时可根据环境情况修改为任意未被占用的端口，同时启动命令、访问地址及训练代码中的服务地址保持一致即可。
     
   
#### 强化学习作业集成SwanLab\&WandB
强化学习平台下发的训练作业集成SwanLab或WandB的整体方式与前文介绍的ModelArts自定义训练基本一致，包括SDK安装、训练代码埋点、服务地址配置以及实验结果查看等流程。
由于强化学习作业运行于新版ModelArts训练平台，其训练代码加载和启动命令配置方式与传统自定义训练存在少量差异。本节主要介绍强化学习作业中的差异配置，SwanLab和WandB的SDK使用方法可参考前文相关章节。
**前置说明**
强化学习作业运行时，可通过自定义镜像预装SDK，也可以在训练启动命令中动态安装SDK。
若使用自定义镜像，可提前将SwanLab或WandB SDK安装到镜像中，并将镜像上传至SWR。创建强化学习作业时选择该镜像，即可直接执行训练代码，无需在任务启动阶段重复安装依赖。
若使用未预装SDK的镜像，可在训练任务启动命令中动态安装相应SDK。例如，安装WandB SDK：
```
python3 -m pip install wandb -i http://<PYPI_MIRROR>/simple/ --trusted-host <PYPI_MIRROR_HOST>
```
安装SwanLab SDK：
```
python3 -m pip install swanlab -i http://<PYPI_MIRROR>/simple/ --trusted-host <PYPI_MIRROR_HOST>
```
其中，\<PYPI_MIRROR\> 表示训练容器能够访问的PyPI镜像源。若训练容器无法访问公网，应使用企业内部或其他可访问的软件源。
**配置训练代码**
强化学习作业主要通过OBS挂载方式，将用户上传的训练代码加载至训练容器。
创建强化学习训练作业时，需要将包含训练代码的OBS路径配置为挂载目录，并指定对应的容器挂载路径。训练任务启动后，可通过Python命令直接执行挂载目录中的训练脚本。
例如：
```
python3 /home/ma-user/modelarts/user-model/code/RL.py
```
实际脚本路径应根据训练作业配置的OBS挂载目录进行调整。
SwanLab或WandB的服务地址、API Key等信息可以通过训练作业环境变量注入训练容器，避免直接写入训练代码。
图14通过环境变量设置API Key   
![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002778981289.png)
**修改训练代码**
强化学习训练代码的SDK接入方式与前文自定义训练基本一致，只需在原有训练逻辑中增加SDK初始化、指标记录和任务结束处理。
以WandB为例，通常需要调用以下接口：
```
wandb.login()
wandb.init()
wandb.log()
wandb.finish()
```
训练过程中，可通过wandb.log()记录Reward、Loss、Episode、Learning Rate、TD Error等指标。
示例初始化代码如下：
```
import os
import time
import math
import random
import wandb
WANDB_BASE_URL = os.getenv("WANDB_BASE_URL")
WANDB_API_KEY = os.getenv("WANDB_API_KEY")
def run_episode(
    episode: int,
    epsilon: float,
    max_steps: int = 50,
) -> tuple[float, int, float]:
    position = 0
    target = 10
    total_reward = 0.0
    td_errors = []
    for step in range(1, max_steps + 1):
        # epsilon-greedy：随机探索或选择朝目标前进
        if random.random() < epsilon:
            action = random.choice([-1, 1])
        else:
            action = 1 if position < target else -1
        old_distance = abs(target - position)
        position += action
        new_distance = abs(target - position)
        if position == target:
            reward = 10.0
            done = True
        elif new_distance < old_distance:
            reward = 0.5
            done = False
        else:
            reward = -1.0
            done = False
        total_reward += reward
        # 模拟 TD Error，用于生成训练 loss
        predicted_value = random.uniform(-0.5, 0.5)
        target_value = reward + 0.95 * random.uniform(-0.5, 0.5)
        td_error = target_value - predicted_value
        td_errors.append(td_error)
        if done:
            loss = sum(error**2 for error in td_errors) / len(td_errors)
            return total_reward, step, loss
    loss = sum(error**2 for error in td_errors) / len(td_errors)
    return total_reward, max_steps, loss
def main() -> None:
    if not WANDB_API_KEY:
        raise RuntimeError()
    # 显式指定自建 W&B 服务
    os.environ["WANDB_BASE_URL"] = WANDB_BASE_URL
    os.environ["WANDB_API_KEY"] = WANDB_API_KEY
    print(f"W&B server: {WANDB_BASE_URL}")
    print("正在登录 W&B 服务……")
    wandb.login(
        key=WANDB_API_KEY,
        host=WANDB_BASE_URL,
        relogin=True,
    )
    run = wandb.init(
        project="modelarts-rl-test",
        name=f"ecs-wandb-test-{int(time.time())}",
        job_type="reinforcement-learning",
        config={
            "algorithm": "epsilon-greedy",
            "environment": "simple-line-world",
            "episodes": 30,
            "max_steps": 50,
            "initial_epsilon": 1.0,
            "minimum_epsilon": 0.05,
            "epsilon_decay": 0.90,
            "discount_factor": 0.95,
            "learning_rate": 0.01,
            "wandb_server": WANDB_BASE_URL,
        },
    )
    epsilon = 1.0
    rewards = []
    try:
        for episode in range(1, run.config.episodes + 1):
            reward, episode_length, loss = run_episode(
                episode=episode,
                epsilon=epsilon,
                max_steps=run.config.max_steps,
            )
            rewards.append(reward)
            average_reward = sum(rewards[-5:]) / min(len(rewards), 5)
            learning_rate = (
                run.config.learning_rate
                * math.exp(-0.02 * episode)
            )
            run.log(
                {
                    "episode": episode,
                    "train/reward": reward,
                    "train/average_reward_5": average_reward,
                    "train/episode_length": episode_length,
                    "train/loss": loss,
                    "train/epsilon": epsilon,
                    "train/learning_rate": learning_rate,
                },
                step=episode,
            )
            print(
                f"episode={episode:02d}, "
                f"reward={reward:6.2f}, "
                f"average_reward={average_reward:6.2f}, "
                f"steps={episode_length:02d}, "
                f"loss={loss:.4f}, "
                f"epsilon={epsilon:.4f}"
            )
            epsilon = max(
                run.config.minimum_epsilon,
                epsilon * run.config.epsilon_decay,
            )
            time.sleep(0.2)
        run.summary["final_reward"] = rewards[-1]
        run.summary["best_reward"] = max(rewards)
        run.summary["average_reward"] = sum(rewards) / len(rewards)
        run.summary["training_status"] = "success"
        print("强化学习模拟训练完成，指标已发送到 W&B。")
    except Exception:
        run.summary["training_status"] = "failed"
        raise
    finally:
        run.finish()
if __name__ == "__main__":
    main()
```
使用SwanLab时，可在训练代码中调用对应接口：
```
swanlab.login()
swanlab.init()
swanlab.log()
swanlab.finish()
```
具体初始化参数、服务地址配置及指标记录方式可参考前文SwanLab相关章节。
**查看实验结果**
强化学习作业的实验结果查看方式与自定义训练一致，可根据使用场景选择离线查看或实时监控。
**离线查看**
训练过程中，将SwanLab或WandB生成的实验文件保存至训练任务配置的OBS输出挂载目录。训练结束后，实验文件将同步至对应OBS路径。
图15设置OBS路径   
![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002779141141.png)
用户可将实验文件下载至本地，并通过SwanLab或WandB提供的本地工具查看和分析实验结果。具体配置方式可参考前文实验文件导出与本地查看章节。
**实时监控**
若在ECS上部署SwanLab或WandB服务，并在训练代码中配置对应的服务地址和API Key，训练过程中的实验数据可实时上传至ECS上部署的服务。
用户可通过Web页面查看训练任务状态、实验指标变化以及不同训练任务之间的对比结果。
使用实时监控模式时，应确保训练容器能够正常访问ECS服务。
网络配置说明
若采用ECS部署SwanLab或WandB服务进行实时监控，建议强化学习作业使用专属资源池运行。
同时，应确保专属资源池与ECS之间网络互通，可采用以下方式：
● 专属资源池与ECS使用同一个VPC。
● 专属资源池与ECS位于不同VPC，并在两个VPC之间建立对等连接，同时配置相应路由和安全组规则。
还需要在ECS安全组中放通SwanLab或WandB服务使用的端口，并确保训练容器能够访问对应的服务地址。
网络连通配置方式与前文自定义训练实时监控方案一致，此处不再重复介绍。
**验证结果**
强化学习平台接入SwanLab或WandB的基本原理与ModelArts自定义训练一致。
完成SDK安装、OBS代码挂载、环境变量配置和网络连通配置后，强化学习作业即可记录Reward、Loss、Episode、Learning Rate等训练指标，并支持指标可视化、历史实验管理和多次实验对比。
图16查看强化学习指标   
![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002749542204.png)
本节以WandB为例展示强化学习作业的接入方式。SwanLab的整体使用流程与WandB基本一致，具体接口和配置方式可参考前文SwanLab相关章节。
