Skip to content

[MLU] feat: Add Cambricon MLU support for verl - #6327

Closed
uqyxx wants to merge 2 commits into
verl-project:mainfrom
uqyxx:verl-mlu
Closed

uqyxx wants to merge 2 commits into
verl-project:mainfrom
uqyxx:verl-mlu

Conversation

@uqyxx

@uqyxx uqyxx commented May 13, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

This pr is for supporting Cambricon MLU backend. You can read the docs: docs/mlu/start_with_mlu.rst for requirement needed to run on mlu.

Checklist Before Starting

  • Search for similar PRs. Paste at least one query link here: ...
  • Format the PR title as [{modules}] {type}: {description} (This will be checked by the CI)
    • {modules} include fsdp, megatron, veomni, sglang, vllm, rollout, trainer, ci, training_utils, recipe, hardware, deployment, ray, worker, single_controller, misc, perf, model, algo, env, tool, ckpt, doc, data, cfg, reward, fully_async, one_step_off
    • If this PR involves multiple modules, separate them with , like [megatron, fsdp, doc]
    • {type} is in feat, fix, refactor, chore, test
    • If this PR breaks any API (CLI arguments, config, function signature, etc.), add [BREAKING] to the beginning of the title.
    • Example: [BREAKING][fsdp, megatron] feat: dynamic batching

Test

For changes that can not be tested by CI (e.g., algorithm implementation, new model support), validate by experiment(s) and show results like training curve plots, evaluation results, etc.

API and Usage Example

Demonstrate how the API changes if any, and provide usage example(s) if possible.

# Add code snippet or script demonstrating how to use this

Design & Code Changes

Demonstrate the high-level design if this PR is complex, and list the specific changes.

Checklist Before Submitting

Important

Please check all the following items before requesting a review, otherwise the reviewer might deprioritize this PR for review.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


yuxiaoxi seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@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 support for Cambricon MLU devices, including the implementation of CNCLCheckpointEngine for collective communication and updates to device utilities and engine registrations. Feedback highlights the need to offload BroadcastOperation to a background thread in CNCLCheckpointEngine to prevent blocking the Ray event loop and to ensure proper synchronization in wait_for_complete. Additionally, it was noted that get_resource_name should be updated to explicitly support the "MLU" resource name for correct Ray scheduling.

self.socket = socket
self.topic = topic

self._run()

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 BroadcastOperation class is intended to perform operations asynchronously in a separate thread, as stated in its docstring. However, self._run() is currently called directly in __init__, which executes synchronously and blocks the event loop. This is a critical issue for Ray actors as it can lead to deadlocks or significant performance degradation when waiting for ZMQ messages or CNCL collectives. It should be offloaded to a background thread to allow the event loop to remain responsive.

Suggested change
self._run()
import threading
self.thread = threading.Thread(target=self._run, daemon=True)
self.thread.start()
References
  1. Avoid blocking the event loop in Ray actors, as it can lead to performance degradation or deadlocks.

Comment on lines +87 to +93
async def wait_for_complete(self) -> dict[str, TensorMeta]:
"""Wait for the broadcast operation to complete.

Returns:
dict[str, TensorMeta]: The bucket meta after broadcast.
"""
return self.metadata

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

Since BroadcastOperation should run in a background thread, wait_for_complete must actually wait for that thread to finish. The current implementation returns immediately, which could lead to race conditions where the next operation starts before the current broadcast is complete. Using asyncio.sleep in a loop allows the event loop to yield while waiting for the thread.

Suggested change
async def wait_for_complete(self) -> dict[str, TensorMeta]:
"""Wait for the broadcast operation to complete.
Returns:
dict[str, TensorMeta]: The bucket meta after broadcast.
"""
return self.metadata
async def wait_for_complete(self) -> dict[str, TensorMeta]:
"""Wait for the broadcast operation to complete.
Returns:
dict[str, TensorMeta]: The bucket meta after broadcast.
"""
import asyncio
while self.thread.is_alive():
await asyncio.sleep(0.01)
return self.metadata
References
  1. Avoid blocking the event loop in Ray actors, as it can lead to performance degradation or deadlocks.

Comment thread verl/utils/device.py
Comment on lines 64 to +72
def get_resource_name() -> str:
"""Function that return ray resource name based on the device type.
Returns:
ray resource name string, either "GPU" or "NPU".
"""
return "GPU" if is_cuda_available else "NPU"
if is_npu_available:
return "NPU"
else:
return "GPU"

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 get_resource_name function is missing support for Cambricon MLU. When running on MLU-based clusters, Ray typically uses the "MLU" resource name for scheduling. Returning "GPU" for MLU devices may lead to scheduling failures if the cluster is configured with MLU resources. Additionally, the docstring should be updated to reflect the support for MLU.

Suggested change
def get_resource_name() -> str:
"""Function that return ray resource name based on the device type.
Returns:
ray resource name string, either "GPU" or "NPU".
"""
return "GPU" if is_cuda_available else "NPU"
if is_npu_available:
return "NPU"
else:
return "GPU"
def get_resource_name() -> str:
"""Function that return ray resource name based on the device type.
Returns:
ray resource name string, either "GPU", "NPU", or "MLU".
"""
if is_npu_available:
return "NPU"
elif is_mlu_available:
return "MLU"
else:
return "GPU"

@wuxibin89

Copy link
Copy Markdown
Collaborator

MLU will be supported via external plugin #6086

@wuxibin89

Copy link
Copy Markdown
Collaborator

@uqyxx All training/inference backend plugin will be located in https://github.com/verl-project/verl-hardware-plugin

@uqyxx

uqyxx commented May 20, 2026 •

Copy link
Copy Markdown
Contributor Author

@uqyxx All training/inference backend plugin will be located in https://github.com/verl-project/verl-hardware-plugin

hi @wuxibin89 do you have a rough timeline about verl-hardware-plugin? if verl-hardware-plugin will not be ready to accept contributions in a short time, can we merge this pr first and continue other implementations in verl-hardware-plugin?
Thanks a lot

@wuxibin89

Copy link
Copy Markdown
Collaborator

@uqyxx #6086 will be merged after v0.8 release, we will release v0.8 in next 2 weeks. Then you can develop MLU plugin in verl-project/verl-hardware-plugin

@heavyrain-lzy

Copy link
Copy Markdown
Contributor

@uqyxx Hi~ Currently, we have updated the PR #6086 and verl-hardware-plugin https://github.com/verl-project/verl-hardware-plugin. You can adapt according to the instructions. If there are any issues, please contact us promptly.

@wuxibin89 wuxibin89 closed this Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants