跳到主要内容
AI教程

Ultimate SFighterAI 教程:用 PPO 训练能通关《街头霸王 2》的智能体

本教程介绍如何配置 Ultimate SFighterAI,运行预训练 NatureCNN 模型、评估连续通关能力、使用 PPO 重新训练或续训,并通过 TensorBoard 分析训练曲线。

Ultimate SFighterAI 教程:用 PPO 训练能通关《街头霸王 2》的智能体

项目简介

Ultimate SFighterAI 是一个面向《街头霸王 2:冠军特别版》的深度强化学习项目。它使用隆作为玩家角色,通过 PPO 算法训练 NatureCNN 模型,并将训练范围扩展到全部 12 个街机关卡。

模型的决策输入完全来自游戏画面的 RGB 像素,不直接读取角色位置、动作状态或血量。训练环境仅使用内存变量中的 agent_hp 和 enemy_hp 计算奖励并判断胜负。

项目已经提供训练完成的模型权重和训练记录,因此你既可以直接观看 AI 对战,也可以复现实验、调整并行规模,或者在已有模型的基础上继续训练。

核心功能与实现特点

  • 覆盖全部 12 关:每个关卡可在独立模拟器中运行,并共同训练同一个 NatureCNN 模型。
  • 纯视觉决策:模型根据处理后的游戏画面选择移动、攻击和特殊招式。
  • 27 个离散动作:包括中立、移动、普通攻击、蹲攻击,以及面向左右方向的波动拳、旋风腿和升龙拳等动作。
  • PPO 强化学习:项目基于 Stable-Baselines3 的 PPO 算法进行训练。
  • 多种评估模式:支持逐关加载存档测试、三局两胜、单次 KO 评估和从第一关开始连续闯关。
  • 预训练模型:默认权重位于 logs/trained_models/ppo_ryu.zip。
  • 训练可视化:可使用 TensorBoard 查看奖励变化与模型更新记录。
  • 多设备支持:训练和推理参数支持 auto、cpu、cuda 和 mps。

画面预处理

原始游戏画面会经过居中裁剪、运动前景提取和缩放,最终形成 84×84×3 的模型输入。运动前景提取使用 t-16、t-8 和 t 三个时刻的灰度差分,将背景亮度乘以 0.35,再组合 R、G、B 三个通道。这种处理有助于模型感知角色移动与攻击。

奖励机制

奖励主要由双方血量变化、击倒结果和时间成本组成。伤害奖励的计算方式为:

0.01 × (3 × 对手掉血 − 自己掉血)

击倒对手时的奖励为:

0.01 × (176 + 自己剩余血量)

自己被击倒时的惩罚为:

0.01 × (176 + 对手剩余血量)

此外,每次实际执行动作都会扣除时间惩罚,默认值为 0.0005。

项目目录说明

  • data/:保存 12 个关卡开局存档、游戏内存变量定义和场景配置。
  • main/train.py:负责全关卡并行训练和续训。
  • main/test.py:负责逐关测试和连续闯关评估。
  • main/env_utils.py:处理 ROM 配置与环境构建。
  • main/custom_wrappers.py:实现画面处理、动作映射和奖励计算。
  • logs/trained_models/ppo_ryu.zip:项目提供的训练完成模型。
  • logs/:包含训练过程的 TensorBoard 记录。
  • requirements.txt:Python 依赖列表。

安装与环境配置

第一步:准备 Python 环境

项目建议使用 Python 3.10。README 中记录的验证环境为 macOS、Apple Silicon 和 Python 3.10.20,同时验证了 CPU 与 Apple MPS 路径。其他平台应参考 Stable-Retro 和 PyTorch 的官方安装说明。

在项目根目录创建并激活虚拟环境,然后安装依赖:

python3.10 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

Windows 用户可使用以下命令激活虚拟环境:

.venv\Scripts\activate

也可以使用 Anaconda 创建 Python 3.10 环境,再安装 requirements.txt 中的依赖。项目主要依赖 Gymnasium、Stable-Retro 和 Stable-Baselines3。

第二步:准备游戏 ROM

Stable-Retro 不提供游戏 ROM,本项目也不包含 ROM。请通过合法途径获得《街头霸王 2:冠军特别版》美版的受支持 ROM。

取得 ROM 后,可以通过环境变量提供其绝对路径。在 macOS 或 Linux 中执行:

export SF2_ROM_PATH="/absolute/path/to/your/rom.md"

Windows PowerShell 使用:

$env:SF2_ROM_PATH = "C:\path\to\your\rom.md"

另一种方式是将 ROM 放到项目中的默认位置:

data/street-fighter-ii-special-champion-edition-usa.md

训练与测试程序会自动导入 ROM。如果当前 Python 环境的 Stable-Retro 已经导入该 ROM,则可以直接运行。

第三步:确认关卡数据

data/ 目录中的 12 个 .state 文件分别保存第 1 至第 12 关的开局状态。data.json 和 scenario_full_frame.json 定义游戏内存变量与场景配置。程序会直接读取这些文件,不需要将它们复制到 Stable-Retro 的安装目录。

运行预训练模型

逐关测试全部 12 关

完成环境配置后,在项目根目录执行:

python -m main.test --episodes 1

程序会依次加载第 1 至第 12 关的开局存档,每关默认采用三局两胜。--episodes 1 表示完整评估一轮;如果省略该参数,默认测试 10 轮。

