Skip to content

test: Add e2e test for fast_inference vLLM path#7136

Open
JoshuaL3000 wants to merge 4 commits into
unslothai:mainfrom
JoshuaL3000:test/fast-inference-vllm
Open

test: Add e2e test for fast_inference vLLM path#7136
JoshuaL3000 wants to merge 4 commits into
unslothai:mainfrom
JoshuaL3000:test/fast-inference-vllm

Conversation

@JoshuaL3000

@JoshuaL3000 JoshuaL3000 commented Jul 15, 2026

Copy link
Copy Markdown

What This PR Does

This PR adds an end-to-end test script for the GRPO trainer when argument fast_inference=True from FastLanguageModel.from_pretrained() is set for vLLM rollout. This add a single test file tests/fast_inference/test_fast_inference.py.
The script can be run withpython tests/fast_inference/test_fast_inference.py. It is designed to match the end-to-end scripts under tests/qlora/.

Please let me know if any improvements are required and if the file location is appropriate.

Why

To add coverage for vLLM rollout on different devices.

Validation

This test passes on CUDA, but fails on Intel XPU hardware with AssertionError: Torch not compiled with CUDA enabled error, which is the aim this test captures.

Traceback:

[rank0]: Traceback (most recent call last):
[rank0]:   File "/home/sdp/joshua/repos/unsloth/tests/fast_inference/test_fast_inference.py", line 83, in <module>
[rank0]:     model, tokenizer = FastLanguageModel.from_pretrained(
[rank0]:                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/unsloth/unsloth/models/loader_utils.py", line 1073, in _wrapper
[rank0]:     return fn(*args, **kwargs)
[rank0]:            ^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/unsloth/unsloth/models/loader.py", line 838, in from_pretrained
[rank0]:     model, tokenizer = dispatch_model.from_pretrained(
[rank0]:                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/frameworks.ai.trainingframework.recipes/cri-sdv/RLonvLLM/.venv/lib/python3.12/site-packages/unsloth_zoo/temporary_patches/moe_grouped_modulelist.py", line 369, in wrapper
[rank0]:     result = func(*args, **kwargs)
[rank0]:              ^^^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/unsloth/unsloth/models/llama.py", line 2788, in from_pretrained
[rank0]:     _, quant_state_dict = get_vllm_state_dict(
[rank0]:                           ^^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/frameworks.ai.trainingframework.recipes/cri-sdv/RLonvLLM/.venv/lib/python3.12/site-packages/unsloth_zoo/vllm_utils.py", line 904, in get_vllm_state_dict
[rank0]:     return _get_vllm_state_dict(llm, return_state_dict, config, is_vision_model)
[rank0]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/frameworks.ai.trainingframework.recipes/cri-sdv/RLonvLLM/.venv/lib/python3.12/site-packages/unsloth_zoo/vllm_utils.py", line 947, in _get_vllm_state_dict
[rank0]:     capability = torch.cuda.get_device_capability()
[rank0]:                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/frameworks.ai.trainingframework.recipes/cri-sdv/RLonvLLM/.venv/lib/python3.12/site-packages/torch/cuda/__init__.py", line 682, in get_device_capability
[rank0]:     prop = get_device_properties(device)
[rank0]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/frameworks.ai.trainingframework.recipes/cri-sdv/RLonvLLM/.venv/lib/python3.12/site-packages/torch/cuda/__init__.py", line 699, in get_device_properties
[rank0]:     _lazy_init()  # will define _get_device_properties
[rank0]:     ^^^^^^^^^^^^
[rank0]:   File "/home/sdp/joshua/repos/frameworks.ai.trainingframework.recipes/cri-sdv/RLonvLLM/.venv/lib/python3.12/site-packages/torch/cuda/__init__.py", line 484, in _lazy_init
[rank0]:     raise AssertionError("Torch not compiled with CUDA enabled")
[rank0]: AssertionError: Torch not compiled with CUDA enabled

Environments

NVIDIA A100 (CUDA):

  • unsloth 2026.7.2
  • unsloth-zoo 2026.7.2
  • torch 2.11.0+cu130 (to match vllm version)
  • triton 3.7.0
  • trl 1.8.0
  • vllm 0.23.0

Intel Arc Pro B60 (XPU):

  • unsloth 2026.7.1
  • unsloth-zoo 2026.7.1
  • torch 2.12.0+xpu
  • triton-xpu 3.7.1
  • trl 1.8.0
  • vllm 0.23.1rc1.dev920+gdd127d82e.xpu (Built from source)
  • vllm-xpu-kernels 0.1.10.1

@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 new test file tests/fast_inference/test_fast_inference.py to verify GRPO training with the fast_inference=True vLLM rollout path. The review feedback suggests dynamically selecting the tensor data type (falling back to torch.float16 if bfloat16 is not supported) to prevent runtime errors on older GPUs, and correcting misleading type hints in the helper function get_unsloth_peft_model.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread tests/fast_inference/test_fast_inference.py
Comment thread tests/fast_inference/test_fast_inference.py Outdated
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=MODEL_NAME,
max_seq_length=MAX_SEQ_LENGTH,
dtype=torch.bfloat16,

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

Dynamically select the tensor data type (e.g., using torch.bfloat16 only if supported, falling back to torch.float16) to prevent runtime errors on devices that do not natively support bfloat16.

Suggested change
dtype=torch.bfloat16,
dtype=torch.bfloat16 if is_bfloat16_supported() else torch.float16,
References
  1. When probing GPU capabilities or running test kernels on older GPUs (such as Turing/Volta, sm < 80), dynamically select the tensor data type (e.g., using torch.bfloat16 only if supported, falling back to torch.float16) to prevent runtime errors on devices that do not natively support bfloat16.

pre-commit-ci Bot and others added 3 commits July 15, 2026 07:43
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b46889498

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

)


if __name__ == "__main__":

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Expose the fast-inference scenario to pytest

In the repo CPU workflow I checked, .github/workflows/studio-backend-ci.yml runs python -m pytest tests/ and does not ignore tests/fast_inference, but pytest will only import this file because the actual model load/train path is guarded by if __name__ == "__main__". That means CI, and anyone invoking pytest tests/fast_inference, gets no executable assertions for this new test, so regressions in the vLLM fast_inference path this file is meant to catch won't fail. Please wrap the body in a test_* function with appropriate GPU/vLLM marks/skips, or add the script to an explicit runner.

Useful? React with 👍 / 👎.

Comment on lines +127 to +133
trainer = GRPOTrainer(
model=model,
processing_class=tokenizer,
reward_funcs=[length_reward_func],
args=training_args,
train_dataset=dataset,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Assert GRPO binds the fast-inference engine

This instantiation never verifies that GRPOTrainer actually switches to the colocated vLLM rollout backed by model.vllm_engine; if the Unsloth patch that sets args.use_vllm or assigns self.llm = model.vllm_engine regresses, training can still succeed via the normal generation path and this test would pass despite not exercising the path it claims to cover. After constructing the trainer, please assert the vLLM mode/engine binding (for example that the trainer's llm is the model's vllm_engine) before calling train().

Useful? React with 👍 / 👎.

Comment on lines +48 to +51
def length_reward_func(completions, **kwargs) -> list[float]:
"""Simple reward: prefer non-empty completions."""
responses = [completion[0]["content"] for completion in completions]
return [1.0 if len(r) > 0 else 0.0 for r in responses]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Make the reward produce non-zero GRPO advantages

When both generations for a prompt are non-empty — the normal case for this model — this reward gives every completion in the GRPO group the same score, so the group-normalized advantages are zero and the LoRA optimizer path can do no meaningful update while trainer.train() still returns successfully. If this is meant to be an end-to-end GRPO training check, use a reward that creates variation within each prompt group or assert that adapter weights changed.

Useful? React with 👍 / 👎.

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.

1 participant