liger-kernel-nightly 0.5.10.dev20250624183504__py3-none-any.whl → 0.6.3.dev20251121010306__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of liger-kernel-nightly might be problematic. Click here for more details.

Files changed (68) hide show
  1. liger_kernel/chunked_loss/__init__.py +1 -0
  2. liger_kernel/chunked_loss/cosine_similarity_loss.py +136 -0
  3. liger_kernel/chunked_loss/dpo_loss.py +54 -3
  4. liger_kernel/chunked_loss/functional.py +2 -0
  5. liger_kernel/chunked_loss/fused_linear_distillation.py +13 -2
  6. liger_kernel/chunked_loss/fused_linear_ppo.py +4 -0
  7. liger_kernel/chunked_loss/grpo_loss.py +38 -4
  8. liger_kernel/chunked_loss/jsd_loss.py +23 -7
  9. liger_kernel/ops/cross_entropy.py +118 -62
  10. liger_kernel/ops/fused_add_rms_norm.py +412 -0
  11. liger_kernel/ops/fused_linear_cross_entropy.py +113 -21
  12. liger_kernel/ops/geglu.py +1 -1
  13. liger_kernel/ops/layer_norm.py +124 -89
  14. liger_kernel/ops/llama4_rope.py +225 -0
  15. liger_kernel/ops/poly_norm.py +386 -0
  16. liger_kernel/ops/rms_norm.py +2 -2
  17. liger_kernel/ops/rope.py +1 -1
  18. liger_kernel/ops/swiglu.py +1 -1
  19. liger_kernel/ops/tiled_mlp.py +136 -0
  20. liger_kernel/transformers/__init__.py +50 -0
  21. liger_kernel/transformers/cross_entropy.py +8 -3
  22. liger_kernel/transformers/experimental/__init__.py +5 -0
  23. liger_kernel/transformers/functional.py +38 -6
  24. liger_kernel/transformers/fused_add_rms_norm.py +39 -0
  25. liger_kernel/transformers/fused_linear_cross_entropy.py +16 -4
  26. liger_kernel/transformers/llama4_rope.py +93 -0
  27. liger_kernel/transformers/model/falcon_h1.py +122 -0
  28. liger_kernel/transformers/model/gemma.py +28 -8
  29. liger_kernel/transformers/model/gemma2.py +31 -8
  30. liger_kernel/transformers/model/gemma3.py +100 -110
  31. liger_kernel/transformers/model/glm4.py +18 -5
  32. liger_kernel/transformers/model/glm4v.py +163 -0
  33. liger_kernel/transformers/model/glm4v_moe.py +172 -0
  34. liger_kernel/transformers/model/internvl.py +157 -0
  35. liger_kernel/transformers/model/llama.py +26 -7
  36. liger_kernel/transformers/model/llama4.py +121 -0
  37. liger_kernel/transformers/model/llava.py +18 -6
  38. liger_kernel/transformers/model/loss_utils.py +34 -3
  39. liger_kernel/transformers/model/mistral.py +17 -10
  40. liger_kernel/transformers/model/mixtral.py +24 -9
  41. liger_kernel/transformers/model/mllama.py +18 -7
  42. liger_kernel/transformers/model/olmo2.py +18 -5
  43. liger_kernel/transformers/model/output_classes.py +147 -0
  44. liger_kernel/transformers/model/paligemma.py +41 -5
  45. liger_kernel/transformers/model/phi3.py +24 -159
  46. liger_kernel/transformers/model/qwen2.py +26 -4
  47. liger_kernel/transformers/model/qwen2_5_vl.py +21 -8
  48. liger_kernel/transformers/model/qwen2_vl.py +24 -7
  49. liger_kernel/transformers/model/qwen3.py +22 -6
  50. liger_kernel/transformers/model/qwen3_moe.py +27 -7
  51. liger_kernel/transformers/model/qwen3_next.py +146 -0
  52. liger_kernel/transformers/model/qwen3_vl.py +150 -0
  53. liger_kernel/transformers/model/qwen3_vl_moe.py +126 -0
  54. liger_kernel/transformers/model/smollm3.py +199 -0
  55. liger_kernel/transformers/model/smolvlm.py +158 -0
  56. liger_kernel/transformers/monkey_patch.py +1090 -116
  57. liger_kernel/transformers/multi_token_attention.py +1 -1
  58. liger_kernel/transformers/poly_norm.py +42 -0
  59. liger_kernel/transformers/rms_norm.py +7 -0
  60. liger_kernel/transformers/rope.py +43 -0
  61. liger_kernel/transformers/tiled_mlp.py +133 -0
  62. {liger_kernel_nightly-0.5.10.dev20250624183504.dist-info → liger_kernel_nightly-0.6.3.dev20251121010306.dist-info}/METADATA +26 -24
  63. liger_kernel_nightly-0.6.3.dev20251121010306.dist-info/RECORD +116 -0
  64. liger_kernel_nightly-0.5.10.dev20250624183504.dist-info/RECORD +0 -95
  65. {liger_kernel_nightly-0.5.10.dev20250624183504.dist-info → liger_kernel_nightly-0.6.3.dev20251121010306.dist-info}/LICENSE +0 -0
  66. {liger_kernel_nightly-0.5.10.dev20250624183504.dist-info → liger_kernel_nightly-0.6.3.dev20251121010306.dist-info}/NOTICE +0 -0
  67. {liger_kernel_nightly-0.5.10.dev20250624183504.dist-info → liger_kernel_nightly-0.6.3.dev20251121010306.dist-info}/WHEEL +0 -0
  68. {liger_kernel_nightly-0.5.10.dev20250624183504.dist-info → liger_kernel_nightly-0.6.3.dev20251121010306.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,28 @@
1
1
  from typing import Optional
2
+ from typing import Tuple
2
3
 
3
4
  import torch
4
5
  import torch.nn as nn
5
6
 
6
7
  import liger_kernel.transformers.functional as F
7
8
 
9
+ from liger_kernel.transformers.functional import CrossEntropyOutput
10
+
11
+
12
+ def unpack_cross_entropy_result(
13
+ result,
14
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[torch.Tensor]]:
15
+ if isinstance(result, CrossEntropyOutput):
16
+ return result.loss, result.z_loss, result.token_accuracy
17
+
18
+ if isinstance(result, tuple):
19
+ loss = result[0]
20
+ z_loss = result[1] if len(result) > 1 else None
21
+ token_accuracy = result[2] if len(result) > 2 else None
22
+ return loss, z_loss, token_accuracy
23
+
24
+ return result, None, None
25
+
8
26
 
9
27
  def fixed_fused_linear_cross_entropy(
10
28
  hidden_states: torch.Tensor,
@@ -13,20 +31,31 @@ def fixed_fused_linear_cross_entropy(
13
31
  num_items_in_batch: Optional[int] = None,
14
32
  ignore_index: int = -100,
15
33
  final_logit_softcapping: Optional[float] = None,
34
+ accum_dtype: Optional[torch.dtype] = None,
35
+ return_token_accuracy: bool = False,
16
36
  **kwargs,
17
37
  ):
18
38
  reduction = "sum" if num_items_in_batch is not None else "mean"
19
- loss = F.liger_fused_linear_cross_entropy(
39
+ result = F.liger_fused_linear_cross_entropy(
20
40
  hidden_states,
21
41
  lm_head_weight,
22
42
  target,
23
43
  reduction=reduction,
24
44
  ignore_index=ignore_index,
25
45
  softcap=final_logit_softcapping,
46
+ accum_dtype=accum_dtype,
47
+ return_token_accuracy=return_token_accuracy,
48
+ **kwargs,
26
49
  )
50
+
51
+ loss, _, token_accuracy = unpack_cross_entropy_result(result)
52
+
27
53
  if reduction == "sum":
28
54
  loss = loss / num_items_in_batch
29
55
 
56
+ if return_token_accuracy:
57
+ return CrossEntropyOutput(loss=loss, token_accuracy=token_accuracy)
58
+
30
59
  return loss
31
60
 
32
61
 
@@ -39,6 +68,7 @@ def LigerForCausalLMLoss(
39
68
  ignore_index: int = -100,
40
69
  shift_labels: Optional[torch.Tensor] = None,
41
70
  final_logit_softcapping: Optional[float] = None,
71
+ return_token_accuracy: bool = False,
42
72
  **kwargs,
43
73
  ):
44
74
  # Skip upcast since intermediate values for the loss are all fp32 in kernel
@@ -52,13 +82,14 @@ def LigerForCausalLMLoss(
52
82
  shift_labels = shift_labels.view(-1)
53
83
  # Enable model parallelism
54
84
  shift_labels = shift_labels.to(hidden_states.device)
55
- loss = fixed_fused_linear_cross_entropy(
85
+ result = fixed_fused_linear_cross_entropy(
56
86
  hidden_states,
57
87
  lm_head_weight,
58
88
  shift_labels,
59
89
  num_items_in_batch,
60
90
  ignore_index,
61
91
  final_logit_softcapping,
92
+ return_token_accuracy=return_token_accuracy,
62
93
  **kwargs,
63
94
  )
64
- return loss
95
+ return result
@@ -6,10 +6,11 @@ from typing import Union
6
6
  import torch
7
7
 
8
8
  from transformers.cache_utils import Cache
9
- from transformers.modeling_outputs import CausalLMOutputWithPast
10
9
  from transformers.utils.deprecation import deprecate_kwarg
11
10
 
12
11
  from liger_kernel.transformers.model.loss_utils import LigerForCausalLMLoss
12
+ from liger_kernel.transformers.model.loss_utils import unpack_cross_entropy_result
13
+ from liger_kernel.transformers.model.output_classes import LigerCausalLMOutputWithPast
13
14
 
14
15
 
15
16
  @deprecate_kwarg("num_logits_to_keep", version="4.50", new_name="logits_to_keep")
@@ -29,7 +30,7 @@ def lce_forward(
29
30
  logits_to_keep: Union[int, torch.Tensor] = 0,
30
31
  skip_logits: Optional[bool] = None,
31
32
  **kwargs,
32
- ) -> Union[Tuple, CausalLMOutputWithPast]:
33
+ ) -> Union[Tuple, LigerCausalLMOutputWithPast]:
33
34
  r"""
34
35
  Copy paste Mistral's forward but replace torch cross entropy with liger fused linear cross entropy
35
36
 
@@ -94,6 +95,7 @@ def lce_forward(
94
95
  shift_labels = kwargs.pop("shift_labels", None)
95
96
  loss = None
96
97
  logits = None
98
+ token_accuracy = None
97
99
 
98
100
  if skip_logits and labels is None and shift_labels is None:
99
101
  raise ValueError("skip_logits is True, but labels and shift_labels are None")
@@ -101,8 +103,9 @@ def lce_forward(
101
103
  if skip_logits is None:
102
104
  skip_logits = self.training and (labels is not None or shift_labels is not None)
103
105
 
106
+ # Compute loss
104
107
  if skip_logits:
105
- loss = LigerForCausalLMLoss(
108
+ result = LigerForCausalLMLoss(
106
109
  hidden_states=kept_hidden_states,
107
110
  lm_head_weight=self.lm_head.weight,
108
111
  labels=labels,
@@ -110,29 +113,33 @@ def lce_forward(
110
113
  hidden_size=self.config.hidden_size,
111
114
  **kwargs,
112
115
  )
116
+ loss, _, token_accuracy = unpack_cross_entropy_result(result)
113
117
 
114
118
  else:
115
119
  logits = self.lm_head(kept_hidden_states)
116
120
 
117
121
  loss = None
118
- if labels is not None:
122
+ if labels is not None or shift_labels is not None:
119
123
  loss = self.loss_function(
120
124
  logits=logits,
121
125
  labels=labels,
126
+ shift_labels=shift_labels,
122
127
  vocab_size=self.config.vocab_size,
123
128
  **kwargs,
124
129
  )
130
+
125
131
  if not return_dict:
126
- output = (logits,) + outputs[1:]
127
- return (loss,) + output if loss is not None else output
132
+ output_tuple = (logits,) + outputs[1:]
133
+ output = (loss,) + output_tuple if loss is not None else output_tuple
134
+ output = output + (token_accuracy,) if token_accuracy is not None else output
135
+ return output
128
136
 
129
- return CausalLMOutputWithPast(
137
+ # Return custom output class with token_accuracy field
138
+ return LigerCausalLMOutputWithPast(
130
139
  loss=loss,
131
140
  logits=logits,
132
141
  past_key_values=outputs.past_key_values,
133
142
  hidden_states=outputs.hidden_states,
134
143
  attentions=outputs.attentions,
144
+ token_accuracy=token_accuracy,
135
145
  )
136
-
137
-
138
- # Note: Grad Acc is not fixed in mistral at transformer 4.46.1
@@ -12,6 +12,8 @@ from transformers.utils.deprecation import deprecate_kwarg
12
12
 
13
13
  from liger_kernel.transformers.fused_linear_cross_entropy import LigerFusedLinearCrossEntropyLoss
14
14
  from liger_kernel.transformers.model.loss_utils import LigerForCausalLMLoss
15
+ from liger_kernel.transformers.model.loss_utils import unpack_cross_entropy_result
16
+ from liger_kernel.transformers.model.output_classes import LigerMoeCausalLMOutputWithPast
15
17
 
16
18
 
17
19
  def lce_forward_deprecated(
@@ -158,7 +160,7 @@ def lce_forward(
158
160
  logits_to_keep: Union[int, torch.Tensor] = 0,
159
161
  skip_logits: Optional[bool] = None,
160
162
  **kwargs,
161
- ) -> Union[Tuple, MoeCausalLMOutputWithPast]:
163
+ ) -> Union[Tuple, LigerMoeCausalLMOutputWithPast]:
162
164
  r"""
163
165
  Args:
164
166
  labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
@@ -226,6 +228,7 @@ def lce_forward(
226
228
  shift_labels = kwargs.pop("shift_labels", None)
227
229
  logits = None
228
230
  loss = None
231
+ token_accuracy = None
229
232
 
230
233
  if skip_logits and labels is None and shift_labels is None:
231
234
  raise ValueError("skip_logits is True, but labels and shift_labels are None")
@@ -234,8 +237,9 @@ def lce_forward(
234
237
  # By default, if in training mode, don't materialize logits
235
238
  skip_logits = self.training and (labels is not None or shift_labels is not None)
236
239
 
240
+ # Compute loss
237
241
  if skip_logits:
238
- loss = LigerForCausalLMLoss(
242
+ result = LigerForCausalLMLoss(
239
243
  hidden_states=kept_hidden_states,
240
244
  lm_head_weight=self.lm_head.weight,
241
245
  labels=labels,
@@ -243,13 +247,20 @@ def lce_forward(
243
247
  hidden_size=self.config.hidden_size,
244
248
  **kwargs,
245
249
  )
250
+ loss, _, token_accuracy = unpack_cross_entropy_result(result)
246
251
 
247
252
  else:
248
253
  logits = self.lm_head(kept_hidden_states)
249
254
 
250
255
  loss = None
251
- if labels is not None:
252
- loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
256
+ if labels is not None or shift_labels is not None:
257
+ loss = self.loss_function(
258
+ logits=logits,
259
+ labels=labels,
260
+ shift_labels=shift_labels,
261
+ vocab_size=self.vocab_size,
262
+ **kwargs,
263
+ )
253
264
  aux_loss = None
254
265
  if output_router_logits:
255
266
  aux_loss = load_balancing_loss_func(
@@ -262,17 +273,21 @@ def lce_forward(
262
273
  loss += self.router_aux_loss_coef * aux_loss.to(loss.device) # make sure to reside in the same device
263
274
 
264
275
  if not return_dict:
265
- output = (logits,) + outputs[1:]
276
+ output_tuple = (logits,) + outputs[1:]
266
277
  if output_router_logits:
267
- output = (aux_loss,) + output
268
- return (loss,) + output if loss is not None else output
278
+ output_tuple = (aux_loss,) + output_tuple
279
+ if token_accuracy is not None:
280
+ output_tuple = output_tuple + (token_accuracy,)
281
+ return (loss,) + output_tuple if loss is not None else output_tuple
269
282
 
270
- return MoeCausalLMOutputWithPast(
283
+ # Return custom output class with token_accuracy field
284
+ return LigerMoeCausalLMOutputWithPast(
271
285
  loss=loss,
272
286
  aux_loss=aux_loss,
273
287
  logits=logits,
274
288
  past_key_values=outputs.past_key_values,
275
289
  hidden_states=outputs.hidden_states,
276
290
  attentions=outputs.attentions,
277
- router_logits=outputs.router_logits,
291
+ router_logits=outputs.router_logits if return_dict else outputs[-1],
292
+ token_accuracy=token_accuracy,
278
293
  )
@@ -12,6 +12,8 @@ from transformers.utils.deprecation import deprecate_kwarg
12
12
 
13
13
  from liger_kernel.transformers.fused_linear_cross_entropy import LigerFusedLinearCrossEntropyLoss
14
14
  from liger_kernel.transformers.model.loss_utils import LigerForCausalLMLoss
15
+ from liger_kernel.transformers.model.loss_utils import unpack_cross_entropy_result
16
+ from liger_kernel.transformers.model.output_classes import LigerCausalLMOutputWithPast
15
17
 
16
18
 
17
19
  def lce_forward_deprecated(
@@ -149,7 +151,7 @@ def lce_forward(
149
151
  logits_to_keep: Union[int, torch.Tensor] = 0,
150
152
  skip_logits: Optional[bool] = None,
151
153
  **kwargs,
152
- ) -> Union[Tuple, CausalLMOutputWithPast]:
154
+ ) -> Union[Tuple, LigerCausalLMOutputWithPast]:
153
155
  r"""
154
156
  Args:
155
157
  labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
@@ -190,7 +192,9 @@ def lce_forward(
190
192
  output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
191
193
  )
192
194
  return_dict = return_dict if return_dict is not None else self.config.use_return_dict
193
-
195
+ # Filter out accum_dtype from kwargs for model call as MllamaTextModel doesn't accept it in transformers 4.49.0
196
+ # but preserve it for loss function calls
197
+ model_kwargs = {k: v for k, v in kwargs.items() if k != "accum_dtype"}
194
198
  # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
195
199
  outputs = self.model(
196
200
  input_ids=input_ids,
@@ -206,7 +210,7 @@ def lce_forward(
206
210
  output_hidden_states=output_hidden_states,
207
211
  return_dict=return_dict,
208
212
  cache_position=cache_position,
209
- **kwargs,
213
+ **model_kwargs,
210
214
  )
211
215
 
212
216
  hidden_states = outputs[0]
@@ -217,6 +221,7 @@ def lce_forward(
217
221
  shift_labels = kwargs.pop("shift_labels", None)
218
222
  logits = None
219
223
  loss = None
224
+ token_accuracy = None
220
225
 
221
226
  if skip_logits and labels is None and shift_labels is None:
222
227
  raise ValueError("skip_logits is True, but labels and shift_labels are None")
@@ -226,7 +231,7 @@ def lce_forward(
226
231
  skip_logits = self.training and (labels is not None or shift_labels is not None)
227
232
 
228
233
  if skip_logits:
229
- loss = LigerForCausalLMLoss(
234
+ result = LigerForCausalLMLoss(
230
235
  hidden_states=kept_hidden_states,
231
236
  lm_head_weight=self.lm_head.weight,
232
237
  labels=labels,
@@ -234,25 +239,31 @@ def lce_forward(
234
239
  hidden_size=self.config.hidden_size,
235
240
  **kwargs,
236
241
  )
242
+ loss, _, token_accuracy = unpack_cross_entropy_result(result)
237
243
 
238
244
  else:
239
245
  logits = self.lm_head(kept_hidden_states)
240
- if labels is not None:
246
+ if labels is not None or shift_labels is not None:
241
247
  loss = self.loss_function(
242
248
  logits=logits,
243
249
  labels=labels,
250
+ shift_labels=shift_labels,
244
251
  vocab_size=self.config.vocab_size,
245
252
  **kwargs,
246
253
  )
247
254
 
248
255
  if not return_dict:
249
256
  output = (logits,) + outputs[1:]
250
- return (loss,) + output if loss is not None else output
257
+ output = (loss,) + output if loss is not None else output
258
+ output = output + (token_accuracy,) if token_accuracy is not None else output
259
+ return output
251
260
 
252
- return CausalLMOutputWithPast(
261
+ # Return custom output class with token_accuracy field
262
+ return LigerCausalLMOutputWithPast(
253
263
  loss=loss,
254
264
  logits=logits,
255
265
  past_key_values=outputs.past_key_values,
256
266
  hidden_states=outputs.hidden_states,
257
267
  attentions=outputs.attentions,
268
+ token_accuracy=token_accuracy,
258
269
  )
@@ -5,10 +5,11 @@ from typing import Union
5
5
 
6
6
  import torch
7
7
 
8
- from transformers.modeling_outputs import CausalLMOutputWithPast
9
8
  from transformers.utils.deprecation import deprecate_kwarg
10
9
 
11
10
  from liger_kernel.transformers.model.loss_utils import LigerForCausalLMLoss
11
+ from liger_kernel.transformers.model.loss_utils import unpack_cross_entropy_result
12
+ from liger_kernel.transformers.model.output_classes import LigerCausalLMOutputWithPast
12
13
 
13
14
 
14
15
  @deprecate_kwarg("num_logits_to_keep", version="4.50", new_name="logits_to_keep")
@@ -28,7 +29,7 @@ def lce_forward(
28
29
  logits_to_keep: Union[int, torch.Tensor] = 0,
29
30
  skip_logits: Optional[bool] = None,
30
31
  **kwargs,
31
- ) -> Union[Tuple, CausalLMOutputWithPast]:
32
+ ) -> Union[Tuple, LigerCausalLMOutputWithPast]:
32
33
  r"""
33
34
  Args:
34
35
  labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
@@ -91,6 +92,7 @@ def lce_forward(
91
92
  shift_labels = kwargs.pop("shift_labels", None)
92
93
  logits = None
93
94
  loss = None
95
+ token_accuracy = None
94
96
 
95
97
  if skip_logits and labels is None and shift_labels is None:
96
98
  raise ValueError("skip_logits is True, but labels and shift_labels are None")
@@ -99,8 +101,9 @@ def lce_forward(
99
101
  # By default, if in training mode, don't materialize logits
100
102
  skip_logits = self.training and (labels is not None or shift_labels is not None)
101
103
 
104
+ # Compute loss
102
105
  if skip_logits:
103
- loss = LigerForCausalLMLoss(
106
+ result = LigerForCausalLMLoss(
104
107
  hidden_states=kept_hidden_states,
105
108
  lm_head_weight=self.lm_head.weight,
106
109
  labels=labels,
@@ -108,21 +111,31 @@ def lce_forward(
108
111
  hidden_size=self.config.hidden_size,
109
112
  **kwargs,
110
113
  )
114
+ loss, _, token_accuracy = unpack_cross_entropy_result(result)
111
115
 
112
116
  else:
113
117
  logits = self.lm_head(kept_hidden_states)
114
- if labels is not None:
118
+ if labels is not None or shift_labels is not None:
115
119
  loss = self.loss_function(
116
120
  logits=logits,
117
121
  labels=labels,
122
+ shift_labels=shift_labels,
118
123
  vocab_size=self.config.vocab_size,
119
124
  **kwargs,
120
125
  )
121
126
 
122
- return CausalLMOutputWithPast(
127
+ if not return_dict:
128
+ output = (logits,) + outputs[1:]
129
+ output = ((loss,) + output) if loss is not None else output
130
+ output = output + (token_accuracy,) if token_accuracy is not None else output
131
+ return output
132
+
133
+ # Return custom output class with token_accuracy field
134
+ return LigerCausalLMOutputWithPast(
123
135
  loss=loss,
124
136
  logits=logits,
125
137
  past_key_values=outputs.past_key_values,
126
138
  hidden_states=outputs.hidden_states,
127
139
  attentions=outputs.attentions,
140
+ token_accuracy=token_accuracy,
128
141
  )
@@ -0,0 +1,147 @@
1
+ """
2
+ Custom output classes for Liger-Kernel that extend transformers' ModelOutput classes
3
+ with optional token accuracy field.
4
+ """
5
+
6
+ from dataclasses import dataclass
7
+ from typing import Optional
8
+
9
+ import torch
10
+
11
+ from transformers.modeling_outputs import CausalLMOutputWithPast
12
+ from transformers.modeling_outputs import MoeCausalLMOutputWithPast
13
+
14
+ # The following model-specific outputs are optional and depend on the installed
15
+ # transformers version. Guard their imports so our module remains importable
16
+ # even when those models are not available in the environment.
17
+ try:
18
+ from transformers.models.gemma3.modeling_gemma3 import Gemma3CausalLMOutputWithPast as _Gemma3CausalLMOutputWithPast
19
+ except Exception:
20
+ _Gemma3CausalLMOutputWithPast = None
21
+
22
+ try:
23
+ from transformers.models.glm4v_moe.modeling_glm4v_moe import (
24
+ Glm4vMoeCausalLMOutputWithPast as _Glm4vMoeCausalLMOutputWithPast,
25
+ )
26
+ except Exception:
27
+ _Glm4vMoeCausalLMOutputWithPast = None
28
+
29
+ try:
30
+ from transformers.models.internvl.modeling_internvl import (
31
+ InternVLCausalLMOutputWithPast as _InternVLCausalLMOutputWithPast,
32
+ )
33
+ except Exception:
34
+ _InternVLCausalLMOutputWithPast = None
35
+
36
+ try:
37
+ from transformers.models.llava.modeling_llava import LlavaCausalLMOutputWithPast as _LlavaCausalLMOutputWithPast
38
+ except Exception:
39
+ _LlavaCausalLMOutputWithPast = None
40
+
41
+ try:
42
+ from transformers.models.paligemma.modeling_paligemma import (
43
+ PaliGemmaCausalLMOutputWithPast as _PaliGemmaCausalLMOutputWithPast,
44
+ )
45
+ except Exception:
46
+ _PaliGemmaCausalLMOutputWithPast = None
47
+
48
+ try:
49
+ from transformers.models.qwen2_5_vl.modeling_qwen2_5_vl import (
50
+ Qwen2_5_VLCausalLMOutputWithPast as _Qwen2_5_VLCausalLMOutputWithPast,
51
+ )
52
+ except Exception:
53
+ _Qwen2_5_VLCausalLMOutputWithPast = None
54
+
55
+ try:
56
+ from transformers.models.qwen2_vl.modeling_qwen2_vl import (
57
+ Qwen2VLCausalLMOutputWithPast as _Qwen2VLCausalLMOutputWithPast,
58
+ )
59
+ except Exception:
60
+ _Qwen2VLCausalLMOutputWithPast = None
61
+
62
+ try:
63
+ from transformers.models.qwen3_vl.modeling_qwen3_vl import (
64
+ Qwen3VLCausalLMOutputWithPast as _Qwen3VLCausalLMOutputWithPast,
65
+ )
66
+ except Exception:
67
+ _Qwen3VLCausalLMOutputWithPast = None
68
+
69
+ try:
70
+ from transformers.models.qwen3_vl_moe.modeling_qwen3_vl_moe import (
71
+ Qwen3VLMoeCausalLMOutputWithPast as _Qwen3VLMoeCausalLMOutputWithPast,
72
+ )
73
+ except Exception:
74
+ _Qwen3VLMoeCausalLMOutputWithPast = None
75
+
76
+
77
+ @dataclass
78
+ class LigerCausalLMOutputWithPast(CausalLMOutputWithPast):
79
+ token_accuracy: Optional[torch.FloatTensor] = None
80
+
81
+
82
+ @dataclass
83
+ class LigerMoeCausalLMOutputWithPast(MoeCausalLMOutputWithPast):
84
+ token_accuracy: Optional[torch.FloatTensor] = None
85
+
86
+
87
+ if _Gemma3CausalLMOutputWithPast is not None:
88
+
89
+ @dataclass
90
+ class LigerGemma3CausalLMOutputWithPast(_Gemma3CausalLMOutputWithPast):
91
+ token_accuracy: Optional[torch.FloatTensor] = None
92
+
93
+
94
+ if _Glm4vMoeCausalLMOutputWithPast is not None:
95
+
96
+ @dataclass
97
+ class LigerGlm4vMoeCausalLMOutputWithPast(_Glm4vMoeCausalLMOutputWithPast):
98
+ token_accuracy: Optional[torch.FloatTensor] = None
99
+
100
+
101
+ if _LlavaCausalLMOutputWithPast is not None:
102
+
103
+ @dataclass
104
+ class LigerLlavaCausalLMOutputWithPast(_LlavaCausalLMOutputWithPast):
105
+ token_accuracy: Optional[torch.FloatTensor] = None
106
+
107
+
108
+ if _InternVLCausalLMOutputWithPast is not None:
109
+
110
+ @dataclass
111
+ class LigerInternVLCausalLMOutputWithPast(_InternVLCausalLMOutputWithPast):
112
+ token_accuracy: Optional[torch.FloatTensor] = None
113
+
114
+
115
+ if _PaliGemmaCausalLMOutputWithPast is not None:
116
+
117
+ @dataclass
118
+ class LigerPaliGemmaCausalLMOutputWithPast(_PaliGemmaCausalLMOutputWithPast):
119
+ token_accuracy: Optional[torch.FloatTensor] = None
120
+
121
+
122
+ if _Qwen2_5_VLCausalLMOutputWithPast is not None:
123
+
124
+ @dataclass
125
+ class LigerQwen2_5_VLCausalLMOutputWithPast(_Qwen2_5_VLCausalLMOutputWithPast):
126
+ token_accuracy: Optional[torch.FloatTensor] = None
127
+
128
+
129
+ if _Qwen2VLCausalLMOutputWithPast is not None:
130
+
131
+ @dataclass
132
+ class LigerQwen2VLCausalLMOutputWithPast(_Qwen2VLCausalLMOutputWithPast):
133
+ token_accuracy: Optional[torch.FloatTensor] = None
134
+
135
+
136
+ if _Qwen3VLCausalLMOutputWithPast is not None:
137
+
138
+ @dataclass
139
+ class LigerQwen3VLCausalLMOutputWithPast(_Qwen3VLCausalLMOutputWithPast):
140
+ token_accuracy: Optional[torch.FloatTensor] = None
141
+
142
+
143
+ if _Qwen3VLMoeCausalLMOutputWithPast is not None:
144
+
145
+ @dataclass
146
+ class LigerQwen3VLMoeCausalLMOutputWithPast(_Qwen3VLMoeCausalLMOutputWithPast):
147
+ token_accuracy: Optional[torch.FloatTensor] = None
@@ -13,6 +13,9 @@ from transformers.utils import logging
13
13
  from transformers.utils.deprecation import deprecate_kwarg
14
14
 
15
15
  from liger_kernel.transformers.fused_linear_cross_entropy import LigerFusedLinearCrossEntropyLoss
16
+ from liger_kernel.transformers.model.loss_utils import LigerForCausalLMLoss
17
+ from liger_kernel.transformers.model.loss_utils import unpack_cross_entropy_result
18
+ from liger_kernel.transformers.model.output_classes import LigerPaliGemmaCausalLMOutputWithPast
16
19
 
17
20
  logger = logging.get_logger(__name__)
18
21
 
@@ -218,7 +221,7 @@ def lce_forward(
218
221
  logits_to_keep: Union[int, torch.Tensor] = 0,
219
222
  skip_logits: Optional[bool] = None,
220
223
  **lm_kwargs,
221
- ) -> Union[Tuple, PaliGemmaCausalLMOutputWithPast]:
224
+ ) -> Union[Tuple, LigerPaliGemmaCausalLMOutputWithPast]:
222
225
  r"""
223
226
  Args:
224
227
  labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
@@ -331,6 +334,7 @@ def lce_forward(
331
334
 
332
335
  loss = None
333
336
  logits = None
337
+ token_accuracy = None
334
338
 
335
339
  if skip_logits and labels is None:
336
340
  raise ValueError("skip_logits is True, but labels is None")
@@ -358,8 +362,16 @@ def lce_forward(
358
362
  shift_hidden_states = shift_hidden_states.view(-1, self.config.text_config.hidden_size)
359
363
  shift_labels = shift_labels.view(-1).to(hidden_device)
360
364
 
361
- lce = LigerFusedLinearCrossEntropyLoss()
362
- loss = lce(self.language_model.lm_head.weight, shift_hidden_states, shift_labels)
365
+ # Use LigerForCausalLMLoss with accuracy support and pass already shifted labels
366
+ result = LigerForCausalLMLoss(
367
+ hidden_states=shift_hidden_states,
368
+ lm_head_weight=self.language_model.lm_head.weight,
369
+ labels=None,
370
+ shift_labels=shift_labels,
371
+ hidden_size=self.config.text_config.hidden_size,
372
+ **lm_kwargs,
373
+ )
374
+ loss, _, token_accuracy = unpack_cross_entropy_result(result)
363
375
  else:
364
376
  logits = self.language_model.lm_head(hidden_states)
365
377
  if labels is not None:
@@ -382,15 +394,39 @@ def lce_forward(
382
394
  flat_logits = shift_logits.view(-1, self.config.text_config.vocab_size)
383
395
  flat_labels = shift_labels.view(-1).to(shift_logits.device)
384
396
  loss = loss_fct(flat_logits, flat_labels)
397
+ elif shift_labels is not None:
398
+ # Upcast to float if we need to compute the loss to avoid potential precision issues
399
+ logits = logits.float()
400
+ shift_logits = logits[..., :-1, :]
401
+ if attention_mask is not None:
402
+ # we use the input attention mask to shift the logits and labels, because it is 2D.
403
+ # we also crop attn mask in case it is longer, which happens in PrefixTuning with peft
404
+ shift_attention_mask = attention_mask[:, -shift_logits.shape[1] :].to(logits.device)
405
+ shift_logits = shift_logits[shift_attention_mask.to(logits.device) != 0].contiguous()
406
+ shift_labels = shift_labels[shift_attention_mask.to(shift_labels.device) != 0].contiguous()
407
+ else:
408
+ shift_logits = shift_logits.contiguous()
409
+ shift_labels = shift_labels.contiguous()
410
+ # Flatten the tokens
411
+ loss_fct = CrossEntropyLoss()
412
+
413
+ flat_logits = shift_logits.view(-1, self.config.text_config.vocab_size)
414
+ flat_labels = shift_labels.view(-1).to(shift_logits.device)
415
+ loss = loss_fct(flat_logits, flat_labels)
416
+
385
417
  if not return_dict:
386
418
  output = (logits,) + outputs[1:]
387
- return (loss,) + output if loss is not None else output
419
+ output = (loss,) + output if loss is not None else output
420
+ output = output + (token_accuracy,) if token_accuracy is not None else output
421
+ return output
388
422
 
389
- return PaliGemmaCausalLMOutputWithPast(
423
+ # Return PaliGemma output with token_accuracy field
424
+ return LigerPaliGemmaCausalLMOutputWithPast(
390
425
  loss=loss,
391
426
  logits=logits,
392
427
  past_key_values=outputs.past_key_values,
393
428
  hidden_states=outputs.hidden_states,
394
429
  attentions=outputs.attentions,
395
430
  image_hidden_states=image_features if pixel_values is not None else None,
431
+ token_accuracy=token_accuracy,
396
432
  )