Skip to content

Commit aaa48cf

Browse files
cf-icehzgzhmyname
authored andcommitted
fix: align Granite causal LM loss
Use shifted labels for causal loss and strengthen Granite loss and generation coverage.
1 parent 3ece187 commit aaa48cf

2 files changed

Lines changed: 28 additions & 10 deletions

File tree

paddleformers/transformers/granite/modeling.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,12 @@ def forward(
548548

549549
loss = None
550550
if labels is not None:
551-
flat_logits = logits.reshape([-1, logits.shape[-1]])
552-
flat_labels = labels.reshape([-1])
553-
valid = flat_labels != -100
554-
safe_labels = paddle.where(valid, flat_labels, paddle.zeros_like(flat_labels))
551+
shift_logits = logits[:, :-1].reshape([-1, logits.shape[-1]])
552+
shift_labels = labels[:, 1:].reshape([-1])
553+
valid = shift_labels != -100
554+
safe_labels = paddle.where(valid, shift_labels, paddle.zeros_like(shift_labels))
555555
selected_log_probs = paddle.take_along_axis(
556-
F.log_softmax(flat_logits, axis=-1), safe_labels.unsqueeze(-1), axis=-1
556+
F.log_softmax(shift_logits, axis=-1), safe_labels.unsqueeze(-1), axis=-1
557557
).squeeze(-1)
558558
valid_count = paddle.cast(valid, selected_log_probs.dtype).sum()
559559
loss = -(selected_log_probs * paddle.cast(valid, selected_log_probs.dtype)).sum() / valid_count

tests/transformers/granite/test_modeling.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717

1818
import paddle
1919

20-
from paddleformers.transformers import GraniteConfig, GraniteForCausalLM, GraniteModel
20+
from paddleformers.transformers import (
21+
GraniteConfig,
22+
GraniteForCausalLM,
23+
GraniteModel,
24+
)
2125
from tests.testing_utils import gpu_device_initializer
2226
from tests.transformers.test_configuration_common import ConfigTester
2327
from tests.transformers.test_generation_utils import GenerationTesterMixin
@@ -178,14 +182,28 @@ def create_and_check_lm_model(self, config, input_ids, input_mask, sequence_labe
178182
def create_and_check_loss(self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels):
179183
model = GraniteForCausalLM(config)
180184
model.eval()
181-
result = model(input_ids, labels=input_ids)
182-
self.parent.assertEqual(result[0].ndim, 0)
185+
labels = input_ids.clone()
186+
labels[:, :2] = -100
187+
result = model(input_ids, labels=labels, return_dict=True)
188+
shift_logits = result.logits[:, :-1].reshape([-1, config.vocab_size])
189+
shift_labels = labels[:, 1:].reshape([-1])
190+
valid = shift_labels != -100
191+
safe_labels = paddle.where(valid, shift_labels, paddle.zeros_like(shift_labels))
192+
selected_log_probs = paddle.take_along_axis(
193+
paddle.nn.functional.log_softmax(shift_logits, axis=-1), safe_labels.unsqueeze(-1), axis=-1
194+
).squeeze(-1)
195+
expected_loss = -(selected_log_probs * paddle.cast(valid, selected_log_probs.dtype)).sum() / paddle.cast(
196+
valid, selected_log_probs.dtype
197+
).sum()
198+
self.parent.assertTrue(paddle.allclose(result.loss, expected_loss, rtol=1e-5, atol=1e-5))
183199

184200
def create_and_check_generate(self, config, input_ids, input_mask):
185201
model = GraniteForCausalLM(config)
186202
model.eval()
187-
result = model.generate(input_ids, max_new_tokens=5, decode_strategy="greedy_search")
188-
self.parent.assertIsNotNone(result)
203+
generated = model.generate(input_ids, max_new_tokens=5, decode_strategy="greedy_search")
204+
if isinstance(generated, tuple):
205+
generated = generated[0]
206+
self.parent.assertEqual(generated.shape, [input_ids.shape[0], 5])
189207

190208
def prepare_config_and_inputs_for_common(self):
191209
config_and_inputs = self.prepare_config_and_inputs()

0 commit comments

Comments
 (0)