Repository navigation
Conversation
Datasets formatted with `with_format("torch")` give each label as a tensor.
A 0-dim tensor passes the collator's `Collection` check, so scalar labels
were collated into a list of tensors instead of one tensor, and the
default CrossEncoderTrainer losses (BinaryCrossEntropyLoss and
CrossEntropyLoss) as well as MSELoss failed on the first step. Stack 0-dim
tensor labels, and keep tensor label lists as one tensor per sample
without copying them. Python-valued labels take the same path as before.
#4231 fixed this in BaseDataCollator, but CrossEncoderDataCollator has its
own label handling.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Member
|
Hello! Thanks for the fix! I verified the regression and pushed a few small simplifications to the comments and tests. The relevant tests pass, and this looks good to me.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CrossEncoderTrainerfails on the first training step when the label column is formatted as tensors, for example afterdataset.with_format("torch"), or afterload_from_diskon a dataset that was saved with that format. #4231 fixed this inBaseDataCollator, butCrossEncoderDataCollatoroverrides__call__with its own label handling, so CrossEncoder training still has the problem.A 0-dim tensor counts as a
collections.abc.Collection, so the collator treats each scalar label as a list of labels and returns a Python list of 0-dim tensors instead of one tensor. The pointwise losses then fail, including both losses thatCrossEncoderTraineruses by default:BinaryCrossEntropyLoss(default fornum_labels=1)AttributeError: 'list' object has no attribute 'numel'CrossEntropyLoss(default fornum_labels>1)AttributeError: 'list' object has no attribute 'is_floating_point'MSELossAttributeError: 'list' object has no attribute 'numel'Minimal reproducer:
I found this through code analysis while checking which collators #4231 covers, not in actual use. I then trained each CrossEncoder loss for two steps on a small local model, with an unformatted and a torch-formatted dataset: the three losses above fail on main and pass with this change.
MarginMSELossand the listwise losses already accept a list of labels, so they ran, but every tensor row went throughtorch.tensor(tensor), which copies it and emits aUserWarning.Change
When the labels are tensors, stack 0-dim ones into one tensor, and keep larger ones as the per-sample list that the listwise losses expect, without copying them. Python-valued labels take the same path as before.
Tests
tests/cross_encoder/test_data_collator.py(new): torch-formatted float and integer labels collate to the same tensor as the unformatted dataset, and torch-formatted label lists stay one tensor per sample.tests/cross_encoder/test_trainer.py::test_trainer_tensor_formatted_labels: oneCrossEncoderTrainerstep with the default loss fornum_labels=1andnum_labels=3on a torch-formatted dataset. The model is a small randomly initializedBertForSequenceClassificationbuilt in the test, so nothing is downloaded. The step completes, and the weights change and stay finite.ruff check,ruff format --checkandtypospass on the changed files. I had no Hub access, so the CrossEncoder tests that download models did not run: intests/cross_encoderandtests/base/test_data_collator.py, the same tests fail on main and on this branch, all with download errors. GPU training and the minimum-versions setup were not run.AI assistance
This PR was prepared with Claude Code, which found the issue and wrote the fix, the tests and this description.
🤖 Generated with Claude Code