Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.
AddLora 的 y_slice_size 默认值、tiling 参数校验和 kernel 实际写回范围存在不一致,可能导致以下问题:
AddLora
y_slice_size
-1
uint32_t
4294967295
y_offset
yOffset_ > H3_
y_offset == H3_
H2_ <= H3_
y_offset + H2_ <= H3_
y_offset + y_slice_size <= H3_
y_offset + H2Offset
y
可以通过以下两个最小场景复现或验证问题。
y_slice_size = -1
y.shape
[1, 16]
x.shape
weightB.shape
[1, 1, 16, 16]
weightA.shape
indices.shape
[1]
0
// math/add_lora/op_host/add_lora_def.cpp this->Attr("y_slice_size").AttrType(OPTIONAL).Int(-1); // math/add_lora/op_graph/add_lora_proto.h .ATTR(y_slice_size, Int, -1) // math/add_lora/examples/test_geir_add_lora.cpp ADD_INPUT_ATTR(y_slice_size, -1);
// math/add_lora/op_host/add_lora_tiling.cpp ySliceSize_ = static_cast<uint32_t>(*ySliceSizePtr); OP_CHECK_IF(ySliceSize_ > H3_, ...);
ySliceSize_ > H3_
y_offset + H2_ > H3_
H2_
16
H3_
8
// math/add_lora/op_host/add_lora_tiling.cpp OP_CHECK_IF(H2_ > H3_, ...); yOffset_ = static_cast<uint32_t>(*yOffsetPtr); OP_CHECK_IF(yOffset_ > H3_, ...); ySliceSize_ = static_cast<uint32_t>(*ySliceSizePtr); OP_CHECK_IF(ySliceSize_ > H3_, ...);
H2_ = 16, H3_ = 16 => H2_ > H3_ 为 false y_offset = 8, H3_ = 16 => yOffset_ > H3_ 为 false y_slice_size = 16 => ySliceSize_ > H3_ 为 false
因此该参数组合可以通过当前 tiling 校验。
// math/add_lora/op_kernel/add_lora_base.h uint32_t dstOffset = mOffsetBatch.GetValue(mOffset) * y_column + y_offset + nidx * DEFAULT_UB_SPLIT_NUM + nIncoreOffset; // math/add_lora/op_kernel/add_lora_310.h uint32_t dstGmOffset = batchIdxOri * y_column + H2Offset + y_offset;
y_offset = 8
H2_ = 16
写回范围:[8, 24) y 的第二维范围:[0, 16)
因此会超过 y.shape[1] = 16 的边界。
y.shape[1] = 16
H3_ - y_offset
0 <= y_offset < H3_
y[:, y_offset:y_offset + y_slice_size] += ...
H2Offset
int64_t
y_slice_size == -1
y_offset + effective_update_size <= H3_
感谢您的反馈,已安排开发分析对应的问题。
已补充参数校验 https://gitcode.com/cann/ops-math/pull/2973
Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.
一、问题描述
AddLora的y_slice_size默认值、tiling 参数校验和 kernel 实际写回范围存在不一致,可能导致以下问题:y_slice_size在 op 定义和 GE 示例中默认值为-1,但 tiling 中会先将其转换为uint32_t再校验,导致默认值-1被转换为4294967295后判定非法。y_offset当前只校验yOffset_ > H3_,会放过y_offset == H3_。H2_ <= H3_,没有检查y_offset + H2_ <= H3_或y_offset + y_slice_size <= H3_。kernel 写回地址中包含y_offset + H2Offset,因此部分参数组合可能越过y当前行的边界。二、环境信息
三、重现步骤
可以通过以下两个最小场景复现或验证问题。
场景 1:默认
y_slice_size = -1会在 tiling 阶段被误判非法AddLora的最小输入形状:y.shape[1, 16]x.shape[1, 16]weightB.shape[1, 1, 16, 16]weightA.shape[1, 1, 16, 16]indices.shape[1]y_offset0y_slice_size-1// math/add_lora/op_host/add_lora_def.cpp this->Attr("y_slice_size").AttrType(OPTIONAL).Int(-1); // math/add_lora/op_graph/add_lora_proto.h .ATTR(y_slice_size, Int, -1) // math/add_lora/examples/test_geir_add_lora.cpp ADD_INPUT_ATTR(y_slice_size, -1);y_slice_size会被转换为uint32_t:// math/add_lora/op_host/add_lora_tiling.cpp ySliceSize_ = static_cast<uint32_t>(*ySliceSizePtr); OP_CHECK_IF(ySliceSize_ > H3_, ...);-1会变成4294967295,因此ySliceSize_ > H3_成立,默认参数会被判定非法。场景 2:
y_offset + H2_ > H3_的参数组合可能通过 tiling 校验y.shape[1, 16]x.shape[1, 16]weightB.shape[1, 1, 16, 16]weightA.shape[1, 1, 16, 16]indices.shape[1]H2_16H3_16y_offset8y_slice_size16// math/add_lora/op_host/add_lora_tiling.cpp OP_CHECK_IF(H2_ > H3_, ...); yOffset_ = static_cast<uint32_t>(*yOffsetPtr); OP_CHECK_IF(yOffset_ > H3_, ...); ySliceSize_ = static_cast<uint32_t>(*ySliceSizePtr); OP_CHECK_IF(ySliceSize_ > H3_, ...);因此该参数组合可以通过当前 tiling 校验。
y_offset + H2Offset:// math/add_lora/op_kernel/add_lora_base.h uint32_t dstOffset = mOffsetBatch.GetValue(mOffset) * y_column + y_offset + nidx * DEFAULT_UB_SPLIT_NUM + nIncoreOffset; // math/add_lora/op_kernel/add_lora_310.h uint32_t dstGmOffset = batchIdxOri * y_column + H2Offset + y_offset;y_offset = 8开始写H2_ = 16列,即:因此会超过
y.shape[1] = 16的边界。四、预期结果
y_slice_size = -1作为默认值时,应被明确定义并正确处理,例如解析为H2_或H3_ - y_offset,而不是因无符号转换导致非法。y_offset应满足0 <= y_offset < H3_,不应允许y_offset == H3_。y的第二维边界:H2_,应校验y_offset + H2_ <= H3_。y_slice_size写回,则 kernel 写回逻辑也应使用有效的y_slice_size。五、实际结果
y_slice_size = -1会在 tiling 中被转换为uint32_t,导致默认参数不可用。y_offset == H3_当前不会被拒绝。y_offset + H2_ > H3_的参数组合可能通过 tiling 校验,但 kernel 写回地址存在越过当前行边界的风险。y_slice_size被写入 tiling data,但从当前 kernel 写回路径看,写回边界主要由H2_/H2Offset和y_offset决定,接口语义与实现不一致。六、建议修复
int64_t原始 attr 做合法性校验,再转换为uint32_t。y_slice_size == -1的语义,并在 host 侧统一转换成有效写回宽度。y_offset校验调整为0 <= y_offset < H3_。y_offset + effective_update_size <= H3_。y_slice_size = -1y_offset == H3_y_offset + H2_ > H3_y_slice_size与H2_不一致时的预期行为