已合并
950 aclnnRmsNormQuant #2060
sakya创建于 4月16日
950 aclnnRmsNormQuant #2060
已合并
共 4 个文件变更+347-8
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2024 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -20,6 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | + | ||
| 23 | 24 | ||
| 24 | namespace atb { | 25 | namespace atb { |
| 25 | static const uint32_t IN_TENSOR_COUNT_SIX = 6; | 26 | static const uint32_t IN_TENSOR_COUNT_SIX = 6; |
| @@ -144,6 +145,11 @@ template <> Status CreateOperation(const infer::RmsNormParam &opParam, Operation | |||
| 144 | ATB_LOG(ERROR) << "AddRmsNormAclnnRunner load aclnn functions failed!"; | 145 | ATB_LOG(ERROR) << "AddRmsNormAclnnRunner load aclnn functions failed!"; |
| 145 | return st; | 146 | return st; |
| 146 | } | 147 | } |
| 148 | + st = RmsNormQuantAclnnRunner::LoadAclnnFuncs(); | ||
| 149 | + if (st != NO_ERROR) { | ||
| 150 | + ATB_LOG(ERROR) << "RmsNormQuantAclnnRunner load aclnn functions failed!"; | ||
| 151 | + return st; | ||
| 152 | + } | ||
| 147 | } | 153 | } |
| 148 | 154 | ||
| 149 | ATB_LOG(INFO) << "CreateOperation with RmsNormParam: " << OpParamToJson(opParam); | 155 | ATB_LOG(INFO) << "CreateOperation with RmsNormParam: " << OpParamToJson(opParam); |
| @@ -483,9 +489,15 @@ std::shared_ptr<Runner> RmsNormOperation::CreateRunner(Context &context) const | |||
| 483 | { | 489 | { |
| 484 | (void)context; | 490 | (void)context; |
| 485 | if (Mki::PlatformInfo::Instance().GetPlatformType() == Mki::PlatformType::ASCEND_950) { | 491 | if (Mki::PlatformInfo::Instance().GetPlatformType() == Mki::PlatformType::ASCEND_950) { |
| 486 | - if (param_.layerType == infer::RmsNormParam::RMS_NORM_NORM && param_.normParam.quantType == infer::QUANT_UNQUANT) { | 492 | + if (param_.layerType == infer::RmsNormParam::RMS_NORM_NORM) { |
| 487 | - ATB_LOG(INFO) << GetLogPrefix() << "create RmsNormAclnnRunner"; | 493 | + if (param_.normParam.quantType == infer::QUANT_UNQUANT) { |
| 488 | - return std::make_shared<RmsNormAclnnRunner>(param_); | 494 | + ATB_LOG(INFO) << GetLogPrefix() << "create RmsNormAclnnRunner"; |
| 495 | + return std::make_shared<RmsNormAclnnRunner>(param_); | ||
| 496 | + } | ||
| 497 | + if (param_.normParam.quantType == infer::QUANT_INT8) { | ||
| 498 | + ATB_LOG(INFO) << GetLogPrefix() << "create RmsNormQuantAclnnRunner"; | ||
| 499 | + return std::make_shared<RmsNormQuantAclnnRunner>(param_); | ||
| 500 | + } | ||
| 489 | } | 501 | } |
| 490 | if (param_.layerType == infer::RmsNormParam::RMS_NORM_PRENORM) { | 502 | if (param_.layerType == infer::RmsNormParam::RMS_NORM_PRENORM) { |
| 491 | ATB_LOG(INFO) << GetLogPrefix() << "create AddRmsNormAclnnRunner"; | 503 | ATB_LOG(INFO) << GetLogPrefix() << "create AddRmsNormAclnnRunner"; |
| @@ -0,0 +1,256 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +namespace { | ||
| 19 | +static const int X_ACLNN_TENSOR_IDX = 0; | ||
| 20 | +static const int GAMMA_ACLNN_TENSOR_IDX = 1; | ||
| 21 | +static const int BETA_ACLNN_TENSOR_IDX = 2; | ||
| 22 | +static const int SCALE_ACLNN_TENSOR_IDX = 3; | ||
| 23 | +static const int OFFSET_ACLNN_TENSOR_IDX = 4; | ||
| 24 | +static const int Y_ACLNN_TENSOR_IDX = 0; | ||
| 25 | +} // namespace | ||
| 26 | + | ||
| 27 | +namespace atb { | ||
| 28 | +AclnnRmsNormQuantGetWorkspaceSizeFunc RmsNormQuantAclnnRunner::aclnnRmsNormQuantGetWorkspaceSizeFunc_ = nullptr; | ||
| 29 | +AclnnRmsNormQuantFunc RmsNormQuantAclnnRunner::aclnnRmsNormQuantFunc_ = nullptr; | ||
| 30 | + | ||
| 31 | +RmsNormQuantAclnnRunner::RmsNormQuantAclnnRunner(const infer::RmsNormParam ¶m) | ||
| 32 | + : AclnnRunner("RmsNormQuantAclnnRunner"), param_(param) | ||
| 33 | +{ | ||
| 34 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::RmsNormQuantAclnnRunner"; | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +RmsNormQuantAclnnRunner::~RmsNormQuantAclnnRunner() | ||
| 38 | +{} | ||
| 39 | + | ||
| 40 | +Status RmsNormQuantAclnnRunner::LoadAclnnFuncs() | ||
| 41 | +{ | ||
| 42 | + ATB_LOG(INFO) << "RmsNormQuantAclnnRunner::LoadAclnnFuncs"; | ||
| 43 | + if (aclnnRmsNormQuantGetWorkspaceSizeFunc_ && aclnnRmsNormQuantFunc_) { | ||
| 44 | + return NO_ERROR; | ||
| 45 | + } | ||
| 46 | + return LoadFromSharedObjectFile("aclnnRmsNormQuantGetWorkspaceSize", | ||
| 47 | + "aclnnRmsNormQuant", | ||
| 48 | + aclnnRmsNormQuantGetWorkspaceSizeFunc_, | ||
| 49 | + aclnnRmsNormQuantFunc_); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +Status RmsNormQuantAclnnRunner::BuildAclnnVariantPack(const RunnerVariantPack &runnerVariantPack) | ||
| 53 | +{ | ||
| 54 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::BuildAclnnVariantPack, runnerVariantPack: " | ||
| 55 | + << runnerVariantPack.ToString(); | ||
| 56 | + atbVariantPack_ = runnerVariantPack; | ||
| 57 | + GetTensorNum(); | ||
| 58 | + InitTensorIndex(); | ||
| 59 | + aclnnVariantPack_.aclInTensors.reserve(aclInTensorNum_); | ||
| 60 | + aclnnVariantPack_.aclInTensors.resize(aclInTensorNum_); | ||
| 61 | + aclnnVariantPack_.aclOutTensors.reserve(aclOutTensorNum_); | ||
| 62 | + aclnnVariantPack_.aclOutTensors.resize(aclOutTensorNum_); | ||
| 63 | + Status st = CreateXAclnnTensor(); | ||
| 64 | + if (st != NO_ERROR) { | ||
| 65 | + return st; | ||
| 66 | + } | ||
| 67 | + st = CreateGammaAclnnTensor(); | ||
| 68 | + if (st != NO_ERROR) { | ||
| 69 | + return st; | ||
| 70 | + } | ||
| 71 | + st = CreateBetaAclnnTensor(); | ||
| 72 | + if (st != NO_ERROR) { | ||
| 73 | + return st; | ||
| 74 | + } | ||
| 75 | + st = CreateScaleAclnnTensor(); | ||
| 76 | + if (st != NO_ERROR) { | ||
| 77 | + return st; | ||
| 78 | + } | ||
| 79 | + st = CreateOffsetAclnnTensor(); | ||
| 80 | + if (st != NO_ERROR) { | ||
| 81 | + return st; | ||
| 82 | + } | ||
| 83 | + return CreateYAclnnTensor(); | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +aclnnStatus RmsNormQuantAclnnRunner::SetAclNNWorkspaceExecutor() | ||
| 87 | +{ | ||
| 88 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::SetAclNNWorkspaceExecutor"; | ||
| 89 | + aclTensor *x = aclnnVariantPack_.aclInTensors.at(xAclTensorIndex_)->tensor; | ||
| 90 | + aclTensor *gamma = aclnnVariantPack_.aclInTensors.at(gammaAclTensorIndex_)->tensor; | ||
| 91 | + aclTensor *beta = aclnnVariantPack_.aclInTensors.at(betaAclTensorIndex_)->tensor; | ||
| 92 | + aclTensor *scale = aclnnVariantPack_.aclInTensors.at(scaleAclTensorIndex_)->tensor; | ||
| 93 | + aclTensor *offset = aclnnVariantPack_.aclInTensors.at(offsetAclTensorIndex_)->tensor; | ||
| 94 | + aclTensor *y = aclnnVariantPack_.aclOutTensors.at(yAclTensorIndex_)->tensor; | ||
| 95 | + double epsilon = static_cast<double>(param_.normParam.epsilon); | ||
L | |||
| 96 | + aclOpExecutor *rawExecutorPtr = aclnnExecutor_.get(); | ||
L aclnnExecutor_.get() 被传入 aclnnRmsNormQuantGetWorkspaceSizeFunc_,但在该函数执行前未保证 aclnnExecutor_ 已被初始化或为 null。若 aclnnRmsNormQuantGetWorkspaceSizeFunc_ 内部修改了 executorPtr,而原始值为 nullptr,可能导致未定义行为。 可以先
并在 if (ret == ACLNN_SUCCESS) 后再设置 aclnnExecutor_。 ![]() ![]() | |||
| 97 | + aclnnStatus ret = aclnnRmsNormQuantGetWorkspaceSizeFunc_( | ||
| 98 | + x, gamma, beta, scale, offset, epsilon, y, &(atbVariantPack_.workspaceBufferSize), &rawExecutorPtr); | ||
| 99 | + aclnnExecutor_ = std::shared_ptr<aclOpExecutor>(rawExecutorPtr, [this](aclOpExecutor *ptr) { | ||
| 100 | + if (ptr && executorRepeatable_) { | ||
| 101 | + aclDestroyAclOpExecutor(ptr); | ||
| 102 | + } | ||
| 103 | + }); | ||
| 104 | + if (ret == ACLNN_SUCCESS) { | ||
| 105 | + ATB_LOG(INFO) << GetLogPrefix() << "workspaceSize: " << atbVariantPack_.workspaceBufferSize; | ||
| 106 | + } else { | ||
| 107 | + ATB_LOG(ERROR) << GetLogPrefix() << "SetAclNNWorkspaceExecutor failed, ret: " << ret; | ||
| 108 | + } | ||
| 109 | + return ret; | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +Status RmsNormQuantAclnnRunner::LaunchAclnnKernel() | ||
| 113 | +{ | ||
| 114 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::LaunchAclnnKernel"; | ||
| 115 | + aclrtStream executeStream = GetExecuteStream(atbVariantPack_.context); | ||
| 116 | + aclnnStatus ret = aclnnRmsNormQuantFunc_( | ||
| 117 | + atbVariantPack_.workspaceBuffer, atbVariantPack_.workspaceBufferSize, aclnnExecutor_.get(), executeStream); | ||
| 118 | + if (ret == ACLNN_SUCCESS) { | ||
| 119 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::LaunchAclnnKernel success"; | ||
| 120 | + return NO_ERROR; | ||
| 121 | + } | ||
| 122 | + ATB_LOG(ERROR) << GetLogPrefix() << "RmsNormQuantAclnnRunner::LaunchAclnnKernel failed, ret: " << ret; | ||
| 123 | + return ERROR_CANN_ERROR; | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +void RmsNormQuantAclnnRunner::GetTensorNum() | ||
| 127 | +{ | ||
| 128 | + aclInTensorNum_ = 5; // 5: x, gamma, beta, scale, offset | ||
| 129 | + aclOutTensorNum_ = 1; // 1: y | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +void RmsNormQuantAclnnRunner::InitTensorIndex() | ||
| 133 | +{ | ||
| 134 | + atbInTensorIndex_ = 0; | ||
| 135 | + aclInTensorIndex_ = 0; | ||
| 136 | + atbOutTensorIndex_ = 0; | ||
| 137 | + aclOutTensorIndex_ = 0; | ||
| 138 | + | ||
| 139 | + xAclTensorIndex_ = 0; | ||
| 140 | + gammaAclTensorIndex_ = 0; | ||
| 141 | + betaAclTensorIndex_ = 0; | ||
| 142 | + scaleAclTensorIndex_ = 0; | ||
| 143 | + offsetAclTensorIndex_ = 0; | ||
| 144 | + yAclTensorIndex_ = 0; | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +Status RmsNormQuantAclnnRunner::CreateXAclnnTensor() | ||
| 148 | +{ | ||
| 149 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::CreateXAclnnTensor"; | ||
| 150 | + | ||
| 151 | + Tensor atbTensor = atbVariantPack_.inTensors.at(atbInTensorIndex_++); | ||
| 152 | + SVector<int64_t> strides = GetCopyTensorStride(atbTensor.desc.shape); | ||
L 调用了 GetCopyTensorStride,但未说明其行为是否适用于非连续内存或非标准布局的 tensor。若 tensor 是非连续的(如 stride[0] != 1),可能导致 ACLNN 内部无法正确访问数据。 若 tensor 是通过 atb::Tensor 创建,应确保其是连续的(is_contiguous())。 ![]() ![]() | |||
| 153 | + std::shared_ptr<AclNNTensor> aclnnTensorPtr = | ||
| 154 | + CreateAclnnTensor(atbTensor, X_ACLNN_TENSOR_IDX, atbTensor.desc.shape, strides); | ||
| 155 | + if (!aclnnTensorPtr->tensor) { | ||
| 156 | + ATB_LOG(ERROR) << GetLogPrefix() << "x aclCreateTensor failed"; | ||
| 157 | + return ERROR_INTERNAL_ERROR; | ||
| 158 | + } | ||
| 159 | + aclnnVariantPack_.aclInTensors.at(aclInTensorIndex_) = aclnnTensorPtr; | ||
| 160 | + xAclTensorIndex_ = aclInTensorIndex_++; | ||
| 161 | + return NO_ERROR; | ||
| 162 | +} | ||
| 163 | + | ||
| 164 | +Status RmsNormQuantAclnnRunner::CreateGammaAclnnTensor() | ||
| 165 | +{ | ||
| 166 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::CreateGammaAclnnTensor"; | ||
| 167 | + | ||
| 168 | + Tensor atbTensor = atbVariantPack_.inTensors.at(atbInTensorIndex_++); | ||
| 169 | + Dims viewShape; | ||
| 170 | + viewShape.dimNum = 1; | ||
| 171 | + viewShape.dims[0] = atbTensor.desc.shape.dims[atbTensor.desc.shape.dimNum - 1]; | ||
| 172 | + SVector<int64_t> strides = GetCopyTensorStride(viewShape); | ||
| 173 | + std::shared_ptr<AclNNTensor> aclnnTensorPtr = | ||
| 174 | + CreateAclnnTensor(atbTensor, GAMMA_ACLNN_TENSOR_IDX, viewShape, strides); | ||
| 175 | + if (!aclnnTensorPtr->tensor) { | ||
| 176 | + ATB_LOG(ERROR) << GetLogPrefix() << "gamma aclCreateTensor failed"; | ||
| 177 | + return ERROR_INTERNAL_ERROR; | ||
| 178 | + } | ||
| 179 | + aclnnVariantPack_.aclInTensors.at(aclInTensorIndex_) = aclnnTensorPtr; | ||
| 180 | + gammaAclTensorIndex_ = aclInTensorIndex_++; | ||
| 181 | + return NO_ERROR; | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +Status RmsNormQuantAclnnRunner::CreateBetaAclnnTensor() | ||
| 185 | +{ | ||
| 186 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::CreateBetaAclnnTensor"; | ||
| 187 | + | ||
| 188 | + Tensor atbTensor = atbVariantPack_.inTensors.at(atbInTensorIndex_++); | ||
| 189 | + Dims viewShape; | ||
| 190 | + viewShape.dimNum = 1; | ||
| 191 | + viewShape.dims[0] = atbTensor.desc.shape.dims[atbTensor.desc.shape.dimNum - 1]; | ||
| 192 | + SVector<int64_t> strides = GetCopyTensorStride(viewShape); | ||
| 193 | + std::shared_ptr<AclNNTensor> aclnnTensorPtr = | ||
| 194 | + CreateAclnnTensor(atbTensor, BETA_ACLNN_TENSOR_IDX, viewShape, strides); | ||
| 195 | + if (!aclnnTensorPtr->tensor) { | ||
| 196 | + ATB_LOG(ERROR) << GetLogPrefix() << "beta aclCreateTensor failed"; | ||
| 197 | + return ERROR_INTERNAL_ERROR; | ||
| 198 | + } | ||
| 199 | + aclnnVariantPack_.aclInTensors.at(aclInTensorIndex_) = aclnnTensorPtr; | ||
| 200 | + betaAclTensorIndex_ = aclInTensorIndex_++; | ||
| 201 | + return NO_ERROR; | ||
| 202 | +} | ||
| 203 | + | ||
| 204 | +Status RmsNormQuantAclnnRunner::CreateScaleAclnnTensor() | ||
| 205 | +{ | ||
| 206 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::CreateScaleAclnnTensor"; | ||
| 207 | + | ||
| 208 | + Tensor atbTensor = atbVariantPack_.inTensors.at(atbInTensorIndex_++); | ||
| 209 | + SVector<int64_t> strides = GetCopyTensorStride(atbTensor.desc.shape); | ||
| 210 | + std::shared_ptr<AclNNTensor> aclnnTensorPtr = | ||
| 211 | + CreateAclnnTensor(atbTensor, SCALE_ACLNN_TENSOR_IDX, atbTensor.desc.shape, strides); | ||
| 212 | + if (!aclnnTensorPtr->tensor) { | ||
| 213 | + ATB_LOG(ERROR) << GetLogPrefix() << "scale aclCreateTensor failed"; | ||
| 214 | + return ERROR_INTERNAL_ERROR; | ||
| 215 | + } | ||
| 216 | + aclnnVariantPack_.aclInTensors.at(aclInTensorIndex_) = aclnnTensorPtr; | ||
| 217 | + scaleAclTensorIndex_ = aclInTensorIndex_++; | ||
| 218 | + return NO_ERROR; | ||
| 219 | +} | ||
| 220 | + | ||
| 221 | +Status RmsNormQuantAclnnRunner::CreateOffsetAclnnTensor() | ||
| 222 | +{ | ||
| 223 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::CreateOffsetAclnnTensor"; | ||
| 224 | + | ||
| 225 | + Tensor atbTensor = atbVariantPack_.inTensors.at(atbInTensorIndex_++); | ||
| 226 | + SVector<int64_t> strides = GetCopyTensorStride(atbTensor.desc.shape); | ||
| 227 | + std::shared_ptr<AclNNTensor> aclnnTensorPtr = | ||
| 228 | + CreateAclnnTensor(atbTensor, OFFSET_ACLNN_TENSOR_IDX, atbTensor.desc.shape, strides); | ||
| 229 | + if (!aclnnTensorPtr->tensor) { | ||
| 230 | + ATB_LOG(ERROR) << GetLogPrefix() << "offset aclCreateTensor failed"; | ||
| 231 | + return ERROR_INTERNAL_ERROR; | ||
| 232 | + } | ||
| 233 | + aclnnVariantPack_.aclInTensors.at(aclInTensorIndex_) = aclnnTensorPtr; | ||
| 234 | + offsetAclTensorIndex_ = aclInTensorIndex_++; | ||
| 235 | + return NO_ERROR; | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +Status RmsNormQuantAclnnRunner::CreateYAclnnTensor() | ||
| 239 | +{ | ||
| 240 | + ATB_LOG(INFO) << GetLogPrefix() << "RmsNormQuantAclnnRunner::CreateYAclnnTensor"; | ||
| 241 | + | ||
| 242 | + Tensor atbTensor = atbVariantPack_.outTensors.at(atbOutTensorIndex_++); | ||
| 243 | + SVector<int64_t> strides = GetCopyTensorStride(atbTensor.desc.shape); | ||
| 244 | + std::shared_ptr<AclNNTensor> aclnnTensorPtr = | ||
| 245 | + CreateAclnnTensor(atbTensor, Y_ACLNN_TENSOR_IDX, atbTensor.desc.shape, strides); | ||
| 246 | + if (!aclnnTensorPtr->tensor) { | ||
| 247 | + ATB_LOG(ERROR) << GetLogPrefix() << "y aclCreateTensor failed"; | ||
| 248 | + return ERROR_INTERNAL_ERROR; | ||
| 249 | + } | ||
| 250 | + aclnnVariantPack_.aclOutTensors.at(aclOutTensorIndex_) = aclnnTensorPtr; | ||
| 251 | + yAclTensorIndex_ = aclOutTensorIndex_++; | ||
| 252 | + return NO_ERROR; | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +REG_RUNNER_TYPE(RmsNormQuantAclnnRunner); | ||
L REG_RUNNER_TYPE 宏是否提供失败反馈机制?若注册失败(如重复注册),运行时可能无法调用。 ![]() ![]() | |||
| 256 | +} // namespace atb | ||
| @@ -0,0 +1,65 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +using AclnnRmsNormQuantGetWorkspaceSizeFunc = aclnnStatus (*)(const aclTensor *x, const aclTensor *gamma, | ||
| 16 | + const aclTensor *beta, const aclTensor *scale, const aclTensor *offset, double epsilon, const aclTensor *y, | ||
| 17 | + uint64_t *workspaceSize, aclOpExecutor **executor); | ||
| 18 | +using AclnnRmsNormQuantFunc = aclnnStatus (*)( | ||
| 19 | + void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream); | ||
| 20 | + | ||
| 21 | +namespace atb { | ||
| 22 | +class RmsNormQuantAclnnRunner : public AclnnRunner { | ||
| 23 | +public: | ||
| 24 | + explicit RmsNormQuantAclnnRunner(const infer::RmsNormParam ¶m); | ||
| 25 | + ~RmsNormQuantAclnnRunner() override; | ||
| 26 | + static Status LoadAclnnFuncs(); | ||
| 27 | + | ||
| 28 | +protected: | ||
| 29 | + Status BuildAclnnVariantPack(const RunnerVariantPack &runnerVariantPack) override; | ||
| 30 | + aclnnStatus SetAclNNWorkspaceExecutor() override; | ||
| 31 | + Status LaunchAclnnKernel() override; | ||
| 32 | + | ||
| 33 | +private: | ||
| 34 | + void GetTensorNum(); | ||
| 35 | + void InitTensorIndex(); | ||
| 36 | + Status CreateXAclnnTensor(); | ||
| 37 | + Status CreateGammaAclnnTensor(); | ||
| 38 | + Status CreateBetaAclnnTensor(); | ||
| 39 | + Status CreateScaleAclnnTensor(); | ||
| 40 | + Status CreateOffsetAclnnTensor(); | ||
| 41 | + Status CreateYAclnnTensor(); | ||
| 42 | + | ||
| 43 | +private: | ||
| 44 | + infer::RmsNormParam param_; | ||
| 45 | + | ||
| 46 | + size_t aclInTensorNum_ = 0; | ||
| 47 | + size_t aclOutTensorNum_ = 0; | ||
| 48 | + | ||
| 49 | + size_t atbInTensorIndex_ = 0; | ||
| 50 | + size_t aclInTensorIndex_ = 0; | ||
| 51 | + size_t atbOutTensorIndex_ = 0; | ||
| 52 | + size_t aclOutTensorIndex_ = 0; | ||
| 53 | + | ||
| 54 | + size_t xAclTensorIndex_ = 0; | ||
| 55 | + size_t gammaAclTensorIndex_ = 0; | ||
| 56 | + size_t betaAclTensorIndex_ = 0; | ||
| 57 | + size_t scaleAclTensorIndex_ = 0; | ||
| 58 | + size_t offsetAclTensorIndex_ = 0; | ||
| 59 | + size_t yAclTensorIndex_ = 0; | ||
| 60 | + | ||
| 61 | + static AclnnRmsNormQuantGetWorkspaceSizeFunc aclnnRmsNormQuantGetWorkspaceSizeFunc_; | ||
| 62 | + static AclnnRmsNormQuantFunc aclnnRmsNormQuantFunc_; | ||
| 63 | +}; | ||
| 64 | +} // namespace atb | ||
| 65 | + | ||
| @@ -193,7 +193,13 @@ CaseNum|CaseName |OpName |OpParam | |||
| 193 | 209 |rms_norm_Ascend950_16 |RmsNormOperation|{"layerType": 1, "normParam": {"quantType": 0, "epsilon": 1e-5, "rstd": true}} |2 |float;float |nd;nd |8,16,32;16,32 |2 |float;float |nd;nd |8,16,32;8,1,1 |random;random; |-5,5;-5,5 | | | | | |Ascend950 |I:ERROR_INVALID_PARAM | 193 | 209 |rms_norm_Ascend950_16 |RmsNormOperation|{"layerType": 1, "normParam": {"quantType": 0, "epsilon": 1e-5, "rstd": true}} |2 |float;float |nd;nd |8,16,32;16,32 |2 |float;float |nd;nd |8,16,32;8,1,1 |random;random; |-5,5;-5,5 | | | | | |Ascend950 |I:ERROR_INVALID_PARAM |
| 194 | 210 |rms_norm_Ascend950_17 |RmsNormOperation|{"layerType": 1, "normParam": {"quantType": 0, "epsilon": 1e-5}} |2 |float16;float16 |nd;nd |1,16;1,16 |1 |bf16 |nd |1,16 |random;random |-100,16;-100,16 | | | | | |Ascend950 |S:ERROR_INVALID_TENSOR_INI_MATCH | 194 | 210 |rms_norm_Ascend950_17 |RmsNormOperation|{"layerType": 1, "normParam": {"quantType": 0, "epsilon": 1e-5}} |2 |float16;float16 |nd;nd |1,16;1,16 |1 |bf16 |nd |1,16 |random;random |-100,16;-100,16 | | | | | |Ascend950 |S:ERROR_INVALID_TENSOR_INI_MATCH |
| 195 | 1|950_aclnnRmsNorm_bugfix|RmsNormOperation|{"layerType":1,"normParam":{"quantType":0,"epsilon":1e-05,"rstd":false}}|2|bf16;bf16|nd;nd|40,28,119,23,7,48;1,1,1,1,1,48|1|bf16|nd|40,28,119,23,7,48|random;random|-100,100;-100,100||||||Ascend950|NO_ERROR | 195 | 1|950_aclnnRmsNorm_bugfix|RmsNormOperation|{"layerType":1,"normParam":{"quantType":0,"epsilon":1e-05,"rstd":false}}|2|bf16;bf16|nd;nd|40,28,119,23,7,48;1,1,1,1,1,48|1|bf16|nd|40,28,119,23,7,48|random;random|-100,100;-100,100||||||Ascend950|NO_ERROR |
| 196 | -1|950_aclnnRmsNorm_prenorm_qwen3dense|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|1,5120;1,5120;5120|2|bf16;bf16|nd;nd|1,5120;1,5120|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | 196 | +1|950_aclnnAddRmsNorm_qwen3dense|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|1,5120;1,5120;5120|2|bf16;bf16|nd;nd|1,5120;1,5120|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR |
| 197 | -2|950_aclnnRmsNorm_prenorm_qwen3dense|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|19,5120;19,5120;5120|2|bf16;bf16|nd;nd|19,5120;19,5120|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | 197 | +2|950_aclnnAddRmsNorm_qwen3dense|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|19,5120;19,5120;5120|2|bf16;bf16|nd;nd|19,5120;19,5120|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR |
| 198 | -3|950_aclnnRmsNorm_prenorm_qwen3vl|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|1,2048;1,2048;2048|2|bf16;bf16|nd;nd|1,2048;1,2048|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | 198 | +3|950_aclnnAddRmsNorm_qwen3vl|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|1,2048;1,2048;2048|2|bf16;bf16|nd;nd|1,2048;1,2048|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR |
| 199 | -4|950_aclnnRmsNorm_prenorm_qwen3vl|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|182,2048;182,2048;2048|2|bf16;bf16|nd;nd|182,2048;182,2048|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | 199 | +4|950_aclnnAddRmsNorm_qwen3vl|RmsNormOperation|{"layerType":2,"preNormParam":{"quantType":0,"epsilon":1e-5}}|3|bf16;bf16;bf16|nd;nd;nd|182,2048;182,2048;2048|2|bf16;bf16|nd;nd|182,2048;182,2048|random;random;random|-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR |
| 200 | +1|950_aclnnRmsNormQuant_deepseekR1|RmsNormOperation|{"layerType":1,"normParam":{"quantType":2,"epsilon":1e-5}}|5|bf16;bf16;bf16;bf16;int8|nd;nd;nd;nd;nd|1,1536;1536;1536;1;1|1|int8|nd|1,1536|random;random;random;random;random|-100,100;-100,100;-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | ||
| 201 | +2|950_aclnnRmsNormQuant_deepseekR1|RmsNormOperation|{"layerType":1,"normParam":{"quantType":2,"epsilon":1e-5}}|5|bf16;bf16;bf16;bf16;int8|nd;nd;nd;nd;nd|13,1536;1536;1536;1;1|1|int8|nd|13,1536|random;random;random;random;random|-100,100;-100,100;-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | ||
| 202 | +3|950_aclnnRmsNormQuant_deepseekR1|RmsNormOperation|{"layerType":1,"normParam":{"quantType":2,"epsilon":1e-5}}|5|bf16;bf16;bf16;bf16;int8|nd;nd;nd;nd;nd|1,7168;7168;7168;1;1|1|int8|nd|1,7168|random;random;random;random;random|-100,100;-100,100;-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | ||
| 203 | +4|950_aclnnRmsNormQuant_deepseekR1|RmsNormOperation|{"layerType":1,"normParam":{"quantType":2,"epsilon":1e-5}}|5|bf16;bf16;bf16;bf16;int8|nd;nd;nd;nd;nd|13,7168;7168;7168;1;1|1|int8|nd|13,7168|random;random;random;random;random|-100,100;-100,100;-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | ||
| 204 | +5|950_aclnnRmsNormQuant_deepseekV32|RmsNormOperation|{"layerType":1,"normParam":{"quantType":2,"epsilon":1e-5}}|5|bf16;bf16;bf16;bf16;int8|nd;nd;nd;nd;nd|14,1536;1536;1536;1;1|1|int8|nd|14,1536|random;random;random;random;random|-100,100;-100,100;-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | ||
| 205 | +6|950_aclnnRmsNormQuant_deepseekV32|RmsNormOperation|{"layerType":1,"normParam":{"quantType":2,"epsilon":1e-5}}|5|bf16;bf16;bf16;bf16;int8|nd;nd;nd;nd;nd|14,7168;7168;7168;1;1|1|int8|nd|14,7168|random;random;random;random;random|-100,100;-100,100;-100,100;-100,100;-100,100||||||Ascend950|NO_ERROR | ||


param_.normParam.epsilon 可能是 float 类型,但 static_cast 可能导致精度丢失
若 epsilon 在 ACLNN 接口要求为 double,可保留,但应注释说明原因。若接口支持 float,建议统一为 float 类型。