某一关失败后,程序仍会继续测试后续关卡。终端将输出各关胜负、奖励、关卡胜率,以及一轮评估中 12 关全部获胜的比例。

关闭画面以专注评估结果

如果不需要观看对局,可以关闭渲染,并明确使用 CPU 推理:

python -m main.test --episodes 1 --no-render --device cpu

关闭渲染适合批量评估,可减少显示带来的额外开销。

从第一关连续闯关

若要观察 AI 按游戏自身流程挑战下一位对手,可运行:

python -m main.test --episodes 1 --no-load-level-saves

该模式只在开局加载第一关存档,之后由游戏正常推进关卡;一旦失败,本次尝试就会结束。程序会输出已经挑战关卡的胜率和完整通关率。

逐关测试中的“全部获胜”表示模型在 12 个独立关卡存档下均通过评估;“完整通关率”则要求模型在一次连续流程中打通全部 12 关,两者含义不同。

常用测试参数

  • --model-path PATH:指定 PPO 模型,默认为 logs/trained_models/ppo_ryu.zip。
  • --episodes N:设置逐关评估遍数或连续闯关尝试次数,默认值为 10。
  • --no-render:关闭游戏画面。
  • --no-load-level-saves:不逐关加载存档,改为从第一关连续挑战。
  • --reset-round:在逐关测试中以单次 KO 为评估单位,而不是默认的三局两胜。
  • --device auto/cpu/cuda/mps:选择模型推理设备,默认值为 auto。
  • --speed N:通过减少显示帧数加快可视化,默认值为 4。

训练自己的模型

从小规模配置开始

默认训练配置的资源需求非常高。首次运行时,建议每关只启动一个模拟器,并使用较小的批次:

python -m main.train --envs-per-level 1 --batch-size 256 --log-dir runs/ryu

由于项目包含 12 个关卡,--envs-per-level 1 意味着总共运行 12 个并行模拟器。先确认 ROM、环境构建、设备和日志输出都正常,再逐步增加并行数量。

理解默认训练规模

直接运行 python -m main.train 时,每关默认启动 64 个模拟器,总计 768 个并行环境。配合默认的 n-steps=128,一次 PPO 更新会收集 98,304 个样本,完整训练目标为 7 亿步。

默认配置需要充足的 CPU 和内存,不适合作为普通电脑上的首次测试。应根据实际硬件降低 --envs-per-level、--batch-size 或总训练步数。

常用训练参数

  • --envs-per-level N:每个关卡的并行环境数量;未指定时为每关 64 个。
  • --total-timesteps N:本次训练总步数;续训时表示追加步数,默认值为 700000000。
  • --n-steps N:每个模拟器在一次更新前采集的步数,默认值为 128。
  • --batch-size N:PPO 更新批次大小,默认值为 8192。
  • --n-epochs N:每批采样数据的训练轮数,默认值为 3。
  • --learning-rate N:学习率,默认值为 0.0002。
  • --device auto/cpu/cuda/mps:选择训练设备,默认值为 mps。
  • --log-dir PATH:模型与训练曲线输出目录,默认为 logs/ALL_MOTION_SIMULTANEOUS。

基于预训练权重继续训练

项目支持从提供的 PPO 权重开始续训。下面的命令追加训练 100 万步,并把结果写入新目录:

python -m main.train \
  --resume-model logs/trained_models/ppo_ryu.zip \
  --envs-per-level 1 --batch-size 256 \
  --total-timesteps 1000000 --log-dir runs/ryu-resume

续训时,--total-timesteps 表示本次额外执行的训练步数,而不是包含旧模型训练量的累计目标。

使用 TensorBoard 查看训练曲线

项目自带训练记录。启动 TensorBoard:

tensorboard --logdir=logs

随后在浏览器打开 http://localhost:6006/,即可查看奖励变化和模型更新相关曲线。

如果要查看自己训练产生的日志,只需替换目录:

tensorboard --logdir=runs/ryu

进阶使用建议

  1. 先验证再扩容:先使用每关一个环境完成短时间训练,确认 ROM 导入、存档读取和日志写入无误后,再增加并行模拟器数量。
  2. 根据平台指定设备:Apple Silicon 可尝试 mps,具备兼容 NVIDIA GPU 的环境可选择 cuda,否则使用 cpu 或 auto。README 验证的是 macOS Apple Silicon 环境,其他平台需结合 PyTorch 与 Stable-Retro 的要求配置。
  3. 区分两类评估:逐关存档测试适合分析各对手表现,连续闯关更接近完整游戏流程。报告结果时应注明使用的模式。
  4. 使用无渲染批量评估:进行多轮统计时加入 --no-render,观看策略表现时再启用画面。
  5. 用独立目录保存实验:通过 --log-dir 为不同参数组合创建目录,避免训练记录相互覆盖,并方便在 TensorBoard 中比较。
  6. 查看完整命令选项:训练与测试脚本均提供帮助信息。
python -m main.train --help
python -m main.test --help

除了模块方式,项目也支持直接执行脚本:

python main/train.py
python main/test.py

结语

Ultimate SFighterAI 展示了如何把像素输入、动作映射、奖励塑形、PPO 和多关卡并行环境组合成完整的格斗游戏智能体。最稳妥的上手路径是先配置 ROM 并运行预训练模型,再以低并行度复现训练,最后通过续训、设备选择和 TensorBoard 分析逐步扩展实验规模。

项目基于 Apache License 2.0 发布,并使用 Gymnasium、Stable-Retro 与 Stable-Baselines3 等开源组件。