From 04bec21ef844c3bba291c35b1df439a87a06ddef Mon Sep 17 00:00:00 2001 From: "tianle.zhong" Date: Fri, 2 Oct 2026 14:40:51 +0000 Subject: [PATCH] [runtime, deps] fix: initialize rollout state with the current VeOmni API --- README.md | 5 + pyproject.toml | 12 +- tests/test_veomni_parallel_state.py | 112 ++++++++++++++++++ .../test_async_server_model_version.py | 28 ++++- uv.lock | 87 +++++++------- vexact/integrations/verl/async_server.py | 12 +- vexact/utils/veomni_parallel_state.py | 35 ++++++ vexact/worker/worker.py | 8 +- 8 files changed, 241 insertions(+), 58 deletions(-) create mode 100644 tests/test_veomni_parallel_state.py create mode 100644 vexact/utils/veomni_parallel_state.py diff --git a/README.md b/README.md index 0c11e89..ff2ed1f 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,11 @@ Extras: `gpu` (PyTorch + FlashAttention + kernels), `verl` and `veomni` `[tool.uv.sources]` block; to develop against a local checkout, set `editable = true` there (inline hints included). +VeOmni integration requires its current `init_parallel_state_from_config` API; +the legacy `init_parallel_state` API is not supported. Standalone rollout +workers derive their non-EP topology from the initialized process group, +even when they inherit a different `WORLD_SIZE` from the trainer. + ## Components - [`vexact/batch_invariant_ops/`](vexact/batch_invariant_ops/README.md) — batch-invariant operators/kernels for true on-policy RL training. diff --git a/pyproject.toml b/pyproject.toml index c6e1255..8ab6be0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,18 +36,18 @@ verl = [ "verl", # VeRL's v1 trainer imports TransferQueue unconditionally, but the # upstream package does not currently declare it as a dependency. - "TransferQueue==0.1.9", + "TransferQueue==0.1.10", "uvicorn", "fastapi", "cachetools", ] veomni = [ "veomni", - # VeOmni's default install pins transformers==5.9.0 (via its + # VeOmni's default install pins transformers==5.16.1 (via its # `transformers-stable` dependency group). Mirror that pin here so vexact # users picking up the veomni extra resolve to the same version VeOmni # tests/develops against. - "transformers==5.9.0", + "transformers==5.16.1", ] [build-system] @@ -133,10 +133,10 @@ known-third-party = [ ] [tool.uv.sources] -verl = { git = "https://github.com/verl-project/verl.git", rev = "e9618406de5bad40041d7612554e465ec2003ec1" } +verl = { git = "https://github.com/verl-project/verl.git", rev = "8718ca30a3f002f93b7c4fd99b9b2506718681bc" } # To work on verl locally, point this at `{ path = "./verl", editable = true }`. # To work on VeOmni locally, point this at `{ path = "./VeOmni", editable = true }`. -veomni = { git = "https://github.com/ByteDance-Seed/VeOmni.git", rev = "9651e80750a7d204d69423d71063c2987b03bf08" } +veomni = { git = "https://github.com/ByteDance-Seed/VeOmni.git", rev = "aa8bb43c6ba457afde4b9bd35cceaf74823604cc" } torch = [ { index = "pytorch", extra = "gpu" }, ] @@ -162,5 +162,5 @@ environments = ["sys_platform == 'linux'"] override-dependencies = [ "opencv-python-headless<4.13.0", # Keep the vllm and veomni extras on the same Transformers version. - "transformers==5.9.0", + "transformers==5.16.1", ] diff --git a/tests/test_veomni_parallel_state.py b/tests/test_veomni_parallel_state.py new file mode 100644 index 0000000..54baebf --- /dev/null +++ b/tests/test_veomni_parallel_state.py @@ -0,0 +1,112 @@ +# Copyright 2026 Bytedance Ltd. and/or its affiliates +# +# 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. + +"""Check current VeOmni initialization in standalone spawned rollout workers.""" + +import os +import sys +from datetime import timedelta +from types import ModuleType +from unittest.mock import Mock + +import pytest +import torch.distributed as dist +import torch.multiprocessing as mp + +from vexact.utils.veomni_parallel_state import init_veomni_parallel_state + + +def _install_veomni(): + class AcceleratorConfig: + def __init__(self): + self.world_size = self.dp_size = self.dp_shard_size = int(os.environ.get("WORLD_SIZE", "1")) + self.dp_replicate_size = self.pp_size = self.tp_size = self.cp_size = self.ulysses_size = 1 + self.ep_size = 1 + + veomni = ModuleType("veomni") + arguments = ModuleType("veomni.arguments") + arguments.AcceleratorConfig = AcceleratorConfig + distributed = ModuleType("veomni.distributed") + parallel_state = ModuleType("veomni.distributed.parallel_state") + distributed.parallel_state = parallel_state + veomni.arguments = arguments + veomni.distributed = distributed + return { + "veomni": veomni, + "veomni.arguments": arguments, + "veomni.distributed": distributed, + "veomni.distributed.parallel_state": parallel_state, + } + + +@pytest.mark.parametrize("inherited_world_size", ["1", "16"]) +def test_uses_rollout_group_topology(monkeypatch, inherited_world_size): + modules = _install_veomni() + initializer = Mock() + modules["veomni.distributed.parallel_state"].init_parallel_state_from_config = initializer + for name, value in modules.items(): + monkeypatch.setitem(sys.modules, name, value) + monkeypatch.setattr(dist, "is_initialized", lambda: True) + monkeypatch.setattr(dist, "get_world_size", lambda: 4) + monkeypatch.setenv("WORLD_SIZE", inherited_world_size) + + assert init_veomni_parallel_state() is initializer.return_value + initializer.assert_called_once() + accelerator = initializer.call_args.args[0] + assert accelerator.world_size == accelerator.dp_size == accelerator.dp_shard_size == 4 + assert accelerator.dp_replicate_size == accelerator.pp_size == accelerator.tp_size == 1 + assert accelerator.cp_size == accelerator.ulysses_size == accelerator.ep_size == 1 + assert initializer.call_args.kwargs == {"name": None} + assert os.environ["WORLD_SIZE"] == inherited_world_size + + +def test_uninitialized_group_does_not_import_veomni(monkeypatch): + monkeypatch.setattr(dist, "is_initialized", lambda: False) + monkeypatch.setitem(sys.modules, "veomni", None) + assert init_veomni_parallel_state() is None + + +def _spawned_worker(rank, world_size, init_method): + assert "verl" not in sys.modules + assert os.environ["WORLD_SIZE"] == "16" + dist.init_process_group( + "gloo", init_method=init_method, rank=rank, world_size=world_size, timeout=timedelta(seconds=30) + ) + try: + from unittest.mock import patch + + from veomni.distributed import parallel_state + + # Exercise a real VeOmni mesh on CPU even on the GPU CI runner. + with patch.object(parallel_state, "get_device_type", return_value="cpu"): + first = init_veomni_parallel_state() + assert first is init_veomni_parallel_state() + assert first is parallel_state.get_parallel_state() + assert first.dp_size == first.dp_shard_size == first.world_size == world_size + assert first.dp_replicate_size == first.pp_size == first.tp_size == 1 + assert first.cp_size == first.ulysses_size == 1 + assert not first.ep_enabled + assert first.device_mesh.device_type == "cpu" + assert first.dp_group.size() == world_size + assert "verl" not in sys.modules + assert os.environ["WORLD_SIZE"] == "16" + dist.barrier() + finally: + dist.destroy_process_group() + + +def test_spawned_rollout_group_uses_current_api(monkeypatch, tmp_path): + pytest.importorskip("veomni") + monkeypatch.setenv("WORLD_SIZE", "16") + mp.spawn(_spawned_worker, args=(4, f"file://{tmp_path / 'rendezvous'}"), nprocs=4, join=True) diff --git a/tests/verl_integrations/test_async_server_model_version.py b/tests/verl_integrations/test_async_server_model_version.py index ede560e..e6ae76b 100644 --- a/tests/verl_integrations/test_async_server_model_version.py +++ b/tests/verl_integrations/test_async_server_model_version.py @@ -20,7 +20,8 @@ pytest.importorskip("verl") -from vexact.integrations.verl.async_server import VeXactServer # noqa: E402 +from verl.checkpoint_engine.base import CheckpointEngineManager # noqa: E402 +from vexact.integrations.verl.async_server import VeXactReplica, VeXactServer # noqa: E402 from vexact.integrations.verl.rollout import ServerAdapter # noqa: E402 @@ -77,6 +78,31 @@ async def test_unversioned_weight_update_clears_previous_model_version(): assert server.global_steps is None +@pytest.mark.asyncio +async def test_abort_accepts_current_verl_checkpoint_keyword(): + server = VeXactServer.__new__(VeXactServer) + remote_abort = AsyncMock(side_effect=server.abort_all_requests) + replica = VeXactReplica.__new__(VeXactReplica) + replica.servers = [SimpleNamespace(abort_all_requests=SimpleNamespace(remote=remote_abort))] + + manager = CheckpointEngineManager.__new__(CheckpointEngineManager) + manager.replicas = [replica] + await manager.abort_replicas(reject_request=False) + + remote_abort.assert_awaited_once_with(reject_request=False) + + +@pytest.mark.asyncio +async def test_abort_does_not_silently_ignore_request_rejection(): + server = VeXactServer.__new__(VeXactServer) + remote_abort = AsyncMock(side_effect=server.abort_all_requests) + replica = VeXactReplica.__new__(VeXactReplica) + replica.servers = [SimpleNamespace(abort_all_requests=SimpleNamespace(remote=remote_abort))] + + with pytest.raises(NotImplementedError, match="rejecting incoming generation requests"): + await replica.abort_all_requests(reject_request=True) + + class _RemoteMethod: def __init__(self, name, calls): self.name = name diff --git a/uv.lock b/uv.lock index 70456d5..52553a3 100644 --- a/uv.lock +++ b/uv.lock @@ -12,7 +12,7 @@ supported-markers = [ [manifest] overrides = [ { name = "opencv-python-headless", specifier = "<4.13.0" }, - { name = "transformers", specifier = "==5.9.0" }, + { name = "transformers", specifier = "==5.16.1" }, ] [[package]] @@ -2638,20 +2638,21 @@ wheels = [ [[package]] name = "safetensors" -version = "0.7.0" +version = "0.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/29/9c/6e74567782559a63bd040a236edca26fd71bc7ba88de2ef35d75df3bca5e/safetensors-0.7.0.tar.gz", hash = "sha256:07663963b67e8bd9f0b8ad15bb9163606cd27cc5a1b96235a50d8369803b96b0", size = 200878, upload-time = "2025-11-19T15:18:43.199Z" } +sdist = { url = "https://files.pythonhosted.org/packages/45/06/f955dbbb1859e3bd23c8ac6141af5106e7ad5fedec4a3a6e3d60f94b7001/safetensors-0.8.0.tar.gz", hash = "sha256:fabaf3e0f18a6618d9b36560682562157f77c2b71fcffc7b432be2baed9d753d", size = 325846, upload-time = "2026-06-09T07:52:25.563Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/06/578ffed52c2296f93d7fd2d844cabfa92be51a587c38c8afbb8ae449ca89/safetensors-0.7.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e07d91d0c92a31200f25351f4acb2bc6aff7f48094e13ebb1d0fb995b54b6542", size = 491748, upload-time = "2025-11-19T15:18:09.79Z" }, - { url = "https://files.pythonhosted.org/packages/ae/33/1debbbb70e4791dde185edb9413d1fe01619255abb64b300157d7f15dddd/safetensors-0.7.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8469155f4cb518bafb4acf4865e8bb9d6804110d2d9bdcaa78564b9fd841e104", size = 503881, upload-time = "2025-11-19T15:18:16.145Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1c/40c2ca924d60792c3be509833df711b553c60effbd91da6f5284a83f7122/safetensors-0.7.0-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54bef08bf00a2bff599982f6b08e8770e09cc012d7bba00783fc7ea38f1fb37d", size = 623463, upload-time = "2025-11-19T15:18:21.11Z" }, - { url = "https://files.pythonhosted.org/packages/9b/3a/13784a9364bd43b0d61eef4bea2845039bc2030458b16594a1bd787ae26e/safetensors-0.7.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42cb091236206bb2016d245c377ed383aa7f78691748f3bb6ee1bfa51ae2ce6a", size = 532855, upload-time = "2025-11-19T15:18:25.719Z" }, - { url = "https://files.pythonhosted.org/packages/a0/60/429e9b1cb3fc651937727befe258ea24122d9663e4d5709a48c9cbfceecb/safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac7252938f0696ddea46f5e855dd3138444e82236e3be475f54929f0c510d48", size = 507152, upload-time = "2025-11-19T15:18:33.023Z" }, - { url = "https://files.pythonhosted.org/packages/3c/a8/4b45e4e059270d17af60359713ffd83f97900d45a6afa73aaa0d737d48b6/safetensors-0.7.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1d060c70284127fa805085d8f10fbd0962792aed71879d00864acda69dbab981", size = 541856, upload-time = "2025-11-19T15:18:31.075Z" }, - { url = "https://files.pythonhosted.org/packages/06/87/d26d8407c44175d8ae164a95b5a62707fcc445f3c0c56108e37d98070a3d/safetensors-0.7.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cdab83a366799fa730f90a4ebb563e494f28e9e92c4819e556152ad55e43591b", size = 674060, upload-time = "2025-11-19T15:18:37.211Z" }, - { url = "https://files.pythonhosted.org/packages/11/f5/57644a2ff08dc6325816ba7217e5095f17269dada2554b658442c66aed51/safetensors-0.7.0-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:672132907fcad9f2aedcb705b2d7b3b93354a2aec1b2f706c4db852abe338f85", size = 771715, upload-time = "2025-11-19T15:18:38.689Z" }, - { url = "https://files.pythonhosted.org/packages/86/31/17883e13a814bd278ae6e266b13282a01049b0c81341da7fd0e3e71a80a3/safetensors-0.7.0-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:5d72abdb8a4d56d4020713724ba81dac065fedb7f3667151c4a637f1d3fb26c0", size = 714377, upload-time = "2025-11-19T15:18:40.162Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d8/0c8a7dc9b41dcac53c4cbf9df2b9c83e0e0097203de8b37a712b345c0be5/safetensors-0.7.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b0f6d66c1c538d5a94a73aa9ddca8ccc4227e6c9ff555322ea40bdd142391dd4", size = 677368, upload-time = "2025-11-19T15:18:41.627Z" }, + { url = "https://files.pythonhosted.org/packages/09/7d/65a7de0af421317bb36a067241e4235fff194eed60b961ed6d3f59a3fc60/safetensors-0.8.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a46e5ff292c356d6991e60942ba7f79817682d3a2cef0702136448cb9c4d235", size = 502844, upload-time = "2026-06-09T07:52:07.624Z" }, + { url = "https://files.pythonhosted.org/packages/91/4f/3175c9d75634e0e0dda0082794193521035edd7c70a6f212bf33ca06ddf4/safetensors-0.8.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4124502b78f03534117c848f87a39b8f31e577b15eff423bf8bfb95f2a8c30d0", size = 511823, upload-time = "2026-06-09T07:52:09.565Z" }, + { url = "https://files.pythonhosted.org/packages/20/87/846c289e7aa2299eff406335717cf43ce8777194ece8aad75772e0411615/safetensors-0.8.0-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc0a787ba8a35be368ee3574edfa2b1ad389eebd0a72e482ae275490e3f6c98", size = 633461, upload-time = "2026-06-09T07:52:11.128Z" }, + { url = "https://files.pythonhosted.org/packages/76/22/8d64d9df2c45d5ded401df889d0ad90882804ca172d79ec4f0df8f727fe0/safetensors-0.8.0-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040070828e36dc8e122178bbbd5830ff9e97920affb84cbe0f46442497bed358", size = 545148, upload-time = "2026-06-09T07:52:13.603Z" }, + { url = "https://files.pythonhosted.org/packages/28/50/f203ff3a3ddfe19308efc83c5a3a29ed02bf786732ec35e68bf9162f3365/safetensors-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6f3f93c9a0a7cc2788ee63fb763353d4bd2e89b0751bc78fcf7dda00bea774", size = 516040, upload-time = "2026-06-09T07:52:16.29Z" }, + { url = "https://files.pythonhosted.org/packages/46/fb/cdaed17ceb2948784fd9c36b6fd3e951b608547cea81a48e8ee6f8cfdfcb/safetensors-0.8.0-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:fcdd41ec4628fee5799f807c73c353629130fbd942aa23d83c623dd6c9d52d78", size = 513832, upload-time = "2026-06-09T07:52:12.37Z" }, + { url = "https://files.pythonhosted.org/packages/0d/49/1e15de264dcc3b77943d2d0c56a95809956883b1c2d6d585c792523f180b/safetensors-0.8.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e9f537aa183a38ace122d27303dcd986b26bd2a7591f9181d7f0c396f4677ca", size = 559930, upload-time = "2026-06-09T07:52:14.743Z" }, + { url = "https://files.pythonhosted.org/packages/2a/43/bf38443278eab4b1be1fce2931e2b012ad9cb7df52ada751d0aab8f7659a/safetensors-0.8.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87eec7ffed2b809f05a398a8becb7d013f19f7837cd15d9748580d6cf30dbaf4", size = 678670, upload-time = "2026-06-09T07:52:20.032Z" }, + { url = "https://files.pythonhosted.org/packages/72/e3/68cd3fa5b48488e84add63e04cb12f3bc28ae4638c06d4508c6e88823d0e/safetensors-0.8.0-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:4a95ae2b05d7726d751da4ebf626a2ca782b706e101bd894c95bc2450b1cffcc", size = 786679, upload-time = "2026-06-09T07:52:21.322Z" }, + { url = "https://files.pythonhosted.org/packages/29/4b/1c19c509d56e01f4fbb3d0a2e597450f6cc04d1d56cf52defb0a62dfd715/safetensors-0.8.0-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae091f16662658bdc019a4ff6cb4c085bb7d725eb5978b183ffd265863b6d2d", size = 765683, upload-time = "2026-06-09T07:52:22.594Z" }, + { url = "https://files.pythonhosted.org/packages/27/43/41c1621732edd934d868a00d1b891584c892a7b62a9aab82ea5a0a5623ee/safetensors-0.8.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8e080062fcde23be189565e1c3305d16751a218ecf9412c8601e64204eb6f846", size = 722361, upload-time = "2026-06-09T07:52:23.924Z" }, ] [[package]] @@ -2885,23 +2886,24 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.22.2" +version = "0.23.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub", marker = "sys_platform == 'linux'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/6f/f80cfef4a312e1fb34baf7d85c72d4411afde10978d4657f8cdd811d3ccc/tokenizers-0.22.2.tar.gz", hash = "sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917", size = 372115, upload-time = "2026-01-05T10:45:15.988Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/1e/bc6587c5ab643b2e17776cace9070a2ae73549c86bffac9934a600bf3c31/tokenizers-0.23.2.tar.gz", hash = "sha256:7f0f085686b9de0d0079e6f874ae053600db64c5d13049e0bbc0119926d25aac", size = 385745, upload-time = "2026-09-03T08:55:42.89Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/84/7990e799f1309a8b87af6b948f31edaa12a3ed22d11b352eaf4f4b2e5753/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7", size = 3290736, upload-time = "2026-01-05T10:40:32.165Z" }, - { url = "https://files.pythonhosted.org/packages/78/59/09d0d9ba94dcd5f4f1368d4858d24546b4bdc0231c2354aa31d6199f0399/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd", size = 3168835, upload-time = "2026-01-05T10:40:38.847Z" }, - { url = "https://files.pythonhosted.org/packages/47/50/b3ebb4243e7160bda8d34b731e54dd8ab8b133e50775872e7a434e524c28/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5", size = 3521673, upload-time = "2026-01-05T10:40:56.614Z" }, - { url = "https://files.pythonhosted.org/packages/e0/fa/89f4cb9e08df770b57adb96f8cbb7e22695a4cb6c2bd5f0c4f0ebcf33b66/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e", size = 3724818, upload-time = "2026-01-05T10:40:44.507Z" }, - { url = "https://files.pythonhosted.org/packages/64/04/ca2363f0bfbe3b3d36e95bf67e56a4c88c8e3362b658e616d1ac185d47f2/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b", size = 3379195, upload-time = "2026-01-05T10:40:51.139Z" }, - { url = "https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67", size = 3274982, upload-time = "2026-01-05T10:40:58.331Z" }, - { url = "https://files.pythonhosted.org/packages/1d/28/5f9f5a4cc211b69e89420980e483831bcc29dade307955cc9dc858a40f01/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4", size = 9478245, upload-time = "2026-01-05T10:41:04.053Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fb/66e2da4704d6aadebf8cb39f1d6d1957df667ab24cff2326b77cda0dcb85/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a", size = 9560069, upload-time = "2026-01-05T10:45:10.673Z" }, - { url = "https://files.pythonhosted.org/packages/16/04/fed398b05caa87ce9b1a1bb5166645e38196081b225059a6edaff6440fac/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a", size = 9899263, upload-time = "2026-01-05T10:45:12.559Z" }, - { url = "https://files.pythonhosted.org/packages/05/a1/d62dfe7376beaaf1394917e0f8e93ee5f67fea8fcf4107501db35996586b/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5", size = 10033429, upload-time = "2026-01-05T10:45:14.333Z" }, + { url = "https://files.pythonhosted.org/packages/2e/4d/8f569ed49372a3ed8e57099bd515055fd48d7c95912c4307cda6973c2168/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a37039b5dfc4af84eb3ef0a92f4307e28936c8f9adccba2629d36f652e9bf7a2", size = 3516830, upload-time = "2026-09-03T08:55:14.741Z" }, + { url = "https://files.pythonhosted.org/packages/2a/de/e2f14c8919d5bf51874051d00d6c7b7e0e8bde6c6a2dbeddda7f642896ff/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b7e37ba198f24150f523e1242e83c4970de4a525480586be5dcc24d9add32c5", size = 3407975, upload-time = "2026-09-03T08:55:16.842Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bd/93c69152d02ef06ce47aed8b2bf4952dcf733c935a62791873932b2934d9/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43e4f2071e3cc8d5d86421c874aebc82659bb51a68bcdef5a0da75ee89511ccb", size = 3748165, upload-time = "2026-09-03T08:55:24.769Z" }, + { url = "https://files.pythonhosted.org/packages/2d/b7/56b84b80bc96942bba8eb23751a9e8a1fce4faaf4390425e7083f721c98c/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:325fee2e0418a9dc6c9ecf736a5f5f0db7875183ace9549ae339da76f7a1fbb7", size = 4024165, upload-time = "2026-09-03T08:55:18.806Z" }, + { url = "https://files.pythonhosted.org/packages/9b/8a/0175e216f005c2fe08238292663aa41e4c802b216e71047a69a0e9fc6fa3/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:950d7c9426fa72406a0ffeacdbc0bb9985f5db20eb8b263f29c79aaf83105703", size = 3591899, upload-time = "2026-09-03T08:55:22.752Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ca/ca6b93c7820df123b2662a9469e8facc826ccc94e98fdd0d615f6431e73a/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41c2f84d172449b4dadb9cdc508e3e364076613c35b16e76ecfe47a60d1e3305", size = 3386843, upload-time = "2026-09-03T08:55:26.584Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a4/4f9106d317b14a80aefea9f0e3a8d07ef25f856a7607eb7f5ab894281fcb/tokenizers-0.23.2-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:12f0835dc2ee694746a76adf7b1567d4346a4a502ebe93fb1f5f80ea49799b78", size = 3577314, upload-time = "2026-09-03T08:55:20.825Z" }, + { url = "https://files.pythonhosted.org/packages/8d/6a/1552b70fb0d9ab074fd3fc961435d01364e79c9058481822c3af6e8d402c/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:eb2f9c8a24da020ea8c11a01a19c1c2547912d92121ae4a01cfbca46125dee40", size = 9967367, upload-time = "2026-09-03T08:55:33.188Z" }, + { url = "https://files.pythonhosted.org/packages/06/01/3ccb3a956c7528b2507b8a9714155c4baf86af593039db6ea375dd0c96c3/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:f486f402f6f9abee5bb032553736813af0c710a86b2e0ca592634c55cea1f835", size = 9811886, upload-time = "2026-09-03T08:55:35.642Z" }, + { url = "https://files.pythonhosted.org/packages/fa/73/7038e612d48bda1599457f712f6bd3854eae1a9dc9c13aa47f835349db48/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:bef235815a067b2648caf6dcc7a71091b0b0fff9ee8057f6451eb9335fae52ef", size = 10146224, upload-time = "2026-09-03T08:55:38.391Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d8/8e9e4e0b287a338d8f88976729628c9d22e8a54cfaf9777018a7f7cb58a0/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5c56bda1511921587789163e524d196ed8284174ac23abd7685d5ea8da6c4718", size = 10256304, upload-time = "2026-09-03T08:55:40.977Z" }, ] [[package]] @@ -2954,11 +2956,12 @@ wheels = [ [[package]] name = "torch-memory-saver" -version = "0.0.9" +version = "0.0.9.post1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/28/6c/21dfda5d31afb71f52cedff52370acbb8290485b3f0fee6816a15a3d08f1/torch_memory_saver-0.0.9.tar.gz", hash = "sha256:3bbf76391fb16870b1b0df279fc281c8a05ef8f8809400b309b0a8240e8ee5ba", size = 14220, upload-time = "2025-10-18T02:10:18.163Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/fd/42aad783d433fd69dc108b1b2ee5860fcf33e20e5440b899bc004ff97d70/torch_memory_saver-0.0.9.post1.tar.gz", hash = "sha256:25fd4b691ed3242c3a18b2bef0dbe9de84d2e7068b96a37686a923d55c274f43", size = 15209, upload-time = "2026-05-02T05:30:54.649Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/35/b22df9e730d8444d62445a594421992781c7fad271325d41656d8a32d103/torch_memory_saver-0.0.9-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:0cf26332993649f8ea1b95d7307dfba3a95ee6cee53de84a3e561fb21752b584", size = 488722, upload-time = "2025-10-18T02:10:16.825Z" }, + { url = "https://files.pythonhosted.org/packages/69/76/9a88e20f0be461af58165cc87663076a1fdfa53893f8371442d2e4ccabd1/torch_memory_saver-0.0.9.post1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:2c3505ba2bd7aa9ac75392417c675e8be686029da7c5f35037c59e2e8a3dfece", size = 1008682, upload-time = "2026-05-02T05:30:53.267Z" }, + { url = "https://files.pythonhosted.org/packages/49/67/6789f9048b836615d07e419fd2f253b83fb9b0f86f34d03ab75ac1f07049/torch_memory_saver-0.0.9.post1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:b4e560fcd88a0641efb21ac530bb79a6e78fc0b31c9a654fa3b5eb7c3629e555", size = 1015832, upload-time = "2026-05-02T05:30:51.317Z" }, ] [[package]] @@ -3011,7 +3014,7 @@ wheels = [ [[package]] name = "transferqueue" -version = "0.1.9" +version = "0.1.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "hydra-core", marker = "sys_platform == 'linux'" }, @@ -3025,12 +3028,12 @@ dependencies = [ { name = "tensordict", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/26/24/2bc71f4c3c14f44f4b28d7559d204809c5556b3d19421140f45521f79c95/transferqueue-0.1.9-py3-none-any.whl", hash = "sha256:729f21f393d092a4ac2f23840a61b56923bda73b86db197c4d7c9f11accc0421", size = 342944, upload-time = "2026-07-12T12:29:32.995Z" }, + { url = "https://files.pythonhosted.org/packages/42/6b/374c1ce1078baa628314d068fe0994a58380a020d57b9b0427cc2560c98f/transferqueue-0.1.10-py3-none-any.whl", hash = "sha256:a8efceb971fe57d52ac7ddd86d9a6ef63f1824819dddc2ea980a96b73ff2f8ea", size = 360774, upload-time = "2026-08-21T21:23:24.561Z" }, ] [[package]] name = "transformers" -version = "5.9.0" +version = "5.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub", marker = "sys_platform == 'linux'" }, @@ -3043,9 +3046,9 @@ dependencies = [ { name = "tqdm", marker = "sys_platform == 'linux'" }, { name = "typer", marker = "sys_platform == 'linux'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/51/58/7f843608f2e8421f86bb97060b54649be6239ec612b82bf9d41e65c26c00/transformers-5.9.0.tar.gz", hash = "sha256:25997cb8fa6053533171634b6162d7df54346530ec2aa9b42bb834e63668c842", size = 8642240, upload-time = "2026-05-20T14:50:49.278Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/2e/ba418680ab901dae269360bb8642485eae04f1af91ee2ebb8bd6f3607305/transformers-5.16.1.tar.gz", hash = "sha256:17b0eac726ddc55e84ac58946063e0c6d37fd000c456b581f050ea0f4e822869", size = 9650542, upload-time = "2026-08-26T14:48:58.789Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/ca/2eaa5359f2ccb8c2e1656bc26305ad0cf438aa392ce4b29ae67a315c186e/transformers-5.9.0-py3-none-any.whl", hash = "sha256:1d19509bcff7028ebc6b277d71caa712e8353778463d38764237d14b42b52788", size = 10787648, upload-time = "2026-05-20T14:50:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4d/ee3728674c0bbc637bb4af88ccf0be697f92e4e90b55f5dc110c44d61b61/transformers-5.16.1-py3-none-any.whl", hash = "sha256:2f2d5b98a5ad3718713653734298fa620754ed683702a635ebb587df3ed29c7e", size = 12080592, upload-time = "2026-08-26T14:48:55.083Z" }, ] [[package]] @@ -3139,8 +3142,8 @@ wheels = [ [[package]] name = "veomni" -version = "0.1.11" -source = { git = "https://github.com/ByteDance-Seed/VeOmni.git?rev=9651e80750a7d204d69423d71063c2987b03bf08#9651e80750a7d204d69423d71063c2987b03bf08" } +version = "0.1.12" +source = { git = "https://github.com/ByteDance-Seed/VeOmni.git?rev=aa8bb43c6ba457afde4b9bd35cceaf74823604cc#aa8bb43c6ba457afde4b9bd35cceaf74823604cc" } dependencies = [ { name = "blobfile", marker = "sys_platform == 'linux'" }, { name = "datasets", marker = "sys_platform == 'linux'" }, @@ -3157,8 +3160,8 @@ dependencies = [ [[package]] name = "verl" -version = "0.9.0.dev0" -source = { git = "https://github.com/verl-project/verl.git?rev=e9618406de5bad40041d7612554e465ec2003ec1#e9618406de5bad40041d7612554e465ec2003ec1" } +version = "0.10.0.dev0" +source = { git = "https://github.com/verl-project/verl.git?rev=8718ca30a3f002f93b7c4fd99b9b2506718681bc#8718ca30a3f002f93b7c4fd99b9b2506718681bc" } dependencies = [ { name = "accelerate", marker = "sys_platform == 'linux'" }, { name = "codetiming", marker = "sys_platform == 'linux'" }, @@ -3237,15 +3240,15 @@ requires-dist = [ { name = "pyzmq", specifier = ">=27.1.0" }, { name = "quack-kernels", marker = "extra == 'gpu'", specifier = "==0.3.4" }, { name = "torch", marker = "extra == 'gpu'", specifier = "==2.10.0+cu129", index = "https://download.pytorch.org/whl/cu129", conflict = { package = "vexact", extra = "gpu" } }, - { name = "torch-memory-saver", marker = "platform_machine != 'aarch64'", specifier = "==0.0.9" }, + { name = "torch-memory-saver", marker = "platform_machine != 'aarch64'", specifier = "==0.0.9.post1" }, { name = "torchaudio", marker = "extra == 'gpu'", index = "https://download.pytorch.org/whl/cu129" }, { name = "torchvision", marker = "extra == 'gpu'", index = "https://download.pytorch.org/whl/cu129" }, - { name = "transferqueue", marker = "extra == 'verl'", specifier = "==0.1.9" }, + { name = "transferqueue", marker = "extra == 'verl'", specifier = "==0.1.10" }, { name = "transformers" }, - { name = "transformers", marker = "extra == 'veomni'", specifier = "==5.9.0" }, + { name = "transformers", marker = "extra == 'veomni'", specifier = "==5.16.1" }, { name = "uvicorn", marker = "extra == 'verl'" }, - { name = "veomni", marker = "extra == 'veomni'", git = "https://github.com/ByteDance-Seed/VeOmni.git?rev=9651e80750a7d204d69423d71063c2987b03bf08" }, - { name = "verl", marker = "extra == 'verl'", git = "https://github.com/verl-project/verl.git?rev=e9618406de5bad40041d7612554e465ec2003ec1" }, + { name = "veomni", marker = "extra == 'veomni'", git = "https://github.com/ByteDance-Seed/VeOmni.git?rev=aa8bb43c6ba457afde4b9bd35cceaf74823604cc" }, + { name = "verl", marker = "extra == 'verl'", git = "https://github.com/verl-project/verl.git?rev=8718ca30a3f002f93b7c4fd99b9b2506718681bc" }, { name = "vllm", marker = "extra == 'vllm'", specifier = "==0.19.1" }, ] provides-extras = ["gpu", "dev", "vllm", "verl", "veomni"] diff --git a/vexact/integrations/verl/async_server.py b/vexact/integrations/verl/async_server.py index 9129915..1f14950 100644 --- a/vexact/integrations/verl/async_server.py +++ b/vexact/integrations/verl/async_server.py @@ -319,8 +319,10 @@ async def wait_for_requests_to_drain(self): """Wait for all pending requests to complete. VeXact processes requests synchronously.""" pass - async def abort_all_requests(self, reset_prefix_cache: bool = True) -> dict[str, Any]: # noqa: ARG002 - """Abort all ongoing generation requests.""" + async def abort_all_requests(self, reset_prefix_cache: bool = True, reject_request: bool = False) -> dict[str, Any]: # noqa: ARG002 + """Keep the existing no-op abort behavior; reject unsupported admission blocking.""" + if reject_request: + raise NotImplementedError("VeXact does not support rejecting incoming generation requests") return {"aborted_count": 0, "request_ids": []} async def resume_generation(self): @@ -441,9 +443,11 @@ async def sleep(self): await self.servers[0].wait_for_requests_to_drain.remote() await asyncio.gather(*[server.sleep.remote() for server in self.servers]) - async def abort_all_requests(self) -> dict[str, Any]: + async def abort_all_requests(self, reject_request: bool = False) -> dict[str, Any]: """Abort all ongoing generation requests across all servers.""" - results = await asyncio.gather(*[server.abort_all_requests.remote() for server in self.servers]) + results = await asyncio.gather( + *[server.abort_all_requests.remote(reject_request=reject_request) for server in self.servers] + ) total_aborted = sum(r.get("aborted_count", 0) for r in results) all_request_ids = [] diff --git a/vexact/utils/veomni_parallel_state.py b/vexact/utils/veomni_parallel_state.py new file mode 100644 index 0000000..1da0df5 --- /dev/null +++ b/vexact/utils/veomni_parallel_state.py @@ -0,0 +1,35 @@ +# Copyright 2026 Bytedance Ltd. and/or its affiliates +# +# 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. + +"""Initialize VeOmni state for the standalone rollout process group.""" + +import torch.distributed as dist + + +def init_veomni_parallel_state(): + """Bind a non-EP state using the current VeOmni config-based API.""" + if not dist.is_initialized(): + return + + from veomni.arguments import AcceleratorConfig + from veomni.distributed.parallel_state import init_parallel_state_from_config + + accelerator = AcceleratorConfig() + # AcceleratorConfig derives these attributes from WORLD_SIZE, which may + # describe the parent training job rather than this rollout process group. + world_size = dist.get_world_size() + accelerator.world_size = world_size + accelerator.dp_size = world_size + accelerator.dp_shard_size = world_size + return init_parallel_state_from_config(accelerator, name=None) diff --git a/vexact/worker/worker.py b/vexact/worker/worker.py index c4c303d..eb948bd 100644 --- a/vexact/worker/worker.py +++ b/vexact/worker/worker.py @@ -26,6 +26,7 @@ from vexact.inferencer.model_loader import ModelCreator, load_weights_from_weight_iterator from vexact.utils.profiler import ProfilerManager from vexact.utils.torch_memory_saver_adapter import TorchMemorySaverAdapter +from vexact.utils.veomni_parallel_state import init_veomni_parallel_state logger = logging.getLogger(__name__) @@ -118,11 +119,8 @@ def __init__(self, config: VeXactConfig, rank: int): # (e.g. our PP>1 rollout). Bind a non-EP parallel state up front so # subsequent MoE forwards take the cheap non-EP path; we never run # expert parallelism inside the rollout worker. The helper is - # idempotent (warns + early-return when state already exists). - if torch.distributed.is_initialized(): - from veomni.distributed.parallel_state import init_parallel_state - - init_parallel_state(dp_size=torch.distributed.get_world_size()) + # idempotent (reuses a matching VeOmni topology). + init_veomni_parallel_state() self.inferencer = Inferencer( model=self.model,