后羿计划技术报告——如何在Apex Legends中打赢一场智能化战争

后羿计划技术报告——如何在Apex Legends中打赢一场智能化战争

后羿(HOUYI) 定位于通用电子射击游戏瞄准辅助程序,目前支持的游戏是Apex Legends(以下简称apex)。其运行框架由识别-追踪二阶段构成,具体来说,先用目标检测算法识别出屏幕中敌人,再自动计算并校正准星位置。HOUYI的使命是用计算机技术对抗电子射击游戏对人的异化。

在己无居,形物自著。其动若水,其静若镜,其应若响。

——《庄子·天下》

形物自著

以YOLO为代表的深度学习算法性能优异,部署流程也非常成熟,是当前计算机视觉领域目标检测任务中的主流方法。后羿使用百度飞浆框架训练检测模型,使用微软ONNXRT与Nvidia的TensorRT部署模型。

数据理解

apex中的目标检测难度主要在于

  • Apex中角色多、皮肤多、光效复杂
  • 敌我识别难度大
  • 远处目标(>30m)在画面中像素数量很少,属于小目标检测问题
  • 需要主流显卡在游戏负载下还能实时推理

屏幕中心区域示例

目标区域

数据采集与标注

整体数据链路 HOUYI使用人工标注的约13k样本作为初始数据集,训练出初版模型后投入生产,采集在线真实样本扩充数据集,端云协同进化。

数据采集策略 HOUYI针对不同状态(腰射/开镜射击/开镜瞄准)下的屏幕图像实现了实时均匀采样策略,减少不同状态下的信息损失,尽可能使训练集数据分布利于训练&与实战一致。

模式 采样区域 采样比例 压缩方式
腰射 1080x1080 1/100 无损
开镜射击 640x640 1/100 无损
开镜瞄准 640x640 1/500 无损

特征一致性 HOUYI凭借两点确保在线/离线特征一致性:

  • 部署&采集一体。实战时,每次模型推理前有小概率缓存图片,在session结束后上传至服务器。另外每次准星校正记录也会上传,作为控制算法研发的参考资料。
  • 无损压缩格式。使用png作为图片格式确保逐像素一致。

自动化标注 HOUYI使用参数最多,精度最高的离线模型预标注在线采集的样本,由人工检查与微调后加入训练集。

目标检测算法

PP-YOLOE+ HOUYI主要使用PP-YOLOE+作为在线推理模型。PP-YOLOE+是基于PP-YOLOv2的卓越的单阶段Anchor-free模型,精度-fps超越了多种流行的YOLO模型。不仅如此,PP-YOLOE+仅需80个epoch即可收敛,相比常见的300epoch大幅减少了训练时间与成本。

模型 Epoch AP0.5:0.95 AP0.5 AP0.75 APsmall APmedium APlarge ARsmall ARmedium ARlarge
PP-YOLOE+_s 80 43.7 60.6 47.9 26.5 47.5 59.0 46.7 71.4 81.7
PP-YOLOE+_m 80 49.8 67.1 54.5 31.8 53.9 66.2 53.3 75.0 84.6
PP-YOLOE+_l 80 52.9 70.1 57.9 35.2 57.5 69.1 56.0 77.9 86.9
PP-YOLOE+_x 80 54.7 72.0 59.9 37.9 59.3 70.4 57.0 78.7 87.2

检测效果示例


其动若水

在屏幕中目标被成功识别后,另一步就是把准星拖上去——这一步骤其实十分困难——玩家的操作、枪支后坐力以及敌人的不规则运动都会带来控制误差。此外,由于服务器、推理、操作延迟,如果只是简单地向目标移动,可能只是不断追逐敌人曾经所在的位置。仅仅通过优化程序性能无法彻底解决这一问题,因此需要设计控制算法来达到更好的用户体验。

PID

闭环控制根据控制对象输出反馈来进行误差校正。我们可以把移动准星也视作闭环控制问题:当前准星位置为原点,t时刻敌人坐标即是误差\(e(t)\)。如当前敌人位置是(100,200),那么最naive的想法是鼠标需要移动(100,200)。但这样的瞬移策略首先很不自然,其次也不能达到最优效果。自然的想法是引入连续系统中技术最成熟、应用最广泛的闭环控制算法PID(proportional–integral–derivative controller)。

$$ u(t)=K_{\mathrm{p}} e(t)+K_{\mathrm{i}} \int_{0}^{t} e(\tau) \mathrm{d} \tau+K_{\mathrm{d}} \frac{\mathrm{d} e(t)}{\mathrm{d} t} $$

其中第一项是比例控制项,第二项是积分控制项,第三项是差分控制项。

第一项非常好理解——误差越大,需要做的调整就越大,但仅使用比例项很快会遇到困难:如果敌人向右匀速移动的速度是10,取\(K_p=0.5\),最终会达到\(e(t)=20, u(t)=10\)的稳态。

这时就需要引入积分项消除稳态误差——例如过去1秒内累计误差是20,取\(K_i=0.25\),此时\(u(t)=20·0.5+20·0.25=15\),超过敌人移动速度,能够减小与敌人距离。引入积分后的控制算法被称为PI控制器。



但是i过小收敛太慢,i过大会导致抖动,收敛更慢。最好的效果是轻微过冲:

最后的差分项主要用于减少控制过程中的震荡,缓解过冲。由于\(\mathrm{d}e(t)\)一般是负数,差分项起到刹车的作用,提前减少拉枪幅度防止拉过头的情况。PID调节到合适时:

应用PID的困难在于

  • 对枪时敌人刻意的不规则移动无法被PID预测,难以补偿
  • 参数调整困难,这也是PID的老大难问题
  • 射击场景不同,需要不同的PID参数

向量自回归比例控制PVAR

