Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions tensorrt_llm/_torch/models/dspark/draft.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@
from .heads import confident_prefix_length


def resolve_noise_token_id(mask_token_id: Optional[int], config, ckpt_attr: str) -> int:
"""Resolve the DSpark noise/mask token id.

``mask_token_id`` is the speculative config's value, either indicated in ``DSparkDecodingConfig``
validation. ``None`` falls back to the drafter checkpoint's ``ckpt_attr``,
else ``vocab_size``.
"""
if mask_token_id is None:
mask_token_id = getattr(config, ckpt_attr, None)
if mask_token_id is None:
mask_token_id = config.vocab_size

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The config.vocab_size fallback produces an out-of-range token id for the Qwen3 drafter: embed_tokens is the target's nn.Embedding(vocab_size, hidden), so embedding id vocab_size triggers a device-side assert deep inside the first draft forward — a hard-to-diagnose failure mode. Since the DeepSpec checkpoints always carry mask_token_id, raising a clear ValueError when both the spec config and the checkpoint attribute are missing would fail fast with an actionable message. (The fallback predates this PR on the V4 path, but now that the helper is shared it's worth hardening.) Separately, the docstring's first sentence is truncated: "either indicated in DSparkDecodingConfig validation" doesn't parse.

return int(mask_token_id)


def build_draft_input_ids(
bonus_token_ids: torch.Tensor, *, block_size: int, noise_token_id: int
) -> torch.Tensor:
Expand Down
14 changes: 11 additions & 3 deletions tensorrt_llm/_torch/models/dspark/heads.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,22 @@ class DSparkConfidenceHead(nn.Module):
Markov head's previous-token embedding. Output is a single logit per position.
"""

def __init__(self, *, hidden_size: int, markov_rank: int = 0, with_markov: bool = False):
def __init__(
self,
*,
hidden_size: int,
markov_rank: int = 0,
with_markov: bool = False,
bias: bool = False,
):
super().__init__()
self.with_markov = bool(with_markov)
input_dim = int(hidden_size) + (int(markov_rank) if with_markov else 0)
# The checkpoint stores ``proj`` as a bias-free bf16 weight, but the
# The V4-Pro checkpoint stores ``proj`` as a bias-free bf16 weight; the
# DeepSpec Qwen3 drafter checkpoints carry a bias. Either way the
# confidence score is computed in fp32 (mirrors the DeepSpec reference
# ``Linear(input_dim, 1, dtype=torch.float32)`` with the fp32 matmul).
self.proj = nn.Linear(input_dim, 1, bias=False, dtype=torch.float32)
self.proj = nn.Linear(input_dim, 1, bias=bias, dtype=torch.float32)

def forward(
self, hidden_states: torch.Tensor, prev_embeddings: Optional[torch.Tensor] = None
Expand Down
Loading
Loading