-
Notifications
You must be signed in to change notification settings - Fork 720
Description
I've faced the following issues with the multi-label classification functionality when use_multiprocessing=False is set. This affects both training and prediction workflows.
Bug Description
Location: simpletransformers/classification/classification_utils.py, line 344
Issue: The build_classification_dataset function incorrectly uses torch.long dtype for multi-label classification when multiprocessing is disabled:
if output_mode == "classification":
labels = torch.tensor(labels, dtype=torch.long) # BUG: Should be torch.float for multi-label
elif output_mode == "regression":
labels = torch.tensor(labels, dtype=torch.float)Error Details
Error Message:
TypeError: only integer tensors of a single element can be converted to an indexStack Trace:
File "simpletransformers/classification/classification_utils.py", line 344, in build_classification_dataset
labels = torch.tensor(labels, dtype=torch.long)
TypeError: only integer tensors of a single element can be converted to an indexReproduction Steps
- Create multi-label training data with labels as lists:
[[1,0,1,0], [0,1,0,1], ...] - Set model args with
use_multiprocessing=Falseanduse_multiprocessing_for_evaluation=False - Call
model.train_model()ormodel.predict() - Error occurs in
build_classification_datasetfunction
Possible Root Cause
The bug occurs might be due to:
- Multi-label data requires
torch.floatdtype, nottorch.long - The function doesn't distinguish between single-label and multi-label classification
- When multiprocessing is enabled, the data goes through a different processing pipeline that handles this correctly. But it causes another hanging issues.
- When multiprocessing is disabled, it hits the broken
build_classification_datasetfunction
Additional Info
- Training fails for multi-label classification with disabled multiprocessing
- Prediction fails even when training succeeds (using HuggingFace datasets workaround)
- Forces users to enable multiprocessing, which can cause deadlocks and hanging issues
- Inconsistent behavior between multiprocessing enabled/disabled modes
Sample code I am using:
import logging
import pandas as pd
from simpletransformers.classification import (
MultiLabelClassificationModel,
MultiLabelClassificationArgs,
)
logging.basicConfig(level=logging.INFO)
transformers_logger = logging.getLogger("transformers")
transformers_logger.setLevel(logging.WARNING)
# Train and Evaluation data needs to be in a Pandas Dataframe of two columns. The first column is the text with type str, and the second column in the label with type int.
train_data = [["Example sentence 1 for multilabel", [1, 1, 1, 1, 0, 1]]] + [
["This thing is entirely different from the other thing. ", [0, 1, 1, 0, 0, 0]]
]
train_df = pd.DataFrame(train_data, columns=["text", "labels"])
eval_data = [
["Example sentence belonging to class 1", [1, 1, 1, 1, 0, 1]],
[
"This thing should be entirely different from the other thing. ",
[0, 0, 0, 0, 1, 0],
],
]
eval_df = pd.DataFrame(eval_data, columns=["text", "labels"])
model_args = MultiLabelClassificationArgs(
num_train_epochs = 1,
overwrite_output_dir = True,
train_batch_size = 8, # 32,
eval_batch_size=8, # Smaller eval batch
use_multiprocessing=False,
use_multiprocessing_for_evaluation=False,
dataloader_num_workers=0,
process_count = 1,
save_steps = -1, # set -1 to disable
save_eval_checkpoints = False,
save_model_every_epoch = False,
# Force single-process data handling
no_cache=True,
reprocess_input_data=True,
# fp16 = False
)
# Create a MultiLabelClassificationModel
model = MultiLabelClassificationModel(
'roberta',
'distilroberta-base',
num_labels= 6,
use_cuda = True,
args= model_args
)
# Train the model
model.train_model(train_df)
# # Evaluate the model
result, model_outputs, wrong_predictions = model.eval_model(eval_df)
transformers_logger.info(result)
# print("\nmodel_outputs from model.eval_model()")
# print(model_outputs)
predictions, raw_outputs = model.predict(
[
"Example sentence belonging to class 1",
"This thing should be entirely different from the other thing.",
"This thing should be entirely different from the other thing.",
]
)
transformers_logger.info(predictions)
transformers_logger.info(raw_outputs)
exit()
predictions, raw_outputs = model.predict(
[
"Example sentence belonging to class 1",
"This thing should be entirely different from the other thing.",
]
)
transformers_logger.info("\npredictions from model.predict()")
transformers_logger.info(predictions)
transformers_logger.info("\nraw_outputs from model.predict()")
transformers_logger.info(raw_outputs)
model.args.threshold = [0.9, 0.6, 0.5, 0.3, 0.2, 0.5]
transformers_logger.info("\nAfter variable thresholds.")
predictions, raw_outputs = model.predict(
[
"Example sentence belonging to class 1",
"This thing should be entirely different from the other thing.",
]
)
transformers_logger.info("\npredictions from model.predict()")
transformers_logger.info(predictions)
transformers_logger.info("\nraw_outputs from model.predict()")
transformers_logger.info(raw_outputs)
If I force to use HuggingFace datasets workaround and set use_hf_datasets=True, then model.train() succeeded but it failed with prediction
Traceback (most recent call last):
File "train.py", line 126, in
predictions, raw_outputs = model.predict(
^^^^^^^^^^^^^^
File "lib/python3.12/site-packages/simpletransformers/classification/multi_label_classification_model.py", line 406, in predict
return super().predict(to_predict, multi_label=multi_label)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.12/site-packages/simpletransformers/classification/classification_model.py", line 2160, in predict
eval_dataset = self.load_and_cache_examples(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.12/site-packages/simpletransformers/classification/multi_label_classification_model.py", line 384, in load_and_cache_examples
return super().load_and_cache_examples(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.12/site-packages/simpletransformers/classification/classification_model.py", line 1890, in load_and_cache_examples
dataset = ClassificationDataset(
^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.12/site-packages/simpletransformers/classification/classification_utils.py", line 369, in init
self.examples, self.labels = build_classification_dataset(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.12/site-packages/simpletransformers/classification/classification_utils.py", line 344, in build_classification_dataset
labels = torch.tensor(labels, dtype=torch.long)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: only integer tensors of a single element can be converted to an index
Here are the packages that I have on my machine:
- torch==2.7.1
- torchvision==0.22.1
- torchaudio==2.7.1
- --extra-index-url https://download.pytorch.org/whl/cu126
- transformers==4.56.0
- simpletransformers==0.70.5
@ThilinaRajapakse I really appreciate if you could provide any guidance on this. Thank you for maintaining this excellent library! I'm happy to provide additional details or testing if needed.