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)