Merged
bsa接口文档及示例修复 #13293
Xu-XuePengAdd on Sep 30
bsa接口文档及示例修复 #13293
Merged
Total: 10 files changed+72-72
| @@ -165,7 +165,7 @@ KV方向: ceil(1024/128)=8块 [0, 1, 2, 3, 4, 5, 6, 7] | |||
| 165 | 3. blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 | 165 | 3. blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 |
| 166 | 4. qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 | 166 | 4. qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 |
| 167 | 5. blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 | 167 | 5. blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 |
| 168 | -6. attentionMaskOptional当前只支持传入nullptr。 | 168 | +6. attenMaskOptional当前只支持传入nullptr。 |
| 169 | 7. maskType当前只支持输入0,表示不加mask。 | 169 | 7. maskType当前只支持输入0,表示不加mask。 |
| 170 | 8. actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 | 170 | 8. actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 |
| 171 | 9. 当前不支持PagedAttention,blockTableOptional当前只支持传入nullptr。 | 171 | 9. 当前不支持PagedAttention,blockTableOptional当前只支持传入nullptr。 |
Mattention/block_sparse_attention/docs/aclnnBlockSparseAttention.md+2-2File content is under review, please try again later
| @@ -604,11 +604,11 @@ aclnnStatus aclnnBlockSparseAttentionV2( | |||
| 604 | - query、key、value的D轴当前仅支持配置为64或128 | 604 | - query、key、value的D轴当前仅支持配置为64或128 |
| 605 | - blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 | 605 | - blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 |
| 606 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 | 606 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 |
| 607 | -- attentionMaskOptional当前只支持传入nullptr。 | 607 | +- attenMaskOptional当前只支持传入nullptr。 |
| 608 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 | 608 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 |
| 609 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 | 609 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 |
| 610 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 | 610 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 |
| 611 | -- innerPrecise仅支持配置4,表示混合精度运算,在性能与精度上取得一个折中。 | 611 | +- innerPrecise必须为0或1或4,其中,<term>Ascend 950PR/Ascend 950DT</term>仅支持配置为4,<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>仅支持配置为0或1。 |
| 612 | - softmaxLseFlag仅支持配置0或1,分别表示不开启/开启softmaxLse输出。 | 612 | - softmaxLseFlag仅支持配置0或1,分别表示不开启/开启softmaxLse输出。 |
| 613 | - qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 | 613 | - qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 |
| 614 | - 输入query的headNum为N1,输入key和value的headNum为N2,则N1 >= N2 && N1 % N2 == 0。 | 614 | - 输入query的headNum为N1,输入key和value的headNum为N2,则N1 >= N2 && N1 % N2 == 0。 |
| @@ -781,7 +781,7 @@ void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor | |||
| 781 | aclrtFree(workspaceAddr); | 781 | aclrtFree(workspaceAddr); |
| 782 | } | 782 | } |
| 783 | 783 | ||
| 784 | - aclrtDestroyStream(stream); | 784 | + aclrtDestroyStream(*stream); |
| 785 | aclrtResetDevice(deviceId); | 785 | aclrtResetDevice(deviceId); |
| 786 | aclFinalize(); | 786 | aclFinalize(); |
| 787 | } | 787 | } |
| @@ -671,7 +671,7 @@ aclnnStatus aclnnBlockSparseAttentionV3( | |||
| 671 | - 在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上:blockShapeY须为128的倍数。 | 671 | - 在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上:blockShapeY须为128的倍数。 |
| 672 | <!-- end id8 --> | 672 | <!-- end id8 --> |
| 673 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 | 673 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 |
| 674 | -- attentionMaskOptional当前只支持传入nullptr。 | 674 | +- attenMaskOptional当前只支持传入nullptr。 |
| 675 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 | 675 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 |
| 676 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 | 676 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 |
| 677 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 | 677 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 |
| @@ -893,7 +893,7 @@ void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor | |||
| 893 | aclrtFree(workspaceAddr); | 893 | aclrtFree(workspaceAddr); |
| 894 | } | 894 | } |
| 895 | 895 | ||
| 896 | - aclrtDestroyStream(stream); | 896 | + aclrtDestroyStream(*stream); |
| 897 | aclrtResetDevice(deviceId); | 897 | aclrtResetDevice(deviceId); |
| 898 | aclFinalize(); | 898 | aclFinalize(); |
| 899 | } | 899 | } |
| @@ -37,7 +37,7 @@ using namespace std; | |||
| 37 | printf(message, ##__VA_ARGS__); \ | 37 | printf(message, ##__VA_ARGS__); \ |
| 38 | } while (0) | 38 | } while (0) |
| 39 | 39 | ||
| 40 | -int64_t GetShapeSize(const std::vector<int64_t> &shape) | 40 | +int64_t GetShapeSize(const std::vector<int64_t>& shape) |
| 41 | { | 41 | { |
| 42 | int64_t shapeSize = 1; | 42 | int64_t shapeSize = 1; |
| 43 | for (auto i : shape) { | 43 | for (auto i : shape) { |
| @@ -46,7 +46,7 @@ int64_t GetShapeSize(const std::vector<int64_t> &shape) | |||
| 46 | return shapeSize; | 46 | return shapeSize; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | -int Init(int32_t deviceId, aclrtStream *stream) | 49 | +int Init(int32_t deviceId, aclrtStream* stream) |
| 50 | { | 50 | { |
| 51 | // 固定写法,资源初始化 | 51 | // 固定写法,资源初始化 |
| 52 | auto ret = aclInit(nullptr); | 52 | auto ret = aclInit(nullptr); |
| @@ -59,8 +59,8 @@ int Init(int32_t deviceId, aclrtStream *stream) | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | template <typename T> | 61 | template <typename T> |
| 62 | -int CreateAclTensor(const std::vector<T> &hostData, const std::vector<int64_t> &shape, void **deviceAddr, | 62 | +int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, |
| 63 | - aclDataType dataType, aclTensor **tensor) | 63 | + aclDataType dataType, aclTensor** tensor) |
| 64 | { | 64 | { |
| 65 | // 检查shape是否有效 | 65 | // 检查shape是否有效 |
| 66 | if (shape.empty()) { | 66 | if (shape.empty()) { |
| @@ -108,11 +108,11 @@ int CreateAclTensor(const std::vector<T> &hostData, const std::vector<int64_t> & | |||
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | -void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor *blockSparseMask, | 111 | +void FreeResource(aclTensor* query, aclTensor* key, aclTensor* value, aclTensor* blockSparseMask, |
| 112 | - aclTensor *attentionOut, aclIntArray *actualSeqLengths, aclIntArray *actualSeqLengthsKv, | 112 | + aclTensor* attentionOut, aclIntArray* actualSeqLengths, aclIntArray* actualSeqLengthsKv, |
| 113 | - aclIntArray *blockShape, void *queryDeviceAddr, void *keyDeviceAddr, void *valueDeviceAddr, | 113 | + aclIntArray* blockShape, void* queryDeviceAddr, void* keyDeviceAddr, void* valueDeviceAddr, |
| 114 | - void *blockSparseMaskDeviceAddr, void *attentionOutDeviceAddr, void *workspaceAddr, int32_t deviceId, | 114 | + void* blockSparseMaskDeviceAddr, void* attentionOutDeviceAddr, void* workspaceAddr, int32_t deviceId, |
| 115 | - aclrtStream *stream) | 115 | + aclrtStream* stream) |
| 116 | { | 116 | { |
| 117 | // 释放资源 | 117 | // 释放资源 |
| 118 | if (query) { | 118 | if (query) { |
| @@ -159,7 +159,7 @@ void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor | |||
| 159 | aclrtFree(workspaceAddr); | 159 | aclrtFree(workspaceAddr); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | - aclrtDestroyStream(stream); | 162 | + aclrtDestroyStream(*stream); |
| 163 | aclrtResetDevice(deviceId); | 163 | aclrtResetDevice(deviceId); |
| 164 | aclFinalize(); | 164 | aclFinalize(); |
| 165 | } | 165 | } |
| @@ -173,7 +173,7 @@ int main() | |||
| 173 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | 173 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); |
| 174 | 174 | ||
| 175 | // 2. 设置参数 | 175 | // 2. 设置参数 |
| 176 | - const char *socName = aclrtGetSocName(); | 176 | + const char* socName = aclrtGetSocName(); |
| 177 | std::string socVersion = (socName != nullptr) ? std::string(socName) : std::string(); | 177 | std::string socVersion = (socName != nullptr) ? std::string(socName) : std::string(); |
| 178 | bool isArch22 = socVersion.find("Ascend910") != std::string::npos; | 178 | bool isArch22 = socVersion.find("Ascend910") != std::string::npos; |
| 179 | int64_t innerPrecise = isArch22 ? 0 : 4; | 179 | int64_t innerPrecise = isArch22 ? 0 : 4; |
| @@ -193,21 +193,21 @@ int main() | |||
| 193 | int32_t qBlockNum = (qSeqlen + blockShapeX - 1) / blockShapeX; // Q块的X维度数量 | 193 | int32_t qBlockNum = (qSeqlen + blockShapeX - 1) / blockShapeX; // Q块的X维度数量 |
| 194 | int32_t kvBlockNum = (kvSeqlen + blockShapeY - 1) / blockShapeY; // KV块的Y维度数量 | 194 | int32_t kvBlockNum = (kvSeqlen + blockShapeY - 1) / blockShapeY; // KV块的Y维度数量 |
| 195 | 195 | ||
| 196 | - aclTensor *queryTensor = nullptr; | 196 | + aclTensor* queryTensor = nullptr; |
| 197 | - aclTensor *keyTensor = nullptr; | 197 | + aclTensor* keyTensor = nullptr; |
| 198 | - aclTensor *valueTensor = nullptr; | 198 | + aclTensor* valueTensor = nullptr; |
| 199 | - aclTensor *blockSparseMaskTensor = nullptr; | 199 | + aclTensor* blockSparseMaskTensor = nullptr; |
| 200 | - aclTensor *attentionOutTensor = nullptr; | 200 | + aclTensor* attentionOutTensor = nullptr; |
| 201 | - aclIntArray *actualSeqLengths = nullptr; | 201 | + aclIntArray* actualSeqLengths = nullptr; |
| 202 | - aclIntArray *actualSeqLengthsKv = nullptr; | 202 | + aclIntArray* actualSeqLengthsKv = nullptr; |
| 203 | - aclIntArray *blockShape = nullptr; | 203 | + aclIntArray* blockShape = nullptr; |
| 204 | 204 | ||
| 205 | - void *queryDeviceAddr = nullptr; | 205 | + void* queryDeviceAddr = nullptr; |
| 206 | - void *keyDeviceAddr = nullptr; | 206 | + void* keyDeviceAddr = nullptr; |
| 207 | - void *valueDeviceAddr = nullptr; | 207 | + void* valueDeviceAddr = nullptr; |
| 208 | - void *blockSparseMaskDeviceAddr = nullptr; | 208 | + void* blockSparseMaskDeviceAddr = nullptr; |
| 209 | - void *attentionOutDeviceAddr = nullptr; | 209 | + void* attentionOutDeviceAddr = nullptr; |
| 210 | - void *workspaceAddr = nullptr; | 210 | + void* workspaceAddr = nullptr; |
| 211 | 211 | ||
| 212 | // 3. 创建Query tensor (TND format: [totalQTokens, numHeads, headDim]) | 212 | // 3. 创建Query tensor (TND format: [totalQTokens, numHeads, headDim]) |
| 213 | std::vector<int64_t> queryShape = {totalQTokens, numHeads, headDim}; | 213 | std::vector<int64_t> queryShape = {totalQTokens, numHeads, headDim}; |
| @@ -282,8 +282,8 @@ int main() | |||
| 282 | return -1); | 282 | return -1); |
| 283 | 283 | ||
| 284 | // 9. 准备字符串参数(确保缓冲区大小足够,包含null terminator) | 284 | // 9. 准备字符串参数(确保缓冲区大小足够,包含null terminator) |
| 285 | - const char *qLayoutStr = "TND"; | 285 | + const char* qLayoutStr = "TND"; |
| 286 | - const char *kvLayoutStr = "TND"; | 286 | + const char* kvLayoutStr = "TND"; |
| 287 | char qLayoutBuffer[16] = {0}; | 287 | char qLayoutBuffer[16] = {0}; |
| 288 | char kvLayoutBuffer[16] = {0}; | 288 | char kvLayoutBuffer[16] = {0}; |
| 289 | strncpy(qLayoutBuffer, qLayoutStr, sizeof(qLayoutBuffer) - 1); | 289 | strncpy(qLayoutBuffer, qLayoutStr, sizeof(qLayoutBuffer) - 1); |
| @@ -294,7 +294,7 @@ int main() | |||
| 294 | 294 | ||
| 295 | // 11. 调用第一段接口 | 295 | // 11. 调用第一段接口 |
| 296 | uint64_t workspaceSize = 0; | 296 | uint64_t workspaceSize = 0; |
| 297 | - aclOpExecutor *executor = nullptr; | 297 | + aclOpExecutor* executor = nullptr; |
| 298 | 298 | ||
| 299 | ret = aclnnBlockSparseAttentionGetWorkspaceSize(queryTensor, // query | 299 | ret = aclnnBlockSparseAttentionGetWorkspaceSize(queryTensor, // query |
| 300 | keyTensor, // key | 300 | keyTensor, // key |
| @@ -159,7 +159,7 @@ KV方向: ceil(1024/128)=8块 [0, 1, 2, 3, 4, 5, 6, 7] | |||
| 159 | 3. blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 | 159 | 3. blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 |
| 160 | 4. qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 | 160 | 4. qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 |
| 161 | 5. blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 | 161 | 5. blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 |
| 162 | -6. attentionMaskOptional当前只支持传入nullptr。 | 162 | +6. attenMaskOptional当前只支持传入nullptr。 |
| 163 | 7. maskType当前只支持输入0,表示不加mask。 | 163 | 7. maskType当前只支持输入0,表示不加mask。 |
| 164 | 8. actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 | 164 | 8. actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 |
| 165 | 9. 当前不支持PagedAttention,blockTableOptional当前只支持传入nullptr。 | 165 | 9. 当前不支持PagedAttention,blockTableOptional当前只支持传入nullptr。 |
| @@ -513,7 +513,7 @@ aclnnStatus aclnnBlockSparseAttention( | |||
| 513 | - query、key、value的D轴当前仅支持配置为64或128 | 513 | - query、key、value的D轴当前仅支持配置为64或128 |
| 514 | - blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 | 514 | - blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 |
| 515 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 | 515 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 |
| 516 | -- attentionMaskOptional当前只支持传入nullptr。 | 516 | +- attenMaskOptional当前只支持传入nullptr。 |
| 517 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 | 517 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 |
| 518 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 | 518 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 |
| 519 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 | 519 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 |
| @@ -679,7 +679,7 @@ void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor | |||
| 679 | aclrtFree(workspaceAddr); | 679 | aclrtFree(workspaceAddr); |
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | - aclrtDestroyStream(stream); | 682 | + aclrtDestroyStream(*stream); |
| 683 | aclrtResetDevice(deviceId); | 683 | aclrtResetDevice(deviceId); |
| 684 | aclFinalize(); | 684 | aclFinalize(); |
| 685 | } | 685 | } |
| @@ -604,11 +604,11 @@ aclnnStatus aclnnBlockSparseAttentionV2( | |||
| 604 | - query、key、value的D轴当前仅支持配置为64或128 | 604 | - query、key、value的D轴当前仅支持配置为64或128 |
| 605 | - blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 | 605 | - blockShapeOptional如果传入,则必须包含至少两个元素[blockShapeX, blockShapeY],且值必须大于0,blockShapeY在<term>Ascend 950PR&950DT系列产品</term>上须为16的倍数,在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上须为128的倍数。 |
| 606 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 | 606 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 |
| 607 | -- attentionMaskOptional当前只支持传入nullptr。 | 607 | +- attenMaskOptional当前只支持传入nullptr。 |
| 608 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 | 608 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 |
| 609 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 | 609 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 |
| 610 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 | 610 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 |
| 611 | -- innerPrecise仅支持配置4,表示混合精度运算,在性能与精度上取得一个折中。 | 611 | +- innerPrecise必须为0或1或4,其中,<term>Ascend 950PR/Ascend 950DT</term>仅支持配置为4,<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>仅支持配置为0或1。 |
| 612 | - softmaxLseFlag仅支持配置0或1,分别表示不开启/开启softmaxLse输出。 | 612 | - softmaxLseFlag仅支持配置0或1,分别表示不开启/开启softmaxLse输出。 |
| 613 | - qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 | 613 | - qSeqlen和kvSeqlen不需要被blockShape整除,支持非对齐场景,实际分块数通过向上取整计算。 |
| 614 | - 输入query的headNum为N1,输入key和value的headNum为N2,则N1 >= N2 && N1 % N2 == 0。 | 614 | - 输入query的headNum为N1,输入key和value的headNum为N2,则N1 >= N2 && N1 % N2 == 0。 |
| @@ -781,7 +781,7 @@ void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor | |||
| 781 | aclrtFree(workspaceAddr); | 781 | aclrtFree(workspaceAddr); |
| 782 | } | 782 | } |
| 783 | 783 | ||
| 784 | - aclrtDestroyStream(stream); | 784 | + aclrtDestroyStream(*stream); |
| 785 | aclrtResetDevice(deviceId); | 785 | aclrtResetDevice(deviceId); |
| 786 | aclFinalize(); | 786 | aclFinalize(); |
| 787 | } | 787 | } |
| @@ -670,7 +670,7 @@ aclnnStatus aclnnBlockSparseAttentionV3( | |||
| 670 | - 在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上:blockShapeY须为128的倍数。 | 670 | - 在<term>Atlas A2系列产品</term>、<term>Atlas A3系列产品</term>上:blockShapeY须为128的倍数。 |
| 671 | <!-- end id8 --> | 671 | <!-- end id8 --> |
| 672 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 | 672 | - blockSparseMaskOptional当前必须传入,且shape为[batch, headNum, qBlockNum, kvBlockNum]。TND时,qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。BNSD/BSND时,qBlockNum = ceilDiv(Q shape中的S, blockShapeX),kvBlockNum = ceilDiv(K shape中的S, blockShapeY);若传入actualSeqLengths和actualSeqLengthsKv,也可按实际长度计算:qBlockNum = ceilDiv(max(actualSeqLengths), blockShapeX),kvBlockNum = ceilDiv(max(actualSeqLengthsKv), blockShapeY)。 |
| 673 | -- attentionMaskOptional当前只支持传入nullptr。 | 673 | +- attenMaskOptional当前只支持传入nullptr。 |
| 674 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 | 674 | - actualSeqLengthsOptional在qInputLayout为“TND”时必选;actualSeqLengthsKvOptional在kvInputLayout为“TND”时必选。 |
| 675 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 | 675 | - actualSeqLengthsOptional与actualSeqLengthsKvOptional当前必须同时配置或同时不配置,仅配置其中之一的行为将被算子拦截。 |
| 676 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 | 676 | - blockTableOptional当前只支持传入nullptr,表示不开启PagedAttention特性。 |
| @@ -877,7 +877,7 @@ void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor | |||
| 877 | aclrtFree(workspaceAddr); | 877 | aclrtFree(workspaceAddr); |
| 878 | } | 878 | } |
| 879 | 879 | ||
| 880 | - aclrtDestroyStream(stream); | 880 | + aclrtDestroyStream(*stream); |
| 881 | aclrtResetDevice(deviceId); | 881 | aclrtResetDevice(deviceId); |
| 882 | aclFinalize(); | 882 | aclFinalize(); |
| 883 | } | 883 | } |
| @@ -37,7 +37,7 @@ using namespace std; | |||
| 37 | printf(message, ##__VA_ARGS__); \ | 37 | printf(message, ##__VA_ARGS__); \ |
| 38 | } while (0) | 38 | } while (0) |
| 39 | 39 | ||
| 40 | -int64_t GetShapeSize(const std::vector<int64_t> &shape) | 40 | +int64_t GetShapeSize(const std::vector<int64_t>& shape) |
| 41 | { | 41 | { |
| 42 | int64_t shapeSize = 1; | 42 | int64_t shapeSize = 1; |
| 43 | for (auto i : shape) { | 43 | for (auto i : shape) { |
| @@ -46,7 +46,7 @@ int64_t GetShapeSize(const std::vector<int64_t> &shape) | |||
| 46 | return shapeSize; | 46 | return shapeSize; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | -int Init(int32_t deviceId, aclrtStream *stream) | 49 | +int Init(int32_t deviceId, aclrtStream* stream) |
| 50 | { | 50 | { |
| 51 | // 固定写法,资源初始化 | 51 | // 固定写法,资源初始化 |
| 52 | auto ret = aclInit(nullptr); | 52 | auto ret = aclInit(nullptr); |
| @@ -59,8 +59,8 @@ int Init(int32_t deviceId, aclrtStream *stream) | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | template <typename T> | 61 | template <typename T> |
| 62 | -int CreateAclTensor(const std::vector<T> &hostData, const std::vector<int64_t> &shape, void **deviceAddr, | 62 | +int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, |
| 63 | - aclDataType dataType, aclTensor **tensor) | 63 | + aclDataType dataType, aclTensor** tensor) |
| 64 | { | 64 | { |
| 65 | // 检查shape是否有效 | 65 | // 检查shape是否有效 |
| 66 | if (shape.empty()) { | 66 | if (shape.empty()) { |
| @@ -108,11 +108,11 @@ int CreateAclTensor(const std::vector<T> &hostData, const std::vector<int64_t> & | |||
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | -void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor *blockSparseMask, | 111 | +void FreeResource(aclTensor* query, aclTensor* key, aclTensor* value, aclTensor* blockSparseMask, |
| 112 | - aclTensor *attentionOut, aclIntArray *actualSeqLengths, aclIntArray *actualSeqLengthsKv, | 112 | + aclTensor* attentionOut, aclIntArray* actualSeqLengths, aclIntArray* actualSeqLengthsKv, |
| 113 | - aclIntArray *blockShape, void *queryDeviceAddr, void *keyDeviceAddr, void *valueDeviceAddr, | 113 | + aclIntArray* blockShape, void* queryDeviceAddr, void* keyDeviceAddr, void* valueDeviceAddr, |
| 114 | - void *blockSparseMaskDeviceAddr, void *attentionOutDeviceAddr, void *workspaceAddr, int32_t deviceId, | 114 | + void* blockSparseMaskDeviceAddr, void* attentionOutDeviceAddr, void* workspaceAddr, int32_t deviceId, |
| 115 | - aclrtStream *stream) | 115 | + aclrtStream* stream) |
| 116 | { | 116 | { |
| 117 | // 释放资源 | 117 | // 释放资源 |
| 118 | if (query) { | 118 | if (query) { |
| @@ -159,7 +159,7 @@ void FreeResource(aclTensor *query, aclTensor *key, aclTensor *value, aclTensor | |||
| 159 | aclrtFree(workspaceAddr); | 159 | aclrtFree(workspaceAddr); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | - aclrtDestroyStream(stream); | 162 | + aclrtDestroyStream(*stream); |
| 163 | aclrtResetDevice(deviceId); | 163 | aclrtResetDevice(deviceId); |
| 164 | aclFinalize(); | 164 | aclFinalize(); |
| 165 | } | 165 | } |
| @@ -173,7 +173,7 @@ int main() | |||
| 173 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | 173 | CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); |
| 174 | 174 | ||
| 175 | // 2. 设置参数 | 175 | // 2. 设置参数 |
| 176 | - const char *socName = aclrtGetSocName(); | 176 | + const char* socName = aclrtGetSocName(); |
| 177 | std::string socVersion = (socName != nullptr) ? std::string(socName) : std::string(); | 177 | std::string socVersion = (socName != nullptr) ? std::string(socName) : std::string(); |
| 178 | bool isArch22 = socVersion.find("Ascend910") != std::string::npos; | 178 | bool isArch22 = socVersion.find("Ascend910") != std::string::npos; |
| 179 | int64_t innerPrecise = isArch22 ? 0 : 4; | 179 | int64_t innerPrecise = isArch22 ? 0 : 4; |
| @@ -193,21 +193,21 @@ int main() | |||
| 193 | int32_t qBlockNum = (qSeqlen + blockShapeX - 1) / blockShapeX; // Q块的X维度数量 | 193 | int32_t qBlockNum = (qSeqlen + blockShapeX - 1) / blockShapeX; // Q块的X维度数量 |
| 194 | int32_t kvBlockNum = (kvSeqlen + blockShapeY - 1) / blockShapeY; // KV块的Y维度数量 | 194 | int32_t kvBlockNum = (kvSeqlen + blockShapeY - 1) / blockShapeY; // KV块的Y维度数量 |
| 195 | 195 | ||
| 196 | - aclTensor *queryTensor = nullptr; | 196 | + aclTensor* queryTensor = nullptr; |
| 197 | - aclTensor *keyTensor = nullptr; | 197 | + aclTensor* keyTensor = nullptr; |
| 198 | - aclTensor *valueTensor = nullptr; | 198 | + aclTensor* valueTensor = nullptr; |
| 199 | - aclTensor *blockSparseMaskTensor = nullptr; | 199 | + aclTensor* blockSparseMaskTensor = nullptr; |
| 200 | - aclTensor *attentionOutTensor = nullptr; | 200 | + aclTensor* attentionOutTensor = nullptr; |
| 201 | - aclIntArray *actualSeqLengths = nullptr; | 201 | + aclIntArray* actualSeqLengths = nullptr; |
| 202 | - aclIntArray *actualSeqLengthsKv = nullptr; | 202 | + aclIntArray* actualSeqLengthsKv = nullptr; |
| 203 | - aclIntArray *blockShape = nullptr; | 203 | + aclIntArray* blockShape = nullptr; |
| 204 | 204 | ||
| 205 | - void *queryDeviceAddr = nullptr; | 205 | + void* queryDeviceAddr = nullptr; |
| 206 | - void *keyDeviceAddr = nullptr; | 206 | + void* keyDeviceAddr = nullptr; |
| 207 | - void *valueDeviceAddr = nullptr; | 207 | + void* valueDeviceAddr = nullptr; |
| 208 | - void *blockSparseMaskDeviceAddr = nullptr; | 208 | + void* blockSparseMaskDeviceAddr = nullptr; |
| 209 | - void *attentionOutDeviceAddr = nullptr; | 209 | + void* attentionOutDeviceAddr = nullptr; |
| 210 | - void *workspaceAddr = nullptr; | 210 | + void* workspaceAddr = nullptr; |
| 211 | 211 | ||
| 212 | // 3. 创建Query tensor (TND format: [totalQTokens, numHeads, headDim]) | 212 | // 3. 创建Query tensor (TND format: [totalQTokens, numHeads, headDim]) |
| 213 | std::vector<int64_t> queryShape = {totalQTokens, numHeads, headDim}; | 213 | std::vector<int64_t> queryShape = {totalQTokens, numHeads, headDim}; |
| @@ -282,8 +282,8 @@ int main() | |||
| 282 | return -1); | 282 | return -1); |
| 283 | 283 | ||
| 284 | // 9. 准备字符串参数(确保缓冲区大小足够,包含null terminator) | 284 | // 9. 准备字符串参数(确保缓冲区大小足够,包含null terminator) |
| 285 | - const char *qLayoutStr = "TND"; | 285 | + const char* qLayoutStr = "TND"; |
| 286 | - const char *kvLayoutStr = "TND"; | 286 | + const char* kvLayoutStr = "TND"; |
| 287 | char qLayoutBuffer[16] = {0}; | 287 | char qLayoutBuffer[16] = {0}; |
| 288 | char kvLayoutBuffer[16] = {0}; | 288 | char kvLayoutBuffer[16] = {0}; |
| 289 | strncpy(qLayoutBuffer, qLayoutStr, sizeof(qLayoutBuffer) - 1); | 289 | strncpy(qLayoutBuffer, qLayoutStr, sizeof(qLayoutBuffer) - 1); |
| @@ -294,7 +294,7 @@ int main() | |||
| 294 | 294 | ||
| 295 | // 11. 调用第一段接口 | 295 | // 11. 调用第一段接口 |
| 296 | uint64_t workspaceSize = 0; | 296 | uint64_t workspaceSize = 0; |
| 297 | - aclOpExecutor *executor = nullptr; | 297 | + aclOpExecutor* executor = nullptr; |
| 298 | 298 | ||
| 299 | ret = aclnnBlockSparseAttentionGetWorkspaceSize(queryTensor, // query | 299 | ret = aclnnBlockSparseAttentionGetWorkspaceSize(queryTensor, // query |
| 300 | keyTensor, // key | 300 | keyTensor, // key |