mirror of
https://github.com/huggingface/transformers.git
synced 2025-10-24 03:24:37 +08:00
Compare commits
1 Commits
check_fix_
...
trigger_do
Author | SHA1 | Date | |
---|---|---|---|
4885578420 |
2
.github/workflows/doctests.yml
vendored
2
.github/workflows/doctests.yml
vendored
@ -3,7 +3,7 @@ name: Doctests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- run_doctest*
|
||||
- trigger_doc
|
||||
repository_dispatch:
|
||||
schedule:
|
||||
- cron: "17 2 * * *"
|
||||
|
5
.github/workflows/push-important-models.yml
vendored
5
.github/workflows/push-important-models.yml
vendored
@ -53,12 +53,11 @@ jobs:
|
||||
test_modified_files:
|
||||
needs: get_modified_models
|
||||
name: Slow & FA2 tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [single-gpu, nvidia-gpu, a10, ci]
|
||||
container:
|
||||
image: huggingface/transformers-all-latest-gpu
|
||||
options: --gpus all --privileged --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/
|
||||
if: ${{ needs.get_modified_models.outputs.matrix != '[]' && needs.get_modified_models.outputs.matrix != '' && fromJson(needs.get_modified_models.outputs.matrix)[0] != null }}
|
||||
if: ${{ needs.get_modified_models.outputs.matrix != '[]' && needs.get_modified_models.outputs.matrix != '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@ -134,4 +133,4 @@ jobs:
|
||||
authkey: ${{ secrets.TAILSCALE_SSH_AUTHKEY }}
|
||||
slackChannel: ${{ secrets.SLACK_CIFEEDBACK_CHANNEL }}
|
||||
slackToken: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
|
||||
waitForSSH: true
|
||||
waitForSSH: true
|
42
.github/workflows/self-scheduled-caller.yml
vendored
42
.github/workflows/self-scheduled-caller.yml
vendored
@ -7,9 +7,17 @@ on:
|
||||
- cron: "17 2 * * *"
|
||||
push:
|
||||
branches:
|
||||
- check_fix_torch_pip
|
||||
- run_scheduled_ci*
|
||||
|
||||
jobs:
|
||||
model-ci:
|
||||
name: Model CI
|
||||
uses: ./.github/workflows/self-scheduled.yml
|
||||
with:
|
||||
job: run_tests_gpu
|
||||
slack_report_channel: "#transformers-ci-daily-models"
|
||||
secrets: inherit
|
||||
|
||||
torch-pipeline:
|
||||
name: Torch pipeline CI
|
||||
uses: ./.github/workflows/self-scheduled.yml
|
||||
@ -17,3 +25,35 @@ jobs:
|
||||
job: run_pipelines_torch_gpu
|
||||
slack_report_channel: "#transformers-ci-daily-pipeline-torch"
|
||||
secrets: inherit
|
||||
|
||||
tf-pipeline:
|
||||
name: TF pipeline CI
|
||||
uses: ./.github/workflows/self-scheduled.yml
|
||||
with:
|
||||
job: run_pipelines_tf_gpu
|
||||
slack_report_channel: "#transformers-ci-daily-pipeline-tf"
|
||||
secrets: inherit
|
||||
|
||||
example-ci:
|
||||
name: Example CI
|
||||
uses: ./.github/workflows/self-scheduled.yml
|
||||
with:
|
||||
job: run_examples_gpu
|
||||
slack_report_channel: "#transformers-ci-daily-examples"
|
||||
secrets: inherit
|
||||
|
||||
deepspeed-ci:
|
||||
name: DeepSpeed CI
|
||||
uses: ./.github/workflows/self-scheduled.yml
|
||||
with:
|
||||
job: run_all_tests_torch_cuda_extensions_gpu
|
||||
slack_report_channel: "#transformers-ci-daily-deepspeed"
|
||||
secrets: inherit
|
||||
|
||||
quantization-ci:
|
||||
name: Quantization CI
|
||||
uses: ./.github/workflows/self-scheduled.yml
|
||||
with:
|
||||
job: run_tests_quantization_torch_gpu
|
||||
slack_report_channel: "#transformers-ci-daily-quantization"
|
||||
secrets: inherit
|
||||
|
@ -171,10 +171,7 @@ class Bnb8BitHfQuantizer(HfQuantizer):
|
||||
import bitsandbytes as bnb
|
||||
|
||||
fp16_statistics_key = param_name.replace("weight", "SCB")
|
||||
fp16_weights_format_key = param_name.replace("weight", "weight_format")
|
||||
|
||||
fp16_statistics = state_dict.get(fp16_statistics_key, None)
|
||||
fp16_weights_format = state_dict.get(fp16_weights_format_key, None)
|
||||
|
||||
module, tensor_name = get_module_from_name(model, param_name)
|
||||
if tensor_name not in module._parameters:
|
||||
@ -213,11 +210,6 @@ class Bnb8BitHfQuantizer(HfQuantizer):
|
||||
if unexpected_keys is not None:
|
||||
unexpected_keys.remove(fp16_statistics_key)
|
||||
|
||||
# We just need to pop the `weight_format` keys from the state dict to remove unneeded
|
||||
# messages. The correct format is correctly retrieved during the first forward pass.
|
||||
if fp16_weights_format is not None and unexpected_keys is not None:
|
||||
unexpected_keys.remove(fp16_weights_format_key)
|
||||
|
||||
def _process_model_after_weight_loading(self, model: "PreTrainedModel", **kwargs):
|
||||
model.is_loaded_in_8bit = True
|
||||
model.is_8bit_serializable = self.is_serializable
|
||||
|
@ -173,37 +173,6 @@ class OptimizerNames(ExplicitEnum):
|
||||
GALORE_ADAFACTOR_LAYERWISE = "galore_adafactor_layerwise"
|
||||
|
||||
|
||||
# Sometimes users will pass in a `str` repr of a dict in the CLI
|
||||
# We need to track what fields those can be. Each time a new arg
|
||||
# has a dict type, it must be added to this list.
|
||||
# Important: These should be typed with Optional[Union[dict,str,...]]
|
||||
_VALID_DICT_FIELDS = [
|
||||
"accelerator_config",
|
||||
"fsdp_config",
|
||||
"deepspeed",
|
||||
"gradient_checkpointing_kwargs",
|
||||
"lr_scheduler_kwargs",
|
||||
]
|
||||
|
||||
|
||||
def _convert_str_dict(passed_value: dict):
|
||||
"Safely checks that a passed value is a dictionary and converts any string values to their appropriate types."
|
||||
for key, value in passed_value.items():
|
||||
if isinstance(value, dict):
|
||||
passed_value[key] = _convert_str_dict(value)
|
||||
elif isinstance(value, str):
|
||||
# First check for bool and convert
|
||||
if value.lower() in ("true", "false"):
|
||||
passed_value[key] = value.lower() == "true"
|
||||
# Check for digit
|
||||
elif value.isdigit():
|
||||
passed_value[key] = int(value)
|
||||
elif value.replace(".", "", 1).isdigit():
|
||||
passed_value[key] = float(value)
|
||||
|
||||
return passed_value
|
||||
|
||||
|
||||
# TODO: `TrainingArguments` users rely on it being fully mutable. In the future see if we can narrow this to a few keys: https://github.com/huggingface/transformers/pull/25903
|
||||
@dataclass
|
||||
class TrainingArguments:
|
||||
@ -834,11 +803,11 @@ class TrainingArguments:
|
||||
default="linear",
|
||||
metadata={"help": "The scheduler type to use."},
|
||||
)
|
||||
lr_scheduler_kwargs: Optional[Union[dict, str]] = field(
|
||||
lr_scheduler_kwargs: Optional[Dict] = field(
|
||||
default_factory=dict,
|
||||
metadata={
|
||||
"help": (
|
||||
"Extra parameters for the lr_scheduler such as {'num_cycles': 1} for the cosine with hard restarts."
|
||||
"Extra parameters for the lr_scheduler such as {'num_cycles': 1} for the cosine with hard restarts"
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -1149,6 +1118,7 @@ class TrainingArguments:
|
||||
)
|
||||
},
|
||||
)
|
||||
# Do not touch this type annotation or it will stop working in CLI
|
||||
fsdp_config: Optional[Union[dict, str]] = field(
|
||||
default=None,
|
||||
metadata={
|
||||
@ -1167,7 +1137,8 @@ class TrainingArguments:
|
||||
)
|
||||
},
|
||||
)
|
||||
accelerator_config: Optional[Union[dict, str]] = field(
|
||||
# Do not touch this type annotation or it will stop working in CLI
|
||||
accelerator_config: Optional[str] = field(
|
||||
default=None,
|
||||
metadata={
|
||||
"help": (
|
||||
@ -1176,7 +1147,8 @@ class TrainingArguments:
|
||||
)
|
||||
},
|
||||
)
|
||||
deepspeed: Optional[Union[dict, str]] = field(
|
||||
# Do not touch this type annotation or it will stop working in CLI
|
||||
deepspeed: Optional[str] = field(
|
||||
default=None,
|
||||
metadata={
|
||||
"help": (
|
||||
@ -1280,7 +1252,7 @@ class TrainingArguments:
|
||||
"help": "If True, use gradient checkpointing to save memory at the expense of slower backward pass."
|
||||
},
|
||||
)
|
||||
gradient_checkpointing_kwargs: Optional[Union[dict, str]] = field(
|
||||
gradient_checkpointing_kwargs: Optional[dict] = field(
|
||||
default=None,
|
||||
metadata={
|
||||
"help": "Gradient checkpointing key word arguments such as `use_reentrant`. Will be passed to `torch.utils.checkpoint.checkpoint` through `model.gradient_checkpointing_enable`."
|
||||
@ -1408,17 +1380,6 @@ class TrainingArguments:
|
||||
)
|
||||
|
||||
def __post_init__(self):
|
||||
# Parse in args that could be `dict` sent in from the CLI as a string
|
||||
for field in _VALID_DICT_FIELDS:
|
||||
passed_value = getattr(self, field)
|
||||
# We only want to do this if the str starts with a bracket to indiciate a `dict`
|
||||
# else its likely a filename if supported
|
||||
if isinstance(passed_value, str) and passed_value.startswith("{"):
|
||||
loaded_dict = json.loads(passed_value)
|
||||
# Convert str values to types if applicable
|
||||
loaded_dict = _convert_str_dict(loaded_dict)
|
||||
setattr(self, field, loaded_dict)
|
||||
|
||||
# expand paths, if not os.makedirs("~/bar") will make directory
|
||||
# in the current directory instead of the actual home
|
||||
# see https://github.com/huggingface/transformers/issues/10628
|
||||
|
@ -32,7 +32,7 @@ class ZeroShotAudioClassificationPipelineTests(unittest.TestCase):
|
||||
audio_classifier = pipeline(
|
||||
task="zero-shot-audio-classification", model="hf-internal-testing/tiny-clap-htsat-unfused"
|
||||
)
|
||||
dataset = load_dataset("hf-internal-testing/ashraq-esc50-1-dog-example")
|
||||
dataset = load_dataset("ashraq/esc50")
|
||||
audio = dataset["train"]["audio"][-1]["array"]
|
||||
output = audio_classifier(audio, candidate_labels=["Sound of a dog", "Sound of vaccum cleaner"])
|
||||
self.assertEqual(
|
||||
@ -52,7 +52,7 @@ class ZeroShotAudioClassificationPipelineTests(unittest.TestCase):
|
||||
model="laion/clap-htsat-unfused",
|
||||
)
|
||||
# This is an audio of a dog
|
||||
dataset = load_dataset("hf-internal-testing/ashraq-esc50-1-dog-example")
|
||||
dataset = load_dataset("ashraq/esc50")
|
||||
audio = dataset["train"]["audio"][-1]["array"]
|
||||
output = audio_classifier(audio, candidate_labels=["Sound of a dog", "Sound of vaccum cleaner"])
|
||||
|
||||
|
@ -22,14 +22,12 @@ from argparse import Namespace
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Literal, Optional, Union, get_args, get_origin
|
||||
from typing import List, Literal, Optional
|
||||
|
||||
import yaml
|
||||
|
||||
from transformers import HfArgumentParser, TrainingArguments
|
||||
from transformers.hf_argparser import make_choice_type_function, string_to_bool
|
||||
from transformers.testing_utils import require_torch
|
||||
from transformers.training_args import _VALID_DICT_FIELDS
|
||||
|
||||
|
||||
# Since Python 3.10, we can use the builtin `|` operator for Union types
|
||||
@ -407,68 +405,3 @@ class HfArgumentParserTest(unittest.TestCase):
|
||||
def test_integration_training_args(self):
|
||||
parser = HfArgumentParser(TrainingArguments)
|
||||
self.assertIsNotNone(parser)
|
||||
|
||||
def test_valid_dict_annotation(self):
|
||||
"""
|
||||
Tests to make sure that `dict` based annotations
|
||||
are correctly made in the `TrainingArguments`.
|
||||
|
||||
If this fails, a type annotation change is
|
||||
needed on a new input
|
||||
"""
|
||||
base_list = _VALID_DICT_FIELDS.copy()
|
||||
args = TrainingArguments
|
||||
|
||||
# First find any annotations that contain `dict`
|
||||
fields = args.__dataclass_fields__
|
||||
|
||||
raw_dict_fields = []
|
||||
optional_dict_fields = []
|
||||
|
||||
for field in fields.values():
|
||||
# First verify raw dict
|
||||
if field.type in (dict, Dict):
|
||||
raw_dict_fields.append(field)
|
||||
# Next check for `Union` or `Optional`
|
||||
elif get_origin(field.type) == Union:
|
||||
if any(arg in (dict, Dict) for arg in get_args(field.type)):
|
||||
optional_dict_fields.append(field)
|
||||
|
||||
# First check: anything in `raw_dict_fields` is very bad
|
||||
self.assertEqual(
|
||||
len(raw_dict_fields),
|
||||
0,
|
||||
"Found invalid raw `dict` types in the `TrainingArgument` typings. "
|
||||
"This leads to issues with the CLI. Please turn this into `typing.Optional[dict,str]`",
|
||||
)
|
||||
|
||||
# Next check raw annotations
|
||||
for field in optional_dict_fields:
|
||||
args = get_args(field.type)
|
||||
# These should be returned as `dict`, `str`, ...
|
||||
# we only care about the first two
|
||||
self.assertIn(args[0], (Dict, dict))
|
||||
self.assertEqual(
|
||||
str(args[1]),
|
||||
"<class 'str'>",
|
||||
f"Expected field `{field.name}` to have a type signature of at least `typing.Union[dict,str,...]` for CLI compatibility, "
|
||||
"but `str` not found. Please fix this.",
|
||||
)
|
||||
|
||||
# Second check: anything in `optional_dict_fields` is bad if it's not in `base_list`
|
||||
for field in optional_dict_fields:
|
||||
self.assertIn(
|
||||
field.name,
|
||||
base_list,
|
||||
f"Optional dict field `{field.name}` is not in the base list of valid fields. Please add it to `training_args._VALID_DICT_FIELDS`",
|
||||
)
|
||||
|
||||
@require_torch
|
||||
def test_valid_dict_input_parsing(self):
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
args = TrainingArguments(
|
||||
output_dir=tmp_dir,
|
||||
accelerator_config='{"split_batches": "True", "gradient_accumulation_kwargs": {"num_steps": 2}}',
|
||||
)
|
||||
self.assertEqual(args.accelerator_config.split_batches, True)
|
||||
self.assertEqual(args.accelerator_config.gradient_accumulation_kwargs["num_steps"], 2)
|
||||
|
Reference in New Issue
Block a user