@@ -1378,12 +1378,15 @@ def maybe_gather_sharded_draft_logits(self,
13781378 (see ``_draft_logits_are_sharded``); replicated full-vocab logits are
13791379 returned unchanged.
13801380
1381- Plain TP gathers vocab shards over ``self.mapping``. Under ADP + LM-head
1382- TP the worker has already trimmed the LM-head-TP padding rows so each rank
1383- holds ``[token_count, vocab_shard]`` for its own tokens; a vocab-dim
1384- all-gather over ``mapping_lm_head_tp`` restores full vocab (no token
1385- re-slice is needed after the trim).
1386- """
1381+ Plain TP gathers vocab shards over ``self.mapping``. ADP + LM-head TP
1382+ never reaches this path: rejection sampling (the only consumer of
1383+ advanced draft sampling) is config-gated off under attention DP, and
1384+ the group-stacked sharded logits it produces are handled by the greedy
1385+ path in ``greedy_sample_draft_with_tp_gather``.
1386+ """
1387+ assert mapping_lm_head_tp is None , (
1388+ "Advanced draft sampling is not supported under ADP + LM-head TP "
1389+ "(rejection sampling is config-gated off with attention DP)" )
13871390 if (spec_metadata is None or spec_metadata .is_all_greedy_sample
13881391 or not self ._draft_logits_are_sharded (logits , spec_metadata )):
13891392 return logits
@@ -1750,7 +1753,26 @@ def greedy_sample_draft_with_tp_gather(self,
17501753 vocab-sharded (see ``_draft_logits_are_sharded``) -- e.g. a borrowed or
17511754 gathered full-vocab draft head. Returns tokens in draft-vocab space (the
17521755 caller applies d2t). Expects 2D ``[num_tokens, vocab_shard]`` logits.
1756+
1757+ Under ADP + LM-head TP (``mapping_lm_head_tp`` given) the logits are the
1758+ LM-head-TP group's row-stacked batch (``tp_size`` segments of
1759+ ``max_num_requests`` padded rows, all-gathered along dim 0 by the MTP
1760+ shared head) with the vocab sharded across the group. The global argmax
1761+ must combine the group's vocab shards, and each rank must read its own
1762+ row segment at offset ``tp_rank * max_num_requests`` -- NOT rows
1763+ ``[:batch]``, which belong to group rank 0.
17531764 """
1765+ if (mapping_lm_head_tp is not None
1766+ and getattr (mapping_lm_head_tp , "tp_size" , 1 ) > 1 ):
1767+ from ..distributed .ops import allgather
1768+ combined = self ._get_local_max_and_combined (logits ,
1769+ mapping_lm_head_tp )
1770+ gathered = allgather (combined , mapping_lm_head_tp , dim = - 1 )
1771+ group_size = mapping_lm_head_tp .tp_size
1772+ local_rows = logits .shape [0 ] // group_size
1773+ own_segment = gathered .view (group_size , local_rows ,
1774+ - 1 )[mapping_lm_head_tp .tp_rank ]
1775+ return self ._get_draft_tokens_from_gathered (own_segment )
17541776 mapping = self .mapping
17551777 sharded = self ._draft_logits_are_sharded (logits , spec_metadata )
17561778 if (sharded and mapping is not None
@@ -1760,9 +1782,9 @@ def greedy_sample_draft_with_tp_gather(self,
17601782 combined = self ._get_local_max_and_combined (logits )
17611783 gathered = allgather (combined , mapping , dim = - 1 )
17621784 return self ._get_draft_tokens_from_gathered (gathered )
1763- # No TP gather for attention-DP (incl. ADP + LM-head TP) : each rank owns
1764- # its own requests , so a per-rank argmax is the correct proposal and a
1765- # cross-rank gather here would desync the ranks (see
1785+ # No cross-rank gather for plain attention-DP: each rank owns its own
1786+ # requests with replicated full-vocab logits , so a per-rank argmax is
1787+ # the correct proposal and a gather would desync the ranks (see
17661788 # _draft_logits_are_sharded). Plain argmax; caller applies d2t.
17671789 return torch .argmax (logits , dim = - 1 ).type (torch .int32 )
17681790
@@ -1908,7 +1930,12 @@ def sample_draft_tokens(self,
19081930 tokens = self .greedy_sample_draft_with_tp_gather (
19091931 logits .reshape (- 1 , logits .shape [- 1 ]), spec_metadata ,
19101932 mapping_lm_head_tp )
1911- tokens = tokens .reshape (batch_shape )
1933+ if mapping_lm_head_tp is None :
1934+ tokens = tokens .reshape (batch_shape )
1935+ # else: ADP+LM-head-TP (2D step form only) -- the sampler returned
1936+ # this rank's own row segment, 1/tp_size of the stacked input rows,
1937+ # so the input batch shape no longer applies. Keep as-is; the
1938+ # caller trims the max_num_requests padding to token_count.
19121939 else :
19131940 # Advanced sampling gathers the vocab-sharded draft logits to full
19141941 # vocab, then samples (scattering this step's proposal distribution
0 commit comments