斗地主AI部署实战:从零把DouZero训练、评估到真正能上场
很多刚接触强化学习的同学都会经历这样一个时刻:好不容易把项目克隆下来、train.py 跑起来了,屏幕开始刷日志,然后……然后呢?这个模型到底训练成什么样了?怎么判断它打得厉不厉害?怎么把它拿出去跟别的AI对局,甚至放进自己的应用里?
这篇文章就是冲着这些问题来的。我们会以 DouZero 斗地主AI部署实战 为主线,不按官方文档的线性步骤照搬,而是以"你会在实际动手时遇到什么问题"为线索,把环境安装、训练配置、预训练模型、评估验证、部署使用这些环节串起来。哪怕你完全不了解强化学习,跟着走一遍,也能让这个 ICML 2021 论文里的斗地主AI真正跑起来。
DouZero 是快手 AI 平台开源的斗地主强化学习框架,它用"深度蒙特卡洛 + 自我博弈"的思路,让AI从零开始反复和自己对局练级——就像一个人天天找高手打牌,越打越强。四块GPU、几天训练,就能在 Botzone 的 344 个AI中登顶,实力是经得起检验的。
卡在装环境这关?两步搞定依赖
新手上路的第一道坎,往往不是算法,而是环境。项目本身很轻量,Python 3.6 以上就能跑,核心依赖集中在 requirements.txt 里(主要是 PyTorch 和 rlcard)。
git clone https://gitcode.com/gh_mirrors/do/DouZero
cd DouZero
pip3 install -r requirements.txt
如果你不想动源码、只打算调用稳定版本,也可以直接装发布包。国内网络环境下建议配合 -i 参数走清华镜像源,速度会快很多。
有一点要提前知道:训练代码是给 GPU 设计的,想自己训练模型,得先装好 CUDA。但如果只是做评估验证,CPU 完全够用,后面我们会讲到。
训练时GPU怎么分配?一张图想清楚四个参数
DouZero 的自我博弈训练分两类角色:一批"演员"进程负责模拟打牌、产出数据,一个"学习者"负责拿这些数据更新网络。所以训练命令的核心,就是把 GPU 合理分给这两拨人。
打开 train.py,真正干活的是 douzero/dmc/ 下的实现。它暴露了四个关键参数:
--gpu_devices:系统能看到哪些GPU;--num_actor_devices:其中几块卡专门跑自我博弈模拟;--num_actors:每块模拟卡上起多少个演员进程;--training_device:哪块卡负责模型训练。
假设你有4块GPU,想让前3块各跑15个演员进程做模拟、第4块专职训练,一条命令就够:
python3 train.py --gpu_devices 0,1,2,3 --num_actor_devices 3 --num_actors 15 --training_device 3
如果手头只有一块显卡,直接 python3 train.py 也能跑,默认配置就是单卡训练。至于 --num_actors、--batch_size、--learning_rate 这些超参数,全部在 douzero/dmc/arguments.py 里定义,想调参时去那里翻注释最直观。
小贴士:参数别贪多。演员进程开太多,GPU显存吃紧反而拖慢整体节奏,建议根据自己的卡逐步加。
没有GPU、或者只有Windows?照跑不误
这是新手问得最多的问题之一。Windows 下因为多进程操作 CUDA 张量受限,GPU 模拟这条路走不通,但项目早就给 CPU 留好了后路:
python3 train.py --actor_device_cpu --training_device cpu
这一条命令让演员和学习者全跑在 CPU 上。代价是速度慢不少,胜在"能跑"。同样的思路也适用于 Linux 上临时没有空闲 GPU 的场景——只需要把演员放 CPU,python3 train.py --actor_device_cpu 即可。
不想从零训练?现成模型直接拿来评估
从头训练动辄几天,很多人其实只是想先看看效果。项目提供了几种预训练模型,下载后放进 baselines/ 目录即可:
baselines/sl/:基于人类牌局数据预训练的深度智能体;baselines/douzero_ADP/:以平均分差(ADP)为目标训练出的 DouZero 模型;baselines/douzero_WP/:以胜率(WP)为目标的 DouZero 模型。
除了这些深度模型,评估时还可以用两个内置基线:random(纯随机出牌)和 rlcard(RLCard 的规则智能体)。它们的实现分别在 douzero/evaluation/random_agent.py 和 douzero/evaluation/rlcard_agent.py。
怎么证明模型强不强?走一遍标准评估流程
评估的思路很朴素:让要验证的模型固定坐在某个位置,对手换成随机或规则AI,在大量牌局里统计输赢。DouZero 的评估要分两步走。
第一步,先生成一批对局数据。 牌局由 generate_eval_data.py 随机发牌,默认生成 10000 局:
python3 generate_eval_data.py --num_games 10000
生成结果默认存成 eval_data.pkl。用 --output 可以改名字,比如 --output my_eval 就会得到 my_eval.pkl。
第二步,跑评估脚本。 三个位置参数分别指定地主、地主上家、地主下家的出牌方,可以填模型路径,也可以填 random 或 rlcard:
python3 evaluate.py --landlord baselines/douzero_ADP/landlord.ckpt --landlord_up random --landlord_down random
上面这条让 ADP 模型当地主,对手是两个随机AI。想测它当农民的协作能力,就把农民位置换成模型权重:
python3 evaluate.py --landlord rlcard --landlord_up baselines/douzero_ADP/landlord_up.ckpt --landlord_down baselines/douzero_ADP/landlord_down.ckpt
如果机器有多核,--num_workers 可以开多个子进程并行加速;显存宽裕时也可以 --gpu_device 0 指定 GPU。评估调度逻辑在 douzero/evaluation/simulation.py,想要更精细的控制可以从这里入手。
训练中断了别慌:检查点机制帮你"续命"
长时间训练最怕意外中断。好在 DouZero 默认每30分钟就把模型检查点存到 douzero_checkpoints/douzero/ 下,地主、上家、下家三个位置的权重分开保存。
要找最新的一批权重,不用自己翻文件名,项目自带一个小脚本:
sh get_most_recent.sh douzero_checkpoints/douzero/
它会自动挑出最新的一份,复制到 most_recent_model/ 目录下,方便你直接拿去评估。这几个行为参数(保存间隔、保存目录、实验名)都定义在 douzero/dmc/arguments.py 里:
--xpid:实验标识,默认douzero;--save_interval:保存间隔(分钟);--savedir:检查点根目录;--load_model:加载已有模型继续训练;--disable_checkpoint:关掉自动保存(一般不推荐)。
训练时盯着点仪表盘:胜率、得分、损失都在这里
训练不是盲目的。douzero/dmc/file_writer.py 负责把训练过程中的关键指标写进日志,包括三个位置各自的平均回合收益(也就是胜率趋势)、平均分差和损失收敛情况。你可以通过日志观察模型是不是越打越好、有没有过拟合的苗头。
想改目标函数的话注意一个参数:--objective,可选项是 adp、wp、logadp,默认 adp。不同目标对"什么叫打得好"的定义不同,这也是调优的重要旋钮之一。
想深入研究代码?沿着这三条线走
如果你不满足于跑通,想理解这个AI到底怎么工作的,推荐按下面三条线读源码:
- 算法核心:
douzero/dmc/dmc.py是深度蒙特卡洛算法的主干,训练循环、损失计算、并行调度都在这里; - 网络结构:
douzero/dmc/models.py定义了三个位置共用的神经网络模型; - 环境与工具:
douzero/dmc/env_utils.py负责把牌局状态转成张量,douzero/dmc/utils.py里有并行演员的实现。
顺着这三条线读下来,你会发现 DouZero 的设计其实很"朴素"——没有花哨的注意力机制,靠的是把经典的蒙特卡洛方法和动作编码、并行演员这些工程技巧用好。这本身也是论文想传达的观点。
除了打牌,这套东西还能用在哪儿?
DouZero 的价值不止于斗地主本身:
- 游戏AI开发:给它套一层接口,就能当作斗地主游戏里的智能机器人对手;
- 强化学习教学:斗地主兼具信息不完全、大状态空间、多人协作对抗等特点,是讲解RL的绝佳案例,配合自我博弈的类比非常直观;
- 算法研究基准:论文的公开基线(random、rlcard、SL、ADP、WP)为后续研究者提供了横向对比的参照系。
常见问题速查
Q:训练和评估哪个必须用GPU? A:只有训练必须GPU(Windows下连训练也只能走CPU),评估可以纯CPU跑,只是慢一些。
Q:下载的预训练权重放哪? A:放进 baselines/ 对应的子目录,比如 baselines/douzero_ADP/,文件名要和 evaluate.py 默认值保持一致。
Q:训练日志刷太快,怎么确认在正常进步? A:看 mean_episode_return 系列指标,配合 file_writer.py 输出的胜率趋势判断,而不是只看损失数字。
Q:--objective 选 adp 还是 wp? A:adp(平均分差)让模型更追求大比分赢,wp(胜率)只在意最终谁赢。一般场景先用默认的 adp 即可。
下一步,就现在
回头看,DouZero 的整条链路其实很顺:装依赖 → 定GPU策略 → 训练或直接用预训练模型 → 生成数据做评估 → 拿着权重接入你的场景。每一步都有对应的脚本和清晰的日志,不需要先啃懂强化学习理论也能跑通。
行动建议很直接:先把预训练模型跑一场评估,亲眼看看AI的出牌,再决定要不要投入算力从零训练。从"能跑"到"能上场",差的只是一次动手。去试试吧。🎯
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