如果我说我之所以想去西游,主要是想去女儿国,结果顺道去了趟天竺,你们也一定不会相信吧?

——《西游日记》

当我在谈论自瞄时,其实我想说的是时间序列预测。
一次典型的校正过程中,\(e(t)\)在初期迅速减小至0附近,之后由于后坐力等有原因左右震荡。以下图标展示了拉枪过程中的时间序列数据,enemy_box和confidence是模型输出的敌人框和置信度,ex、ey是敌人在横纵坐标上与准星的距离,ux、uy是控制器输出的鼠标移动指令。

enemy_box_x1 enemy_box_y1 enemy_box_x2 enemy_box_y2 confidence ex ey ux uy
0 266.21786 304.98212 289.40607 362.9163 0.548098 -42.188035 13.94921 -25.31283 8.369531
1 261.20413 304.77383 285.12802 362.66193 0.705141 -46.833925 13.71788 -29.106307 8.525386
2 273.99313 297.0426 297.64008 360.8898 0.700376 -34.183395 8.9662 -22.454103 5.920422
3 289.20618 288.6216 315.9204 360.6148 0.700991 -17.43671 4.6182 -12.794311 3.41447
4 304.0824 283.4045 331.3549 357.4968 0.622412 -2.28135 0.45065 -3.746427 0.922879
5 311.96606 282.16705 340.17767 357.0965 0.715523 6.071865 -0.368225 1.40623 0.423019
6 313.57156 282.32294 341.7551 357.35828 0.734364 7.66333 -0.15939 2.544032 0.544513
7 313.0578 282.24142 341.4103 357.54837 0.754622 7.23405 -0.105105 2.42217 0.575116
8 311.94815 282.4199 340.3355 356.5956 0.768114 6.141825 -0.49225 2.91703 0.036619
9 311.10672 282.8336 339.47678 356.11987 0.770691 5.29175 -0.523265 2.516004 0.007234
10 309.4765 282.83307 337.44662 356.76465 0.778666 3.46156 -0.20114 2.424042 -0.049513
11 305.26862 290.59354 332.79498 361.52643 0.760621 -0.9682 6.059985 0.129709 3.759036
12 303.50372 291.24722 333.49023 363.27325 0.66165 -1.503025 7.260235 -0.325249 4.665564

在实测的数千次拉枪记录中,\(e_x\) 与 \(e_y\) 序列中位数通过了单位根平稳性检验ADFULLER(p<0.0002)。因此HOUYI不仅对当前\(e_t\)做出校正,还使用向量自回归模型(VAR, Vector autoregression)预测\(\hat e_{t+1}\)。

在向量自回归过程的视角下,

$$ e_{t}=c+A_{1} e_{t-1}+A_{2} e_{t-2}+\cdots+A_{p} e_{t-p} $$

引入先验知识调整模型:
  • 当前误差与上次移动指令 \(U_{t-1}\) 有线性关系,因此引入新自变量
  • 误差中不存在常数项

最终HOUYI使用的模型是

$$ e_{t}=A_{1} e_{t-1}+A_{2} e_{t-2}+\cdots+A_{p} e_{t-p} +A_u U_{t-1} $$

VAR与比例控制器最终构成了HOUYI主要的控制算法PVAR。

其应若响

性能优化是HOUYI最重要,也是工作量最大的部分,低延迟高吞吐的图像处理是最终效果的基石。

屏幕捕捉 获取屏幕截图的方法有很多,但其中效率最高的是DXGI,使用GPU直接处理纹理,截图速度几乎只和显卡渲染速度有关。在此基础上,HOUYI针对性地优化了局部截图的内存效率:只读取部分区域的数据,只对目标区域做数据类型转换。

预处理 预处理中的性能杀手依然是访存效率。HOUYI优化了所有不必要的内存复制,在显存中开辟固定区域存放模型输入,借此将每秒校正次数提升约一倍。

推理引擎 将模型导出至onnx后使用来自英伟达的黑科技TensorRT

The core of NVIDIA® TensorRT™ is a C++ library that facilitates high-performance inference on NVIDIA graphics processing units (GPUs). TensorRT takes a trained network, which consists of a network definition and a set of trained parameters, and produces a highly optimized runtime engine that performs inference for that network. TensorRT provides API’s via C++ and Python that help to express deep learning models via the Network Definition API or load a pre-defined model via the parsers that allow TensorRT to optimize and run them on an NVIDIA GPU. TensorRT applies graph optimizations, layer fusion, among other optimizations, while also finding the fastest implementation of that model leveraging a diverse collection of highly optimized kernels. TensorRT also supplies a runtime that you can use to execute this network on all of NVIDIA’s GPU’s from the Kepler generation onwards. TensorRT also includes optional high speed mixed precision capabilities introduced in the Tegra™ X1, and extended with the Pascal™, Volta™, Turing™, and NVIDIA® Ampere GPU architectures.

值得一提的是,tensorRT对不同GPU做针对性的优化,因此首次启动时需要大约15分钟重新部署模型,在该应用场景下影响可以忽略不计。

后记

如果你希望借助外挂获取随意秒杀其他玩家的快感,请勿使用后羿;

如果你不认可借助外力突破人类极限的做法,请勿使用后羿;

如果你觉得在对相同数据输入的处理上,利用算法和算力超越人类极限很cool,渴望用计算机技术对抗电子射击游戏对人的异化,那么愿后羿计划助你打赢一场智能化战争。


参考资料

  1. PID控制算法原理(抛弃公式,从本质上真正理解PID控制)
  2. 看完,你也是PID调参大神!

后羿计划技术报告——如何在Apex Legends中打赢一场智能化战争

https://heth.ink/houyi/

作者

YK

发布于

2022-10-03

更新于

2022-10-15

许可协议