大模型推理 - FasterTransformer调试技巧
Contents
FasterTransformer(FT)有三难,一个kernel算子理解难,一个是对精度麻烦,再一个就是调试难,今天讲一下FasterTransformer调试的技巧。
如何编译DEBUG版本
DEBUG版本很有用,gdb调试时会有更多信息。但FT 通过CMake -DCMAKE_BUILD_TYPE=DEBUG
编译DEBUG版本会报错,可以采用如下方式,修改CMakeLists.txt:
|
|
用cmake -DCMAKE_BUILD_TYPE=Release -DFT_BUILD_DEBUG=1
即可编译DEBUG版本。
如何定位莫名其妙的Cuda错误
假如发生如下类似报错:
|
|
此时通过日志是无法定位的,通过gdb调试看到的调用栈往往也发现不了问题所在,这是因为FT里面的Cuda kernel大部分是异步的,程序的报错已经不是第一次现场, FT内部实现了一个syncAndCheck
函数用于等待cuda kernel调用并检测错误,在调用kernel后跟一个syncAndCheck,可以第一时间发现错误。
Release版本默认syncAndCheck是不打卡的,可以通过FT_DEBUG_LEVEL=DEBUG
打开。
效果如下:
|
|
这样我们就可以确定问题的大概位置,然后检查相关代码定位问题。
如何定位kernel内部显存问题
通过syncAndCheck能找到出问题的kernel函数,但在kernel实现复杂的情况下,还是会一筹莫展。比如有一个kernel函数有十几个buf参数,实现也很复杂,如何知道哪一行的问题呢?此时就需要用到compute-sanitizer了。
首先修改CMakeLists.txt, 让nvcc编译行号:
|
|
然后通过compute-sanitizer启动你的程序:
|
|
compute-sanitizer会将结果输出到终端:
|
|
上面的结果中有3个关键信息:
- 代码行号。 如上面的paged_attention_kernels.cu的第162行
- 异常类型。 write错误 out of bounds.
- 调用栈。
根据这些信息可以精准的定位Bug原因。
常见问题
- NCCL卡住
多卡触发,卡越多概率越大,表现为1. 通过nvidia-smi查看多卡中某些卡的util占用为0,其余为100%,但功率都很低 2. 通过gdb调试会发现阻塞在cudaMallocHost, cublasGemmStridedBatchedEx等Cuda函数
解决方法:export NCCL_LAUNCH_MODE=GROUP
- 启动报错: Caught signal 7 (Bus error: nonexistent physical address)
原因是系统资源分配不足, 容器启动添加--shm-size=10g
即可解决。
License 知识共享署名 3.0 中国大陆许可协议