Skip to content

Amd add quickreduce bak - #8139

Closed
lihaoyang-amd wants to merge 3 commits into
sgl-project:mainfrom
lihaoyang-amd:amd_add_quickreduce_bak
Closed

lihaoyang-amd wants to merge 3 commits into
sgl-project:mainfrom
lihaoyang-amd:amd_add_quickreduce_bak

Conversation

@lihaoyang-amd

Copy link
Copy Markdown
Contributor

test

lihaoyang-amd and others added 3 commits July 18, 2025 04:07
Signed-off-by: Haoyang Li <Haoyang.Li@amd.com>
Co-authored-by: Haoyang Li <307790822@qq.com>
Signed-off-by: Haoyang Li <Haoyang.Li@amd.com>
Co-authored-by: Haoyang Li <307790822@qq.com>
Signed-off-by: Haoyang Li <Haoyang.Li@amd.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @lihaoyang-amd, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new "Quick Allreduce" communication primitive specifically optimized for AMD ROCm MI300 series GPUs. This new all-reduce implementation leverages quantization (FP, INT8, INT6, INT4) to further accelerate collective communication, complementing the existing custom all-reduce. It integrates into the distributed communication framework, allowing for automatic fallback to other methods if conditions for quick all-reduce are not met.

Highlights

  • New Quick Allreduce Implementation: Introduced a new, highly optimized all-reduce primitive (QuickAllReduce) specifically designed for AMD ROCm MI300 series GPUs. This implementation supports various quantization levels (FP, INT8, INT6, INT4) for improved performance.
  • Quantization Support: The Quick Allreduce supports different quantization regimes, allowing for trade-offs between precision and communication speed, with configurable environment variables (ROCM_QUICK_REDUCE_CAST_BF16_TO_FP16, ROCM_QUICK_REDUCE_QUANTIZATION).
  • Dynamic Allreduce Selection: The distributed communication framework now intelligently selects the most efficient all-reduce method (Quick Allreduce, Custom Allreduce, PyMSCCLPP, or PyTorch NCCL) based on hardware capabilities, tensor size, and configuration, with automatic fallback.
  • Centralized Device Utilities: Common utility functions for device introspection (like is_full_nvlink and is_weak_contiguous) have been refactored and moved to a dedicated custom_all_reduce_utils.py file for better organization.
  • Comprehensive Testing: A new test suite (test_quick_allreduce.py) has been added to validate the functionality of the Quick Allreduce in both eager and graph modes across different world sizes and data types.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a "quick all-reduce" implementation for AMD ROCm GPUs, which leverages quantization to accelerate the all-reduce operation. The changes are comprehensive, touching Python application logic, C++/HIP kernels, build files, and adding new tests. The overall structure and implementation are well-done. The refactoring of utility functions into custom_all_reduce_utils.py improves code organization. The new QuickAllReduce class is a significant addition and is integrated into the existing parallel state management. I've identified a few critical issues in the all-reduce dispatch logic and the C++ kernel implementation that need to be addressed. There are also some medium-severity issues related to environment variable handling in Python and a potential bug in the C++ buffer allocation. Once these issues are resolved, this will be a solid contribution to improving performance on ROCm platforms.

