[SOT] Make custom_op dy&st unified #2733
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR描述
上述生成的
static_op_extract_text_token_output函数实现中,存在对输出结果根据长度进行解包的逻辑:当输出结果为单元素列表时,直接返回该元素,否则返回完整的列表。
这种逻辑导致了动态图与静态图模式下接口返回值类型不一致的问题。
在SOT转静执行过程(包括模拟)中,返回值始终经过上述解包处理;
而在动态图模式下,原始实现直接返回底层C++扩展算子的输出,所以我们做进一步处理:
cc @SigureMo
UPDATE 2025.07.11
记录一下解决BUG的过程,略有曲折,算是一个比较难排查的BUG吧:
开启SOT后报:
我们把 Embedding 的输出打出来看:
发现出现了很多莫名其妙的大数
和动态图对比了一下,本来应该为 -1 的每行第0个位置,变成了这些大数
我们知道,动态图第一列的数据相当于 mask,如果是 -1,说明当前只跑了一条数据,而为何SOT这里就会是一个很大的数呢?
还有个实验现象:开测试脚本为1条的时候,就没问题,开测试脚本为2条的时候,就会出现这个问题,我们起先认为是 slice 的问题
我们打印了 Embedding 的结果,发现第一次进入主循环是正常的,在第二次开始,就会有很多大数出现(但此时没报错)
第一次的输出也就是第二次的输入,这个过程有问题
从自定义算子
update_inputs中找到了给第 0 列赋值的位置:FastDeploy/custom_ops/gpu_ops/update_inputs.cu
Lines 48 to 60 in c08561c
第60行会将
next_tokens数据复制到input_ids_now的第0列,那现在就有两种可能了,要么next_tokens数据有问题,要么就是input_ids_now没被赋值,(看前面随机出现的大数,倾向于这个)如果是没被赋值,看上面的if条件
thread_idx < bsz除非 bsz=1,即使我们传入多条数据,也依旧只会给第一行赋值也就是无论数据多少条,都会只取第一条,那很大概率就是存在没考虑到的 slice 或者 索引操作
这时 @zyfncg 建议开
FLAGS_print_ir打印一下 program 看看,并建议倒着看,可惜开发机环境崩了,没办法展示log了从log中可以很明显的看出,存在一个只取第一个元素的操作,也就是:
FastDeploy/fastdeploy/model_executor/models/ernie4_5_vl/ernie4_5_vl_moe.py
Lines 441 to 448 in f6ffbc3
不对啊,之前和 @xiaoxiaohehe001 一起看过这个自定义算子的 infer_meta:
FastDeploy/custom_ops/gpu_ops/extract_text_token_output.cu
Lines 74 to 83 in f6ffbc3
他明明返回的是一个list啊? 我取0号元素,不就是把Tensor拿出来吗?怎么会是对Tensor做索引操作呢?
FastDeploy 中,动态图走 C++ extension ,静态图选择自定义算子,逻辑如下:
FastDeploy/fastdeploy/import_ops.py
Lines 78 to 81 in f6ffbc3
回到 Github PR Description 开头的自定义算子(静态图用),这里会做一个解包的操作:
return res[0] if len(res)==1 else res,如果返回值列表中只有一个元素,则直接返回该元素而在动态图中由于没有这解包操作,所以需要手动在后面添加一个
[0]的索引操作所以,当跑SOT转静的时候,做了两次取0号元素的,所以会始终出现上述问题
这个PR只是在当前算子体系下加了个补丁,后续应该规范算子,C++层面统一返回 vector,而不是既有
vector<Tensor>又有Tensor感谢 @zyfncg @SigureMo 和我一起排查