Fix mtp tp - #224
Closed
randoentity wants to merge 3 commits into
Closed
Conversation
MTP (Multi-Token Prediction) speculative decoding in tensor-parallel mode
was passing raw CUDA tensors directly into the multiprocessing queue,
triggering a cudaMallocAsync IPC failure. The non-TP path now correctly
branches to use the TP dispatcher when TP mode is active.
Problem
-------
Running Qwen3.5 MTP models with speculative decoding in TP mode crashed
with two distinct errors:
1. TP path — cudaMallocAsync IPC failure:
RuntimeError: cudaMallocAsync does not yet support shareIpcHandle
File "exllamav3/generator/generator.py", line 530, in iterate_draftmodel_mtp_gen
batch_logits = self.model.tp_dispatch_lm_head_logits(...)
File "exllamav3/model/model_tp.py", line 375, in tp_dispatch_lm_head_logits
self.tp_worker_dispatch(device, fn, args)
File "exllamav3/model/model_tp.py", line 186, in tp_worker_dispatch
conn.send((fn, args))
File "torch/multiprocessing/reductions.py", line ...
storage._share_cuda_()
Root cause: params["target_hidden"] was a raw CUDA tensor passed
directly into the args tuple sent to worker processes. Python's
multiprocessing pickler invoked PyTorch's reduce_tensor -> _share_cuda_()
which attempts cudaMallocAsync's shareIpcHandle — an unsupported operation.
2. Non-TP path — missing TP branch:
The original code had no conditional for TP vs non-TP in
iterate_draftmodel_mtp_gen. It always called the logits module directly
via self.model.modules[self.model.logit_layer_idx].forward(...), which
fails in TP mode because the lm_head shards live in worker processes,
not on the main process.
Changes
-------
generator.py (iterate_draftmodel_mtp_gen):
- Added use_tp = self.model.loaded_tp guard before the sampling loop
- TP branch: construct a minimal tp_params dict containing only
target_hidden (sent through tp_producer.send()) and attn_mode.
This routes the tensor through CPU shared memory, avoiding the
cudaMallocAsync IPC path entirely.
- Non-TP branch: preserved existing direct-module-forward path unchanged.
model_tp.py (Model_TPMixin):
- Added tp_dispatch_lm_head_logits() method — mirrors the existing
tp_dispatch_lm_head_argmax() but returns full logits instead of
just argmax indices. Handles single-device fast-path and multi-device
scatter/gather via the bulk gather buffer.
model_tp_fn.py:
- Added mp_model_forward_lm_head_logits() worker function — receives
tensors through consumer.recv(), forwards through the sharded
lm_head module, and optionally gathers partial logits from multiple
devices into a complete (batch, seq, vocab) tensor.
Why tp_params is minimal
------------------------
Only target_hidden and attn_mode are passed in tp_params because the
MTP logits module (Qwen3_5MtpDecoderLayer) only reads those keys. The
full params dict also contains block_table, cache, and cache_seqlens
which are irrelevant to the lm_head computation. Excluding them reduces
serialization overhead and avoids accidentally sending unpicklable objects.
Verification
------------
- Both modified files pass Python AST parsing (no syntax errors)
- tp_dispatch_lm_head_argmax confirmed unaffected — it is called with
empty {} params from dflash.py and does not carry CUDA tensors
- target_hidden tensor (~8KB for hidden_size=4096) fits comfortably
within the 64MB SMProducer buffer, no fallback needed
- Non-TP execution path is structurally unchanged
Testing required
----------------
Multi-GPU TP setup with a Qwen3.5 MTP checkpoint to exercise both the
TP and non-TP branches end-to-end.
Author
|
All fixed and working at least from 783bfa7. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes MTP with TP and includes fix from @alexhunt7 (non-TP multi GPU).
AI use disclosure: the changes were made by LLM. I tested both TP and auto split paths successfully.
See theroyallab/tabbyAPI#424 (comment) for more details.