return torch.ops.sglang.outplace_all_reduce(
input_, group_name=self.unique_name
outplace_all_reduce_method = "pymscclpp"
outplace_all_reduce_method = "ca"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This line unconditionally overwrites outplace_all_reduce_method to "ca". This negates the preceding logic that selects between qr, ca, and pymscclpp. As a result, quick_all_reduce will never be used. This seems to be a leftover from debugging and should be removed.

Comment on lines +514 to 518
torch.ops.sglang.outplace_all_reduce(
input_,
group_name=self.unique_name,
outplace_all_reduce_method=outplace_all_reduce_method,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

torch.ops.sglang.outplace_all_reduce is an out-of-place operation that returns a new tensor with the result. The current implementation calls the op but discards its return value. You need to return the result of this operation.

Suggested change
torch.ops.sglang.outplace_all_reduce(
input_,
group_name=self.unique_name,
outplace_all_reduce_method=outplace_all_reduce_method,
)
return torch.ops.sglang.outplace_all_reduce(
input_,
group_name=self.unique_name,
outplace_all_reduce_method=outplace_all_reduce_method,
)

Comment on lines +165 to +174
} else {
int32_t int16_2 = (qw >> (i * 4)) & kMask000F;
int16_t low = static_cast<int16_t>(int16_2 & 0xFFFF);
int16_t high = static_cast<int16_t>((int16_2 >> 16) & 0xFFFF);
nv_bfloat16 bf_low = __float2bfloat16(static_cast<float>(low));
nv_bfloat16 bf_high = __float2bfloat16(static_cast<float>(high));
nv_bfloat162 bf2 = __halves2bfloat162(bf_low, bf_high);
int32_t packed_bf16 = *reinterpret_cast<int32_t*>(&bf2);
w[i] = packed_add<nv_bfloat16>(packed_bf16, kRangeMin);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The dequantization logic for bfloat16 in CodecQ4::recv appears to be incorrect. The send function adds kRangeBias to the quantized values. The recv function should perform the inverse operation, which is subtracting this bias. However, the current implementation for bfloat16 adds kRangeMin instead. This will lead to incorrect results for bfloat16 tensors.

A similar issue seems to exist in CodecQ6::recv (lines 322-331) and CodecQ8::recv (lines 467-475) for bfloat16 dequantization.

}
// Allocate buffer size for worst case: F16 2-stage buffer.
uint32_t flags_buffer_size = 2 * world_size * kMaxNumBlocks * sizeof(uint32_t);
static int64_t data_buffer_size = 2 * this->kMaxProblemSize;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The data_buffer_size is declared as a static local variable inside DeviceComms::init. This means it will be initialized only once, using the kMaxProblemSize of the first DeviceComms instance created. If subsequent instances are created with a different max_problem_size, they will still use the buffer size calculated from the first instance, which could lead to buffer overflows or inefficient memory usage. The static keyword should be removed to make data_buffer_size a regular local variable.

    int64_t data_buffer_size = 2 * this->kMaxProblemSize;

# On RocM, bfloat16 kernels are slower than fp16
# due to slower match operations
# If environment variable is set to 1, we convert input to fp16
self.use_fp16_kernels = os.environ.get("ROCM_QUICK_REDUCE_CAST_BF16_TO_FP16", 1)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

os.environ.get() returns a string. self.use_fp16_kernels is initialized with the string "1" by default, but it's used as a boolean/integer in should_quick_allreduce and passed to qr_all_reduce. While a non-empty string evaluates to True, it's safer and clearer to explicitly cast it to the expected type.

Suggested change
self.use_fp16_kernels = os.environ.get("ROCM_QUICK_REDUCE_CAST_BF16_TO_FP16", 1)
self.use_fp16_kernels = int(os.environ.get("ROCM_QUICK_REDUCE_CAST_BF16_TO_FP16", 1))

Comment on lines +208 to +215
qr_max_size = os.environ.get("ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB", None)
if qr_max_size is not None:
if qr_max_size < 1:
logger.info(
"You should not set a max_size smaller than 1MB, which can "
"lead to error or degradation to custom allreduce or rccl."
)
qr_max_size = qr_max_size * MB

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

os.environ.get() returns a string, but qr_max_size is used in numerical operations on lines 210 and 215. This will cause a TypeError at runtime. You should convert the value from the environment variable to an integer before performing calculations.

        qr_max_size = os.environ.get("ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB", None)
        if qr_max_size is not None:
            qr_max_size = int(qr_max_size) * MB

p.join()


class TestCustomAllReduce:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The test class is named TestCustomAllReduce, but it appears to be testing the new QuickAllReduce implementation. For clarity and consistency, consider renaming it to TestQuickAllReduce.

Suggested change
class TestCustomAllReduce:
class TestQuickAllReduce:

@github-actions

Copy link
Copy Markdown
Contributor

Thanks @lihaoyang-amd. Closing this because it is still a draft and has not been updated in 255 days.

Reopen it if the work is still relevant.

Some directories moved recently, so an older branch may need retargeting:
sgl-kernel/ -> python/sglang/kernels/aot/, python/sglang/jit_kernel/
-> python/sglang/kernels/jit/, docs/ -> docs/docs/ (.mdx),
bench_serving.py -> benchmark/serving.py, test/srt/ -> test/registered/.

@github-actions github-actions Bot closed this Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants