@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 5daffe7cf6
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 14, 22:35 UTC

[BugFix] Fix case where `collective_rpc` returns `None` (#22006)

Signed-off-by: Nick Hill <nhill@redhat.com>

Nick Hill committed Jul 31, 2025 at 13:51 UTC 5daffe7cf6db9765bd667d1a2cf5f18843d58fc7
2 files changed +21 -8
tests/v1/engine/test_engine_core_client.py
+11 -2
@@ -305,10 +305,10 @@ def echo_dc(
305 return_list: bool = False,
306 ) -> Union[MyDataclass, list[MyDataclass]]:
307 print(f"echo dc util function called: {msg}")
308 + val = None if msg is None else MyDataclass(msg)
309 # Return dataclass to verify support for returning custom types
310 # (for which there is special handling to make it work with msgspec).
310 - return [MyDataclass(msg) for _ in range(3)] if return_list \
311 - else MyDataclass(msg)
311 + return [val for _ in range(3)] if return_list else val
312
313
314 @pytest.mark.asyncio(loop_scope="function")
@@ -351,6 +351,15 @@ async def test_engine_core_client_util_method_custom_return(
351 assert isinstance(result, list) and all(
352 isinstance(r, MyDataclass) and r.message == "testarg2"
353 for r in result)
354 +
355 + # Test returning None and list of Nones
356 + result = await core_client.call_utility_async(
357 + "echo_dc", None, False)
358 + assert result is None
359 + result = await core_client.call_utility_async(
360 + "echo_dc", None, True)
361 + assert isinstance(result, list) and all(r is None for r in result)
362 +
363 finally:
364 client.shutdown()
365
vllm/v1/serial_utils.py
+10 -6
@@ -49,7 +49,10 @@ def _log_insecure_serialization_warning():
49 "VLLM_ALLOW_INSECURE_SERIALIZATION=1")
50
51
52 -def _typestr(t: type):
52 +def _typestr(val: Any) -> Optional[tuple[str, str]]:
53 + if val is None:
54 + return None
55 + t = type(val)
56 return t.__module__, t.__qualname__
57
58
@@ -131,14 +134,13 @@ class MsgpackEncoder:
134
135 if isinstance(obj, UtilityResult):
136 result = obj.result
134 - if not envs.VLLM_ALLOW_INSECURE_SERIALIZATION or result is None:
137 + if not envs.VLLM_ALLOW_INSECURE_SERIALIZATION:
138 return None, result
139 # Since utility results are not strongly typed, we also encode
140 # the type (or a list of types in the case it's a list) to
141 # help with correct msgspec deserialization.
139 - cls = result.__class__
140 - return _typestr(cls) if cls is not list else [
141 - _typestr(type(v)) for v in result
142 + return _typestr(result) if type(result) is not list else [
143 + _typestr(v) for v in result
144 ], result
145
146 if not envs.VLLM_ALLOW_INSECURE_SERIALIZATION:
@@ -277,7 +279,9 @@ class MsgpackDecoder:
279 ]
280 return UtilityResult(result)
281
280 - def _convert_result(self, result_type: Sequence[str], result: Any):
282 + def _convert_result(self, result_type: Sequence[str], result: Any) -> Any:
283 + if result_type is None:
284 + return result
285 mod_name, name = result_type
286 mod = importlib.import_module(mod_name)
287 result_type = getattr(mod, name)