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:
co-authored by
kpham-sgl
Claude Opus 4.8
parent
cd60c4edd0
commit
5ea0d1d093
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user