-
Notifications
You must be signed in to change notification settings - Fork 4.1k
[CUDA] fp16 intB gemm #24854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
[CUDA] fp16 intB gemm #24854
Changes from 9 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
baa6022
Add fp16 int4/8 gemm
tianleiwu b275f1a
clean up moe
tianleiwu acf8d02
Merge branch 'main' into tlwu/fp16_intB_gemm
tianleiwu ea3c1fe
Revert "clean up moe"
tianleiwu c77f9bf
update generate_kernels.py
tianleiwu fe8aea9
rename nv_infer_runtime.h to nv_infer_datatype.h
tianleiwu 731301d
Add tests
tianleiwu 43b6a84
fix 4 bit zero point adaptor
tianleiwu 8916212
Add scale only kernels
tianleiwu 0c3461b
format
tianleiwu 13e9be1
Revert "Add scale only kernels"
tianleiwu f48ddfb
remove scaleonly cu files
tianleiwu 1fdf33f
Update cuda compiler settings
tianleiwu d0dbfac
remove ENABLE_BF16
tianleiwu 528e261
fix unused parameters warnings
tianleiwu 358c832
Add bf16 gemv
tianleiwu 7584128
keep last virtual
tianleiwu 31a4194
move min cuda version to cuda_configuraiton.cmake
tianleiwu 213f096
increase test tolerance
tianleiwu cae37c9
static cast
tianleiwu 7207bc4
fix unused paramter warnings
tianleiwu 7b23374
prepacking
tianleiwu 39a5d99
format
tianleiwu bd27273
Merge branch 'main' into tlwu/fp16_intB_gemm
tianleiwu b3f49b0
disable by default
tianleiwu 00f36f4
rewrite transpose b kernel
tianleiwu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
onnxruntime/contrib_ops/cuda/llm/common/cuda_runtime_utils.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| #pragma once | ||
|
|
||
| #include <cuda_runtime_api.h> | ||
| #include "core/providers/cuda/shared_inc/cuda_call.h" | ||
|
|
||
| namespace onnxruntime::llm::common { | ||
| inline int getDevice() { | ||
| int deviceID{0}; | ||
| CUDA_CALL_THROW(cudaGetDevice(&deviceID)); | ||
| return deviceID; | ||
| } | ||
|
|
||
| inline int getSMVersion() { | ||
| int device{-1}; | ||
| CUDA_CALL_THROW(cudaGetDevice(&device)); | ||
| int sm_major = 0; | ||
| int sm_minor = 0; | ||
| CUDA_CALL_THROW(cudaDeviceGetAttribute(&sm_major, cudaDevAttrComputeCapabilityMajor, device)); | ||
| CUDA_CALL_THROW(cudaDeviceGetAttribute(&sm_minor, cudaDevAttrComputeCapabilityMinor, device)); | ||
| return sm_major * 10 + sm_minor; | ||
| } | ||
|
|
||
| inline int getMultiProcessorCount() { | ||
| int nSM{0}; | ||
| int deviceID{0}; | ||
| CUDA_CALL_THROW(cudaGetDevice(&deviceID)); | ||
| CUDA_CALL_THROW(cudaDeviceGetAttribute(&nSM, cudaDevAttrMultiProcessorCount, deviceID)); | ||
| return nSM; | ||
| } | ||
| } // namespace onnxruntime::llm::common |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "core/providers/shared_library/provider_api.h" | ||
|
|
||
| #ifndef NDEBUG | ||
| #define ORT_LLM_LOG_TRACE(msg) LOGS_DEFAULT(VERBOSE) << msg | ||
| #define ORT_LLM_LOG_DEBUG(msg) LOGS_DEFAULT(VERBOSE) << msg | ||
| #else | ||
| #define ORT_LLM_LOG_TRACE(msg) | ||
| #define ORT_LLM_LOG_DEBUG(msg) | ||
| #endif | ||
|
|
||
| #define ORT_LLM_LOG_INFO(msg) LOGS_DEFAULT(INFO) << msg | ||
| #define ORT_LLM_LOG_WARNING(msg) LOGS_DEFAULT(WARNING) << msg | ||
| #define ORT_LLM_LOG_ERROR(msg) LOGS_DEFAULT(ERROR) << msg | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| /* | ||
| * Copyright (c) 1993-2023, NVIDIA CORPORATION. All rights reserved. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| #pragma once | ||
| #include <cstddef> | ||
| #include <cstdint> | ||
|
|
||
| namespace onnxruntime::llm::common { | ||
|
|
||
| std::uintptr_t constexpr kCudaMemAlign = 128; | ||
|
|
||
| inline int8_t* alignPtr(int8_t* ptr, uintptr_t to) { | ||
| uintptr_t addr = (uintptr_t)ptr; | ||
| if (addr % to) { | ||
| addr += to - addr % to; | ||
| } | ||
| return (int8_t*)addr; | ||
| } | ||
|
|
||
| constexpr size_t alignSize(size_t size, size_t to) { | ||
| if ((size % to) != 0U) { | ||
| size += to - size % to; | ||
| } | ||
| return size; | ||
| } | ||
|
|
||
| inline int8_t* nextWorkspacePtrCommon(int8_t* ptr, uintptr_t previousWorkspaceSize, uintptr_t const alignment) { | ||
| uintptr_t addr = (uintptr_t)ptr; | ||
| addr += previousWorkspaceSize; | ||
| return alignPtr((int8_t*)addr, alignment); | ||
| } | ||
|
|
||
| inline int8_t* nextWorkspacePtr(int8_t* ptr, uintptr_t previousWorkspaceSize) { | ||
| return nextWorkspacePtrCommon(ptr, previousWorkspaceSize, kCudaMemAlign); | ||
| } | ||
|
|
||
| inline int8_t* nextWorkspacePtr( | ||
| int8_t* const base, uintptr_t& offset, uintptr_t const size, uintptr_t const alignment = kCudaMemAlign) { | ||
| uintptr_t curr_offset = offset; | ||
| uintptr_t next_offset = curr_offset + ((size + alignment - 1) / alignment) * alignment; | ||
| int8_t* newptr = size == 0 ? nullptr : base + curr_offset; | ||
| offset = next_offset; | ||
| return newptr; | ||
| } | ||
|
|
||
| inline int8_t* nextWorkspacePtrWithAlignment( | ||
| int8_t* ptr, uintptr_t previousWorkspaceSize, uintptr_t const alignment = kCudaMemAlign) { | ||
| return nextWorkspacePtrCommon(ptr, previousWorkspaceSize, alignment); | ||
| } | ||
|
|
||
| inline size_t calculateTotalWorkspaceSize( | ||
| size_t const* workspaces, int count, uintptr_t const alignment = kCudaMemAlign) { | ||
| size_t total = 0; | ||
| for (int i = 0; i < count; i++) { | ||
| total += workspaces[i]; | ||
| if (workspaces[i] % alignment) { | ||
| total += alignment - (workspaces[i] % alignment); | ||
| } | ||
| } | ||
| return total; | ||
| } | ||
|
|
||
| }; // namespace onnxruntime::llm::common |
97 changes: 97 additions & 0 deletions
97
onnxruntime/contrib_ops/cuda/llm/cutlass_extensions/arch/mma.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| /* | ||
| * Copyright (c) 2017-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| /*! \file | ||
| \brief Templates exposing architecture support for multiply-add operations | ||
| */ | ||
|
|
||
| #pragma once | ||
| #include "contrib_ops/cuda/llm/cutlass_extensions/weight_only_quant_op.h" | ||
|
|
||
| ///////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| namespace cutlass { | ||
| namespace arch { | ||
|
|
||
| // Tag which triggers MMA which will trigger | ||
| struct OpMultiplyAddDequantizeInterleavedBToA; | ||
|
|
||
| /* | ||
| Below we have extra tags to signal what kind of dequantization we want to do | ||
| (per col, scale only fine grained, finegrained with zero). This still lets us | ||
| the existing template infrastructure (incl. that in CUTLASS). However, we | ||
| split out the template below into OpMultiplyAddDequantizeInterleavedBToA along | ||
| with the quantization op before instantiating the GEMM pieces. | ||
|
|
||
| Note that this is somewhat of a hack, but it SIGNIFICANTLY reduces the amount of | ||
| code we need to duplicate. | ||
| */ | ||
| struct OpMultiplyAddDequantizeInterleavedBToA_percol_scale; | ||
| struct OpMultiplyAddDequantizeInterleavedBToA_fine_scale; | ||
| struct OpMultiplyAddDequantizeInterleavedBToA_fine_scalebias; | ||
|
|
||
| // The default just forwards the original operator | ||
| template <typename MmaOp, WeightOnlyQuantOp QuantOp_> | ||
| struct TagOperator { | ||
| using TaggedOperator = MmaOp; | ||
| }; | ||
|
|
||
| // Specializations below attach more information to the operator | ||
| template <> | ||
| struct TagOperator<OpMultiplyAddDequantizeInterleavedBToA, WeightOnlyQuantOp::PER_COLUMN_SCALE_ONLY> { | ||
| using TaggedOperator = OpMultiplyAddDequantizeInterleavedBToA_percol_scale; | ||
| }; | ||
|
|
||
| template <> | ||
| struct TagOperator<OpMultiplyAddDequantizeInterleavedBToA, WeightOnlyQuantOp::FINEGRAINED_SCALE_ONLY> { | ||
| using TaggedOperator = OpMultiplyAddDequantizeInterleavedBToA_fine_scale; | ||
| }; | ||
|
|
||
| template <> | ||
| struct TagOperator<OpMultiplyAddDequantizeInterleavedBToA, WeightOnlyQuantOp::FINEGRAINED_SCALE_AND_ZEROS> { | ||
| using TaggedOperator = OpMultiplyAddDequantizeInterleavedBToA_fine_scalebias; | ||
| }; | ||
|
|
||
| // Here we instantiate some structs to "detag" the tagged operator. It splits it back to the original | ||
| // operator + the extra information. If no extra info was tagged, the dequant op per column scaling | ||
| // as a default. | ||
| template <typename TaggedMmaOp> | ||
| struct DetagOperator { | ||
| using Operator = TaggedMmaOp; | ||
| static constexpr WeightOnlyQuantOp QuantOp = WeightOnlyQuantOp::PER_COLUMN_SCALE_ONLY; | ||
| }; | ||
|
|
||
| template <> | ||
| struct DetagOperator<OpMultiplyAddDequantizeInterleavedBToA_percol_scale> { | ||
| using Operator = OpMultiplyAddDequantizeInterleavedBToA; | ||
| static constexpr WeightOnlyQuantOp QuantOp = WeightOnlyQuantOp::PER_COLUMN_SCALE_ONLY; | ||
| }; | ||
|
|
||
| template <> | ||
| struct DetagOperator<OpMultiplyAddDequantizeInterleavedBToA_fine_scale> { | ||
| using Operator = OpMultiplyAddDequantizeInterleavedBToA; | ||
| static constexpr WeightOnlyQuantOp QuantOp = WeightOnlyQuantOp::FINEGRAINED_SCALE_ONLY; | ||
| }; | ||
|
|
||
| template <> | ||
| struct DetagOperator<OpMultiplyAddDequantizeInterleavedBToA_fine_scalebias> { | ||
| using Operator = OpMultiplyAddDequantizeInterleavedBToA; | ||
| static constexpr WeightOnlyQuantOp QuantOp = WeightOnlyQuantOp::FINEGRAINED_SCALE_AND_ZEROS; | ||
| }; | ||
|
|
||
| } // namespace arch | ||
| } // namespace cutlass |
74 changes: 74 additions & 0 deletions
74
onnxruntime/contrib_ops/cuda/llm/cutlass_extensions/compute_occupancy.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| /* | ||
| * Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| #pragma once | ||
|
|
||
| #include <cuda_runtime_api.h> | ||
|
|
||
| #include "cutlass/device_kernel.h" | ||
| #include "contrib_ops/cuda/llm/common/cuda_runtime_utils.h" | ||
| #include "core/providers/cuda/cuda_common.h" | ||
|
|
||
| namespace onnxruntime::llm { | ||
| namespace cutlass_extensions { | ||
|
|
||
| template <typename GemmKernel, bool enable_cutlass_3x = false> | ||
| inline int compute_occupancy_for_kernel() { | ||
| int smem_size = int(sizeof(typename GemmKernel::SharedStorage)); | ||
|
|
||
| if (smem_size > (48 << 10)) { | ||
|
nenad1002 marked this conversation as resolved.
|
||
| cudaFuncAttributes attr; | ||
| int device = 0; | ||
| int max_smem_per_block = 0; | ||
| CUDA_CALL_THROW(cudaGetDevice(&device)); | ||
| CUDA_CALL_THROW( | ||
| cudaDeviceGetAttribute(&max_smem_per_block, cudaDevAttrMaxSharedMemoryPerBlockOptin, device)); | ||
| if constexpr (enable_cutlass_3x) { | ||
| CUDA_CALL_THROW(cudaFuncGetAttributes(&attr, cutlass::device_kernel<GemmKernel>)); | ||
| } else { | ||
| CUDA_CALL_THROW(cudaFuncGetAttributes(&attr, cutlass::Kernel<GemmKernel>)); | ||
| } | ||
| if (smem_size + attr.sharedSizeBytes >= static_cast<size_t>(max_smem_per_block)) { | ||
| // This should mean that | ||
| // cudaFuncSetAttribute(cutlass::Kernel<GemmKernel>, cudaFuncAttributeMaxDynamicSharedMemorySize, smem_size) | ||
| // wouldn't work. In that case, we return an occupancy of 0. This will cause the heuristic to ignore this | ||
| // configuration. | ||
| return 0; | ||
| } | ||
|
|
||
| if constexpr (enable_cutlass_3x) { | ||
| CUDA_CALL_THROW(cudaFuncSetAttribute( | ||
| cutlass::device_kernel<GemmKernel>, cudaFuncAttributeMaxDynamicSharedMemorySize, smem_size)); | ||
| } else { | ||
| CUDA_CALL_THROW(cudaFuncSetAttribute( | ||
| cutlass::Kernel<GemmKernel>, cudaFuncAttributeMaxDynamicSharedMemorySize, smem_size)); | ||
| } | ||
| } | ||
|
|
||
| int max_active_blocks = -1; | ||
|
tianleiwu marked this conversation as resolved.
|
||
| if constexpr (enable_cutlass_3x) { | ||
| CUDA_CALL_THROW( | ||
| cudaOccupancyMaxActiveBlocksPerMultiprocessor(&max_active_blocks, cutlass::device_kernel<GemmKernel>, | ||
| 128 * (GemmKernel::NumLoadWarpGroups + GemmKernel::NumMmaWarpGroups), smem_size)); | ||
| } else { | ||
| CUDA_CALL_THROW(cudaOccupancyMaxActiveBlocksPerMultiprocessor( | ||
| &max_active_blocks, cutlass::Kernel<GemmKernel>, GemmKernel::kThreadCount, smem_size)); | ||
| } | ||
|
|
||
| return max_active_blocks; | ||
| } | ||
|
|
||
| } // namespace cutlass_extensions | ||
| } // namespace onnxruntime::llm | ||
61 changes: 61 additions & 0 deletions
61
onnxruntime/contrib_ops/cuda/llm/cutlass_extensions/epilogue/thread/fused_activations.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /* | ||
| * Copyright (c) 2017-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| /*! \file | ||
| \brief Functor performing linear combination with a maximum operation used by epilogues. | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "cutlass/array.h" | ||
| #include "cutlass/cutlass.h" | ||
| #include "cutlass/epilogue/thread/activation.h" | ||
| #include "cutlass/epilogue/thread/linear_combination_generic.h" | ||
| #include "cutlass/epilogue/thread/scale_type.h" | ||
| #include "cutlass/functional.h" | ||
| #include "cutlass/half.h" | ||
| #include "cutlass/numeric_conversion.h" | ||
| #include "cutlass/numeric_types.h" | ||
|
|
||
| ///////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| namespace cutlass { | ||
| namespace epilogue { | ||
| namespace thread { | ||
|
|
||
| ///////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| __forceinline__ __device__ float copysignf_pos(float a, float b) { | ||
| float r; | ||
| r = __int_as_float(__float_as_int(a) | (__float_as_int(b) & 0x80000000)); | ||
| return r; | ||
| } | ||
|
|
||
| __forceinline__ __device__ float tanh_opt(float x) { | ||
| #if (__CUDACC_VER_MAJOR__ < 11) || (__CUDA_ARCH__ < 750) | ||
|
tianleiwu marked this conversation as resolved.
|
||
| float const exp_val = -1.f * fabs(2 * x); | ||
| return copysignf_pos((1.0f - __expf(exp_val)) / (__expf(exp_val) + 1.0f), x); | ||
| #else | ||
| return fast_tanh(x); | ||
| #endif | ||
| } | ||
|
|
||
| } // namespace thread | ||
| } // namespace epilogue | ||
| } // namespace cutlass | ||
|
|
||
| ///////////////////////////////////////////////////////////////////////////////////////////////// | ||
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.