add dflash gemma4 support (#27471)

Co-authored-by: kpham-sgl <khoa.pham@radixark.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Wang
2026-06-17 16:39:28 -07:00
committed by GitHub
co-authored by kpham-sgl Claude Opus 4.8
parent cd60c4edd0
commit 5ea0d1d093
4 changed files with 212 additions and 17 deletions
@@ -1127,6 +1127,14 @@ class Gemma4ForCausalLM(PreTrainedModel):
def dtype(self) -> torch.dtype:
return next(self.parameters()).dtype
def set_dflash_layers_to_capture(self, layer_ids: list[int]):
if layer_ids is None:
raise ValueError(
"DFLASH requires explicit layer_ids for aux hidden capture."
)
self.capture_aux_hidden_states = True
self.model.layers_to_capture = [val + 1 for val in layer_ids]
@torch.no_grad()
def forward(
self,
+8
View File
@@ -301,6 +301,14 @@ class Gemma4ForConditionalGeneration(PreTrainedModel):
def get_attention_sliding_window_size(self):
return getattr(self.config.text_config, "sliding_window", -1) - 1
def set_dflash_layers_to_capture(self, layer_ids: List[int]):
if layer_ids is None:
raise ValueError(
"DFLASH requires explicit layer_ids for aux hidden capture."
)
self.capture_aux_hidden_states = True
self.language_model.layers_to_capture = [val + 1 for val in layer_ids]
def prepare_attn_masks(
self,
forward_batch: ForwardBatch,
@@ -620,17 +620,27 @@ class DFlashWorkerV2(BaseSpecWorker):
if hidden_states.numel() == 0:
return torch.empty((0,), dtype=torch.long, device=hidden_states.device)
tp_group = get_tp_group()
tp_size = int(tp_group.world_size)
if not hasattr(lm_head, "weight") or not hasattr(lm_head, "shard_indices"):
raise RuntimeError(
"DFLASH greedy sampling requires a vocab-parallel head with `weight` and `shard_indices`."
)
shard = lm_head.shard_indices
weight = lm_head.weight # [local_vocab_padded, hidden]
weight_dtype = weight.dtype
num_tokens = int(hidden_states.shape[0])
out_tokens = torch.empty(
(num_tokens,), dtype=torch.long, device=hidden_states.device
)
def _cast_hs(x: torch.Tensor) -> torch.Tensor:
return x if x.dtype == weight_dtype else x.to(weight_dtype)
if not hasattr(lm_head, "shard_indices"):
for start in range(0, num_tokens, int(chunk_size)):
end = min(num_tokens, start + int(chunk_size))
hs = _cast_hs(hidden_states[start:end])
logits = torch.matmul(hs, weight.T)
out_tokens[start:end] = torch.argmax(logits, dim=-1).to(torch.long)
return out_tokens
shard = lm_head.shard_indices
tp_group = get_tp_group()
tp_size = int(tp_group.world_size)
# Valid ranges in the local shard (excluding padding):
# base vocab: [0, num_org)
@@ -641,14 +651,6 @@ class DFlashWorkerV2(BaseSpecWorker):
org_vocab_start = int(shard.org_vocab_start_index)
added_vocab_start = int(shard.added_vocab_start_index)
num_tokens = int(hidden_states.shape[0])
out_tokens = torch.empty(
(num_tokens,), dtype=torch.long, device=hidden_states.device
)
def _cast_hs(x: torch.Tensor) -> torch.Tensor:
return x if x.dtype == weight_dtype else x.to(weight_dtype)
def _ensure_local_reduce_buffers(
chunk_len: int,
value_dtype: torch.dtype,