AbdulElahGwaith commited on
Commit
a9bd396
·
verified ·
1 Parent(s): 93e5928

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .circleci/TROUBLESHOOT.md +7 -0
  2. .circleci/config.yml +232 -0
  3. .circleci/create_circleci_config.py +412 -0
  4. .circleci/parse_test_outputs.py +71 -0
  5. .gitattributes +11 -35
  6. .github/ISSUE_TEMPLATE/bug-report.yml +126 -0
  7. .github/ISSUE_TEMPLATE/config.yml +12 -0
  8. .github/ISSUE_TEMPLATE/feature-request.yml +31 -0
  9. .github/ISSUE_TEMPLATE/i18n.md +46 -0
  10. .github/ISSUE_TEMPLATE/migration.yml +72 -0
  11. .github/ISSUE_TEMPLATE/new-model-addition.yml +31 -0
  12. .github/PULL_REQUEST_TEMPLATE.md +78 -0
  13. .github/conda/build.sh +1 -0
  14. .github/conda/meta.yaml +56 -0
  15. .github/copilot-instructions.md +39 -0
  16. .github/scripts/assign_reviewers.py +122 -0
  17. .github/scripts/codeowners_for_review_action +369 -0
  18. .github/workflows/TROUBLESHOOT.md +9 -0
  19. .github/workflows/add-model-like.yml +80 -0
  20. .github/workflows/assign-reviewers.yml +26 -0
  21. .github/workflows/benchmark.yml +61 -0
  22. .github/workflows/benchmark_v2.yml +57 -0
  23. .github/workflows/benchmark_v2_a10_caller.yml +17 -0
  24. .github/workflows/benchmark_v2_mi325_caller.yml +17 -0
  25. .github/workflows/build-ci-docker-images.yml +77 -0
  26. .github/workflows/build-docker-images.yml +304 -0
  27. .github/workflows/build-nightly-ci-docker-images.yml +73 -0
  28. .github/workflows/build-past-ci-docker-images.yml +101 -0
  29. .github/workflows/build_documentation.yml +35 -0
  30. .github/workflows/build_pr_documentation.yml +17 -0
  31. .github/workflows/check-workflow-permissions.yml +23 -0
  32. .github/workflows/check_failed_tests.yml +325 -0
  33. .github/workflows/check_tiny_models.yml +82 -0
  34. .github/workflows/circleci-failure-summary-comment.yml +245 -0
  35. .github/workflows/codeql.yml +23 -0
  36. .github/workflows/collated-reports.yml +43 -0
  37. .github/workflows/doctest_job.yml +82 -0
  38. .github/workflows/doctests.yml +89 -0
  39. .github/workflows/get-pr-info.yml +167 -0
  40. .github/workflows/get-pr-number.yml +42 -0
  41. .github/workflows/model_jobs.yml +207 -0
  42. .github/workflows/model_jobs_intel_gaudi.yml +120 -0
  43. .github/workflows/new_model_pr_merged_notification.yml +68 -0
  44. .github/workflows/pr-repo-consistency-bot.yml +314 -0
  45. .github/workflows/pr-style-bot.yml +18 -0
  46. .github/workflows/pr_build_doc_with_comment.yml +134 -0
  47. .github/workflows/pr_slow_ci_suggestion.yml +166 -0
  48. .github/workflows/push-important-models.yml +157 -0
  49. .github/workflows/release-conda.yml +47 -0
  50. .github/workflows/release.yml +60 -0
.circleci/TROUBLESHOOT.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Troubleshooting
2
+
3
+ This is a document explaining how to deal with various issues on Circle-CI. The entries may include actual solutions or pointers to Issues that cover those.
4
+
5
+ ## Circle CI
6
+
7
+ * pytest worker runs out of resident RAM and gets killed by `cgroups`: https://github.com/huggingface/transformers/issues/11408
.circleci/config.yml ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: 2.1
2
+ setup: true
3
+ orbs:
4
+ continuation: circleci/continuation@0.1.0
5
+
6
+ parameters:
7
+ nightly:
8
+ type: boolean
9
+ default: false
10
+ GHA_Actor:
11
+ type: string
12
+ default: ""
13
+ GHA_Action:
14
+ type: string
15
+ default: ""
16
+ GHA_Event:
17
+ type: string
18
+ default: ""
19
+ GHA_Meta:
20
+ type: string
21
+ default: ""
22
+
23
+ jobs:
24
+ # Ensure running with CircleCI/huggingface
25
+ check_circleci_user:
26
+ docker:
27
+ - image: python:3.10-slim
28
+ resource_class: small
29
+ parallelism: 1
30
+ steps:
31
+ - run: echo $CIRCLE_PROJECT_USERNAME
32
+ - run: |
33
+ if [ "$CIRCLE_PROJECT_USERNAME" = "huggingface" ]; then
34
+ exit 0
35
+ else
36
+ echo "The CI is running under $CIRCLE_PROJECT_USERNAME personal account. Please follow https://support.circleci.com/hc/en-us/articles/360008097173-Troubleshooting-why-pull-requests-are-not-triggering-jobs-on-my-organization- to fix it."; exit -1
37
+ fi
38
+ # Fetch the tests to run
39
+ fetch_tests:
40
+ working_directory: ~/transformers
41
+ docker:
42
+ - image: huggingface/transformers-quality
43
+ parallelism: 1
44
+ steps:
45
+ - checkout
46
+ - run: uv pip install -U -e .
47
+ - run: echo 'export "GIT_COMMIT_MESSAGE=$(git show -s --format=%s)"' >> "$BASH_ENV" && source "$BASH_ENV"
48
+ - run: mkdir -p test_preparation
49
+ - run: python utils/tests_fetcher.py | tee tests_fetched_summary.txt || true
50
+ - run: python utils/tests_fetcher.py --filter_tests || true
51
+ - run: export "GIT_COMMIT_MESSAGE=$(git show -s --format=%s)" && echo $GIT_COMMIT_MESSAGE && python .circleci/create_circleci_config.py --fetcher_folder test_preparation
52
+ - run: |
53
+ if [ ! -s test_preparation/generated_config.yml ]; then
54
+ echo "No tests to run, exiting early!"
55
+ circleci-agent step halt
56
+ fi
57
+
58
+ - store_artifacts:
59
+ path: test_preparation
60
+
61
+ - run:
62
+ name: "Retrieve Artifact Paths"
63
+ # [reference] https://circleci.com/docs/api/v2/index.html#operation/getJobArtifacts
64
+ # `CIRCLE_TOKEN` is defined as an environment variables set within a context, see `https://circleci.com/docs/contexts/`
65
+ command: |
66
+ project_slug="gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
67
+ job_number=${CIRCLE_BUILD_NUM}
68
+ url="https://circleci.com/api/v2/project/${project_slug}/${job_number}/artifacts"
69
+ curl -o test_preparation/artifacts.json ${url} --header "Circle-Token: $CIRCLE_TOKEN"
70
+ - run:
71
+ name: "Prepare pipeline parameters"
72
+ command: |
73
+ python utils/process_test_artifacts.py
74
+
75
+ # To avoid too long generated_config.yaml on the continuation orb, we pass the links to the artifacts as parameters.
76
+ # Otherwise the list of tests was just too big. Explicit is good but for that it was a limitation.
77
+ # We used:
78
+
79
+ # https://circleci.com/docs/api/v2/index.html#operation/getJobArtifacts : to get the job artifacts
80
+ # We could not pass a nested dict, which is why we create the test_file_... parameters for every single job
81
+
82
+ - store_artifacts:
83
+ path: test_preparation/transformed_artifacts.json
84
+ - store_artifacts:
85
+ path: test_preparation/artifacts.json
86
+ - continuation/continue:
87
+ parameters: test_preparation/transformed_artifacts.json
88
+ configuration_path: test_preparation/generated_config.yml
89
+
90
+ # To run all tests for the nightly build
91
+ fetch_all_tests:
92
+ working_directory: ~/transformers
93
+ docker:
94
+ - image: huggingface/transformers-quality
95
+ parallelism: 1
96
+ steps:
97
+ - checkout
98
+ - run: uv pip install -U -e .
99
+ - run: echo 'export "GIT_COMMIT_MESSAGE=$(git show -s --format=%s)"' >> "$BASH_ENV" && source "$BASH_ENV"
100
+ - run: mkdir -p test_preparation
101
+ - run: python utils/tests_fetcher.py --fetch_all | tee tests_fetched_summary.txt || true
102
+ - run: python utils/tests_fetcher.py --filter_tests || true
103
+ - run: export "GIT_COMMIT_MESSAGE=$(git show -s --format=%s)" && echo $GIT_COMMIT_MESSAGE && python .circleci/create_circleci_config.py --fetcher_folder test_preparation
104
+ - run: |
105
+ if [ ! -s test_preparation/generated_config.yml ]; then
106
+ echo "No tests to run, exiting early!"
107
+ circleci-agent step halt
108
+ fi
109
+
110
+ - store_artifacts:
111
+ path: test_preparation
112
+
113
+ - run:
114
+ name: "Retrieve Artifact Paths"
115
+ command: |
116
+ project_slug="gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
117
+ job_number=${CIRCLE_BUILD_NUM}
118
+ url="https://circleci.com/api/v2/project/${project_slug}/${job_number}/artifacts"
119
+ curl -o test_preparation/artifacts.json ${url}
120
+ - run:
121
+ name: "Prepare pipeline parameters"
122
+ command: |
123
+ python utils/process_test_artifacts.py
124
+
125
+ # To avoid too long generated_config.yaml on the continuation orb, we pass the links to the artifacts as parameters.
126
+ # Otherwise the list of tests was just too big. Explicit is good but for that it was a limitation.
127
+ # We used:
128
+
129
+ # https://circleci.com/docs/api/v2/index.html#operation/getJobArtifacts : to get the job artifacts
130
+ # We could not pass a nested dict, which is why we create the test_file_... parameters for every single job
131
+
132
+ - store_artifacts:
133
+ path: test_preparation/transformed_artifacts.json
134
+ - store_artifacts:
135
+ path: test_preparation/artifacts.json
136
+ - continuation/continue:
137
+ parameters: test_preparation/transformed_artifacts.json
138
+ configuration_path: test_preparation/generated_config.yml
139
+
140
+ check_code_quality:
141
+ working_directory: ~/transformers
142
+ docker:
143
+ - image: huggingface/transformers-quality
144
+ resource_class: large
145
+ environment:
146
+ TRANSFORMERS_IS_CI: yes
147
+ PYTEST_TIMEOUT: 120
148
+ parallelism: 1
149
+ steps:
150
+ - checkout
151
+ - run: uv pip install -e ".[quality]"
152
+ - run:
153
+ name: Show installed libraries and their versions
154
+ command: pip freeze | tee installed.txt
155
+ - store_artifacts:
156
+ path: ~/transformers/installed.txt
157
+ - run: ruff check examples tests src utils scripts benchmark benchmark_v2 setup.py conftest.py
158
+ - run: ruff format --check examples tests src utils scripts benchmark benchmark_v2 setup.py conftest.py
159
+ - run: python utils/custom_init_isort.py --check_only
160
+ - run: python utils/sort_auto_mappings.py --check_only
161
+
162
+ check_repository_consistency:
163
+ working_directory: ~/transformers
164
+ docker:
165
+ - image: huggingface/transformers-consistency
166
+ resource_class: large
167
+ environment:
168
+ TRANSFORMERS_IS_CI: yes
169
+ PYTEST_TIMEOUT: 120
170
+ parallelism: 1
171
+ steps:
172
+ - checkout
173
+ - run: uv pip install -e ".[quality]"
174
+ - run:
175
+ name: Show installed libraries and their versions
176
+ command: pip freeze | tee installed.txt
177
+ - store_artifacts:
178
+ path: ~/transformers/installed.txt
179
+ - run: python -c "from transformers import *" || (echo '🚨 import failed, this means you introduced unprotected imports! 🚨'; exit 1)
180
+ - run: python utils/check_copies.py
181
+ - run: python utils/check_modular_conversion.py
182
+ - run: python utils/check_doc_toc.py
183
+ - run: python utils/check_docstrings.py
184
+ - run: python utils/check_dummies.py
185
+ - run: python utils/check_repo.py
186
+ - run: python utils/check_modeling_structure.py
187
+ - run: python utils/check_inits.py
188
+ - run: python utils/check_pipeline_typing.py
189
+ - run: python utils/check_config_docstrings.py
190
+ - run: python utils/check_config_attributes.py
191
+ - run: python utils/check_doctest_list.py
192
+ - run: python utils/update_metadata.py --check-only
193
+ - run: python utils/add_dates.py --check-only
194
+ - run: >
195
+ md5sum src/transformers/dependency_versions_table.py > md5sum.saved;
196
+ python setup.py deps_table_update;
197
+ md5sum -c --quiet md5sum.saved || (printf "Error: the version dependency table is outdated.\nPlease run 'make fix-repo' and commit the changes.\n" && exit 1);
198
+ rm md5sum.saved
199
+
200
+ workflows:
201
+ version: 2
202
+ setup_and_quality:
203
+ when:
204
+ and:
205
+ - equal: [<<pipeline.project.git_url>>, https://github.com/huggingface/transformers]
206
+ - not: <<pipeline.parameters.nightly>>
207
+ jobs:
208
+ - check_circleci_user
209
+ - check_code_quality
210
+ - check_repository_consistency
211
+ - fetch_tests
212
+
213
+ setup_and_quality_2:
214
+ when:
215
+ not:
216
+ equal: [<<pipeline.project.git_url>>, https://github.com/huggingface/transformers]
217
+ jobs:
218
+ - check_circleci_user
219
+ - check_code_quality
220
+ - check_repository_consistency
221
+ - fetch_tests:
222
+ # [reference] https://circleci.com/docs/contexts/
223
+ context:
224
+ - TRANSFORMERS_CONTEXT
225
+
226
+ nightly:
227
+ when: <<pipeline.parameters.nightly>>
228
+ jobs:
229
+ - check_circleci_user
230
+ - check_code_quality
231
+ - check_repository_consistency
232
+ - fetch_all_tests
.circleci/create_circleci_config.py ADDED
@@ -0,0 +1,412 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2022 The HuggingFace Inc. team.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import argparse
17
+ import copy
18
+ import os
19
+ from dataclasses import dataclass
20
+ from typing import Any, Optional
21
+
22
+ import yaml
23
+
24
+
25
+ COMMON_ENV_VARIABLES = {
26
+ "OMP_NUM_THREADS": 1,
27
+ "TRANSFORMERS_IS_CI": True,
28
+ "PYTEST_TIMEOUT": 120,
29
+ "RUN_PIPELINE_TESTS": False,
30
+ # will be adjust in `CircleCIJob.to_dict`.
31
+ "RUN_FLAKY": True,
32
+ "DISABLE_SAFETENSORS_CONVERSION": True,
33
+ }
34
+ # Disable the use of {"s": None} as the output is way too long, causing the navigation on CircleCI impractical
35
+ COMMON_PYTEST_OPTIONS = {"max-worker-restart": 0, "vvv": None, "rsfE":None}
36
+ DEFAULT_DOCKER_IMAGE = [{"image": "cimg/python:3.8.12"}]
37
+
38
+ # Strings that commonly appear in the output of flaky tests when they fail. These are used with `pytest-rerunfailures`
39
+ # to rerun the tests that match these patterns.
40
+ FLAKY_TEST_FAILURE_PATTERNS = [
41
+ "OSError", # Machine/connection transient error
42
+ "Timeout", # Machine/connection transient error
43
+ "ConnectionError", # Connection transient error
44
+ "FileNotFoundError", # Raised by `datasets` on Hub failures
45
+ "PIL.UnidentifiedImageError", # Raised by `PIL.Image.open` on connection issues
46
+ "HTTPError", # Also catches HfHubHTTPError
47
+ "AssertionError: Tensor-likes are not close!", # `torch.testing.assert_close`, we might have unlucky random values
48
+ # TODO: error downloading tokenizer's `merged.txt` from hub can cause all the exceptions below. Throw and handle
49
+ # them under a single message.
50
+ "TypeError: expected str, bytes or os.PathLike object, not NoneType",
51
+ "TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType",
52
+ "Converting from Tiktoken failed",
53
+ "KeyError: <class ",
54
+ "TypeError: not a string",
55
+ ]
56
+
57
+
58
+ class EmptyJob:
59
+ job_name = "empty"
60
+
61
+ def to_dict(self):
62
+ steps = [{"run": 'ls -la'}]
63
+ if self.job_name == "collection_job":
64
+ steps.extend(
65
+ [
66
+ "checkout",
67
+ {"run": "pip install requests || true"},
68
+ {"run": """while [[ $(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job" --header "Circle-Token: $CCI_TOKEN"| jq -r '.items[]|select(.name != "collection_job")|.status' | grep -c "running") -gt 0 ]]; do sleep 5; done || true"""},
69
+ {"run": 'python utils/process_circleci_workflow_test_reports.py --workflow_id $CIRCLE_WORKFLOW_ID || true'},
70
+ {"store_artifacts": {"path": "outputs"}},
71
+ {"run": 'echo "All required jobs have now completed"'},
72
+ ]
73
+ )
74
+
75
+ return {
76
+ "docker": copy.deepcopy(DEFAULT_DOCKER_IMAGE),
77
+ "resource_class": "small",
78
+ "steps": steps,
79
+ }
80
+
81
+
82
+ @dataclass
83
+ class CircleCIJob:
84
+ name: str
85
+ additional_env: dict[str, Any] = None
86
+ docker_image: list[dict[str, str]] = None
87
+ install_steps: list[str] = None
88
+ marker: Optional[str] = None
89
+ parallelism: Optional[int] = 0
90
+ pytest_num_workers: int = 8
91
+ pytest_options: dict[str, Any] = None
92
+ resource_class: Optional[str] = "xlarge"
93
+ tests_to_run: Optional[list[str]] = None
94
+ num_test_files_per_worker: Optional[int] = 10
95
+ # This should be only used for doctest job!
96
+ command_timeout: Optional[int] = None
97
+
98
+ def __post_init__(self):
99
+ # Deal with defaults for mutable attributes.
100
+ if self.additional_env is None:
101
+ self.additional_env = {}
102
+ if self.docker_image is None:
103
+ # Let's avoid changing the default list and make a copy.
104
+ self.docker_image = copy.deepcopy(DEFAULT_DOCKER_IMAGE)
105
+ else:
106
+ # BIG HACK WILL REMOVE ONCE FETCHER IS UPDATED
107
+ print(os.environ.get("GIT_COMMIT_MESSAGE"))
108
+ if "[build-ci-image]" in os.environ.get("GIT_COMMIT_MESSAGE", "") or os.environ.get("GIT_COMMIT_MESSAGE", "") == "dev-ci":
109
+ self.docker_image[0]["image"] = f"{self.docker_image[0]['image']}:dev"
110
+ print(f"Using {self.docker_image} docker image")
111
+ if self.install_steps is None:
112
+ self.install_steps = ["uv pip install ."]
113
+ # Use a custom patched pytest to force exit the process at the end, to avoid `Too long with no output (exceeded 10m0s): context deadline exceeded`
114
+ self.install_steps.append("uv pip install git+https://github.com/ydshieh/pytest.git@8.4.1-ydshieh")
115
+ if self.pytest_options is None:
116
+ self.pytest_options = {}
117
+ if isinstance(self.tests_to_run, str):
118
+ self.tests_to_run = [self.tests_to_run]
119
+ else:
120
+ test_file = os.path.join("test_preparation" , f"{self.job_name}_test_list.txt")
121
+ print("Looking for ", test_file)
122
+ if os.path.exists(test_file):
123
+ with open(test_file) as f:
124
+ expanded_tests = f.read().strip().split("\n")
125
+ self.tests_to_run = expanded_tests
126
+ print("Found:", expanded_tests)
127
+ else:
128
+ self.tests_to_run = []
129
+ print("not Found")
130
+
131
+ def to_dict(self):
132
+ env = COMMON_ENV_VARIABLES.copy()
133
+ if self.job_name != "tests_hub":
134
+ # fmt: off
135
+ # not critical
136
+ env.update({"HF_TOKEN": "".join(["h", "f", "_", "H", "o", "d", "V", "u", "M", "q", "b", "R", "m", "t", "b", "z", "F", "Q", "O", "Q", "A", "J", "G", "D", "l", "V", "Q", "r", "R", "N", "w", "D", "M", "V", "C", "s", "d"])})
137
+ # fmt: on
138
+
139
+ # Do not run tests decorated by @is_flaky on pull requests
140
+ env['RUN_FLAKY'] = os.environ.get("CIRCLE_PULL_REQUEST", "") == ""
141
+ env.update(self.additional_env)
142
+
143
+ job = {
144
+ "docker": self.docker_image,
145
+ "environment": env,
146
+ }
147
+ if self.resource_class is not None:
148
+ job["resource_class"] = self.resource_class
149
+
150
+ all_options = {**COMMON_PYTEST_OPTIONS, **self.pytest_options}
151
+ pytest_flags = [f"--{key}={value}" if (value is not None or key in ["doctest-modules"]) else f"-{key}" for key, value in all_options.items()]
152
+ pytest_flags.append(
153
+ f"--make-reports={self.name}" if "examples" in self.name else f"--make-reports=tests_{self.name}"
154
+ )
155
+ # Examples special case: we need to download NLTK files in advance to avoid cuncurrency issues
156
+ timeout_cmd = f"timeout {self.command_timeout} " if self.command_timeout else ""
157
+ marker_cmd = f"-m '{self.marker}'" if self.marker is not None else ""
158
+ junit_flags = " -p no:warning -o junit_family=xunit1 --junitxml=test-results/junit.xml"
159
+ joined_flaky_patterns = "|".join(FLAKY_TEST_FAILURE_PATTERNS)
160
+ repeat_on_failure_flags = f"--reruns 5 --reruns-delay 2 --only-rerun '({joined_flaky_patterns})'"
161
+ parallel = f' << pipeline.parameters.{self.job_name}_parallelism >> '
162
+ steps = [
163
+ "checkout",
164
+ {"attach_workspace": {"at": "test_preparation"}},
165
+ {"run": "apt-get update && apt-get install -y curl"},
166
+ {"run": " && ".join(self.install_steps)},
167
+ {"run": {"name": "Download NLTK files", "command": """python -c "import nltk; nltk.download('punkt', quiet=True)" """} if "example" in self.name else "echo Skipping"},
168
+ {"run": {
169
+ "name": "Show installed libraries and their size",
170
+ "command": """du -h -d 1 "$(pip -V | cut -d ' ' -f 4 | sed 's/pip//g')" | grep -vE "dist-info|_distutils_hack|__pycache__" | sort -h | tee installed.txt || true"""}
171
+ },
172
+ {"run": {
173
+ "name": "Show installed libraries and their versions",
174
+ "command": """pip list --format=freeze | tee installed.txt || true"""}
175
+ },
176
+ {"run": {
177
+ "name": "Show biggest libraries",
178
+ "command": """dpkg-query --show --showformat='${Installed-Size}\t${Package}\n' | sort -rh | head -25 | sort -h | awk '{ package=$2; sub(".*/", "", package); printf("%.5f GB %s\n", $1/1024/1024, package)}' || true"""}
179
+ },
180
+ {"run": {"name": "Create `test-results` directory", "command": "mkdir test-results"}},
181
+ {"run": {"name": "Get files to test", "command":f'curl -L -o {self.job_name}_test_list.txt <<pipeline.parameters.{self.job_name}_test_list>> --header "Circle-Token: $CIRCLE_TOKEN"' if self.name != "pr_documentation_tests" else 'echo "Skipped"'}},
182
+ {"run": {"name": "Split tests across parallel nodes: show current parallel tests",
183
+ "command": f"TESTS=$(circleci tests split --split-by=timings {self.job_name}_test_list.txt) && echo $TESTS > splitted_tests.txt && echo $TESTS | tr ' ' '\n'" if self.parallelism else f"awk '{{printf \"%s \", $0}}' {self.job_name}_test_list.txt > splitted_tests.txt"
184
+ }
185
+ },
186
+ # During the CircleCI docker images build time, we might already (or not) download the data.
187
+ # If it's done already, the files are inside the directory `/test_data/`.
188
+ {"run": {"name": "fetch hub objects before pytest", "command": "cp -r /test_data/* . 2>/dev/null || true; python3 utils/fetch_hub_objects_for_ci.py"}},
189
+ {"run": {"name": "download and unzip hub cache", "command": 'curl -L -o huggingface-cache.tar.gz https://huggingface.co/datasets/hf-internal-testing/hf_hub_cache/resolve/main/huggingface-cache.tar.gz && apt-get install pigz && tar --use-compress-program="pigz -d -p 8" -xf huggingface-cache.tar.gz && mv -n hub/* /root/.cache/huggingface/hub/ && ls -la /root/.cache/huggingface/hub/'}},
190
+ {"run": {
191
+ "name": "Run tests",
192
+ "command": f"({timeout_cmd} python3 -m pytest {marker_cmd} -n {self.pytest_num_workers} {junit_flags} {repeat_on_failure_flags} {' '.join(pytest_flags)} $(cat splitted_tests.txt) | tee tests_output.txt)"}
193
+ },
194
+ {"run":
195
+ {
196
+ "name": "Check for test crashes",
197
+ "when": "always",
198
+ "command": """if [ ! -f tests_output.txt ]; then
199
+ echo "ERROR: tests_output.txt does not exist - tests may not have run properly"
200
+ exit 1
201
+ elif grep -q "crashed and worker restarting disabled" tests_output.txt; then
202
+ echo "ERROR: Worker crash detected in test output"
203
+ echo "Found: crashed and worker restarting disabled"
204
+ exit 1
205
+ else
206
+ echo "Tests output file exists and no worker crashes detected"
207
+ fi"""
208
+ },
209
+ },
210
+ {"run": {"name": "Expand to show skipped tests", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --skip"}},
211
+ {"run": {"name": "Failed tests: show reasons", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --fail"}},
212
+ {"run": {"name": "Errors", "when": "always", "command": "python3 .circleci/parse_test_outputs.py --file tests_output.txt --errors"}},
213
+ {"store_test_results": {"path": "test-results"}},
214
+ {"store_artifacts": {"path": "test-results/junit.xml"}},
215
+ {"store_artifacts": {"path": "reports"}},
216
+ {"store_artifacts": {"path": "tests.txt"}},
217
+ {"store_artifacts": {"path": "splitted_tests.txt"}},
218
+ {"store_artifacts": {"path": "installed.txt"}},
219
+ ]
220
+ if self.parallelism:
221
+ job["parallelism"] = parallel
222
+ job["steps"] = steps
223
+ return job
224
+
225
+ @property
226
+ def job_name(self):
227
+ return self.name if ("examples" in self.name or "pipeline" in self.name or "pr_documentation" in self.name) else f"tests_{self.name}"
228
+
229
+
230
+ # JOBS
231
+ torch_job = CircleCIJob(
232
+ "torch",
233
+ docker_image=[{"image": "huggingface/transformers-torch-light"}],
234
+ marker="not generate",
235
+ parallelism=6,
236
+ )
237
+
238
+ generate_job = CircleCIJob(
239
+ "generate",
240
+ docker_image=[{"image": "huggingface/transformers-torch-light"}],
241
+ # networkx==3.3 (after #36957) cause some issues
242
+ # TODO: remove this once it works directly
243
+ install_steps=["uv pip install ."],
244
+ marker="generate",
245
+ parallelism=6,
246
+ )
247
+
248
+ tokenization_job = CircleCIJob(
249
+ "tokenization",
250
+ docker_image=[{"image": "huggingface/transformers-torch-light"}],
251
+ parallelism=8,
252
+ )
253
+
254
+ processor_job = CircleCIJob(
255
+ "processors",
256
+ docker_image=[{"image": "huggingface/transformers-torch-light"}],
257
+ parallelism=8,
258
+ )
259
+
260
+ pipelines_torch_job = CircleCIJob(
261
+ "pipelines_torch",
262
+ additional_env={"RUN_PIPELINE_TESTS": True},
263
+ docker_image=[{"image":"huggingface/transformers-torch-light"}],
264
+ marker="is_pipeline_test",
265
+ parallelism=4,
266
+ )
267
+
268
+ custom_tokenizers_job = CircleCIJob(
269
+ "custom_tokenizers",
270
+ additional_env={"RUN_CUSTOM_TOKENIZERS": True},
271
+ docker_image=[{"image": "huggingface/transformers-custom-tokenizers"}],
272
+ )
273
+
274
+ examples_torch_job = CircleCIJob(
275
+ "examples_torch",
276
+ additional_env={"OMP_NUM_THREADS": 8},
277
+ docker_image=[{"image":"huggingface/transformers-examples-torch"}],
278
+ # TODO @ArthurZucker remove this once docker is easier to build
279
+ install_steps=["uv pip install . && uv pip install -r examples/pytorch/_tests_requirements.txt"],
280
+ pytest_num_workers=4,
281
+ )
282
+
283
+ hub_job = CircleCIJob(
284
+ "hub",
285
+ additional_env={"HUGGINGFACE_CO_STAGING": True},
286
+ docker_image=[{"image":"huggingface/transformers-torch-light"}],
287
+ install_steps=[
288
+ 'uv pip install .',
289
+ 'git config --global user.email "ci@dummy.com"',
290
+ 'git config --global user.name "ci"',
291
+ ],
292
+ marker="is_staging_test",
293
+ pytest_num_workers=2,
294
+ resource_class="medium",
295
+ )
296
+
297
+ exotic_models_job = CircleCIJob(
298
+ "exotic_models",
299
+ docker_image=[{"image":"huggingface/transformers-exotic-models"}],
300
+ parallelism=4,
301
+ pytest_options={"durations": 100},
302
+ )
303
+
304
+ repo_utils_job = CircleCIJob(
305
+ "repo_utils",
306
+ docker_image=[{"image":"huggingface/transformers-consistency"}],
307
+ pytest_num_workers=4,
308
+ resource_class="large",
309
+ )
310
+
311
+ non_model_job = CircleCIJob(
312
+ "non_model",
313
+ docker_image=[{"image": "huggingface/transformers-torch-light"}],
314
+ # networkx==3.3 (after #36957) cause some issues
315
+ # TODO: remove this once it works directly
316
+ install_steps=["uv pip install .[serving]"],
317
+ marker="not generate",
318
+ parallelism=6,
319
+ )
320
+
321
+ training_ci_job = CircleCIJob(
322
+ "training_ci",
323
+ additional_env={"RUN_TRAINING_TESTS": True},
324
+ docker_image=[{"image": "huggingface/transformers-torch-light"}],
325
+ install_steps=["uv pip install ."],
326
+ marker="is_training_test",
327
+ parallelism=6,
328
+ )
329
+
330
+ # We also include a `dummy.py` file in the files to be doc-tested to prevent edge case failure. Otherwise, the pytest
331
+ # hangs forever during test collection while showing `collecting 0 items / 21 errors`. (To see this, we have to remove
332
+ # the bash output redirection.)
333
+ py_command = 'from utils.tests_fetcher import get_doctest_files; to_test = get_doctest_files() + ["dummy.py"]; to_test = " ".join(to_test); print(to_test)'
334
+ py_command = f"$(python3 -c '{py_command}')"
335
+ command = f'echo """{py_command}""" > pr_documentation_tests_temp.txt'
336
+ doc_test_job = CircleCIJob(
337
+ "pr_documentation_tests",
338
+ docker_image=[{"image":"huggingface/transformers-consistency"}],
339
+ additional_env={"TRANSFORMERS_VERBOSITY": "error", "DATASETS_VERBOSITY": "error", "SKIP_CUDA_DOCTEST": "1"},
340
+ install_steps=[
341
+ # Add an empty file to keep the test step running correctly even no file is selected to be tested.
342
+ "uv pip install .",
343
+ "touch dummy.py",
344
+ command,
345
+ "cat pr_documentation_tests_temp.txt",
346
+ "tail -n1 pr_documentation_tests_temp.txt | tee pr_documentation_tests_test_list.txt"
347
+ ],
348
+ tests_to_run="$(cat pr_documentation_tests.txt)", # noqa
349
+ pytest_options={"-doctest-modules": None, "doctest-glob": "*.md", "dist": "loadfile", "rvsA": None},
350
+ command_timeout=1200, # test cannot run longer than 1200 seconds
351
+ pytest_num_workers=1,
352
+ )
353
+
354
+ REGULAR_TESTS = [torch_job, hub_job, tokenization_job, processor_job, generate_job, non_model_job] # fmt: skip
355
+ EXAMPLES_TESTS = [examples_torch_job]
356
+ PIPELINE_TESTS = [pipelines_torch_job]
357
+ REPO_UTIL_TESTS = [repo_utils_job]
358
+ DOC_TESTS = [doc_test_job]
359
+ TRAINING_CI_TESTS = [training_ci_job]
360
+ ALL_TESTS = REGULAR_TESTS + EXAMPLES_TESTS + PIPELINE_TESTS + REPO_UTIL_TESTS + DOC_TESTS + [custom_tokenizers_job] + [exotic_models_job] + TRAINING_CI_TESTS # fmt: skip
361
+
362
+
363
+ def create_circleci_config(folder=None):
364
+ if folder is None:
365
+ folder = os.getcwd()
366
+ os.environ["test_preparation_dir"] = folder
367
+ jobs = [k for k in ALL_TESTS if os.path.isfile(os.path.join("test_preparation" , f"{k.job_name}_test_list.txt") )]
368
+ print("The following jobs will be run ", jobs)
369
+
370
+ if len(jobs) == 0:
371
+ jobs = [EmptyJob()]
372
+ else:
373
+ print("Full list of job name inputs", {j.job_name + "_test_list":{"type":"string", "default":''} for j in jobs})
374
+ # Add a job waiting all the test jobs and aggregate their test summary files at the end
375
+ collection_job = EmptyJob()
376
+ collection_job.job_name = "collection_job"
377
+ jobs = [collection_job] + jobs
378
+
379
+ config = {
380
+ "version": "2.1",
381
+ "parameters": {
382
+ # Only used to accept the parameters from the trigger
383
+ "nightly": {"type": "boolean", "default": False},
384
+ # Only used to accept the parameters from GitHub Actions trigger
385
+ "GHA_Actor": {"type": "string", "default": ""},
386
+ "GHA_Action": {"type": "string", "default": ""},
387
+ "GHA_Event": {"type": "string", "default": ""},
388
+ "GHA_Meta": {"type": "string", "default": ""},
389
+ "tests_to_run": {"type": "string", "default": ""},
390
+ **{j.job_name + "_test_list":{"type":"string", "default":''} for j in jobs},
391
+ **{j.job_name + "_parallelism":{"type":"integer", "default":1} for j in jobs},
392
+ },
393
+ "jobs": {j.job_name: j.to_dict() for j in jobs}
394
+ }
395
+ if "CIRCLE_TOKEN" in os.environ:
396
+ # For private forked repo. (e.g. new model addition)
397
+ config["workflows"] = {"version": 2, "run_tests": {"jobs": [{j.job_name: {"context": ["TRANSFORMERS_CONTEXT"]}} for j in jobs]}}
398
+ else:
399
+ # For public repo. (e.g. `transformers`)
400
+ config["workflows"] = {"version": 2, "run_tests": {"jobs": [j.job_name for j in jobs]}}
401
+ with open(os.path.join(folder, "generated_config.yml"), "w") as f:
402
+ f.write(yaml.dump(config, sort_keys=False, default_flow_style=False).replace("' << pipeline", " << pipeline").replace(">> '", " >>"))
403
+
404
+
405
+ if __name__ == "__main__":
406
+ parser = argparse.ArgumentParser()
407
+ parser.add_argument(
408
+ "--fetcher_folder", type=str, default=None, help="Only test that all tests and modules are accounted for."
409
+ )
410
+ args = parser.parse_args()
411
+
412
+ create_circleci_config(args.fetcher_folder)
.circleci/parse_test_outputs.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import re
3
+
4
+
5
+ def parse_pytest_output(file_path):
6
+ skipped_tests = {}
7
+ skipped_count = 0
8
+ with open(file_path, 'r') as file:
9
+ for line in file:
10
+ match = re.match(r'^SKIPPED \[(\d+)\] (tests/.*): (.*)$', line)
11
+ if match:
12
+ skipped_count += 1
13
+ test_file, test_line, reason = match.groups()
14
+ skipped_tests[reason] = skipped_tests.get(reason, []) + [(test_file, test_line)]
15
+ for k,v in sorted(skipped_tests.items(), key=lambda x:len(x[1])):
16
+ print(f"{len(v):4} skipped because: {k}")
17
+ print("Number of skipped tests:", skipped_count)
18
+
19
+ def parse_pytest_failure_output(file_path):
20
+ failed_tests = {}
21
+ failed_count = 0
22
+ with open(file_path, 'r') as file:
23
+ for line in file:
24
+ match = re.match(r'^FAILED (tests/.*) - (.*): (.*)$', line)
25
+ if match:
26
+ failed_count += 1
27
+ _, error, reason = match.groups()
28
+ failed_tests[reason] = failed_tests.get(reason, []) + [error]
29
+ for k,v in sorted(failed_tests.items(), key=lambda x:len(x[1])):
30
+ print(f"{len(v):4} failed because `{v[0]}` -> {k}")
31
+ print("Number of failed tests:", failed_count)
32
+ if failed_count>0:
33
+ exit(1)
34
+
35
+ def parse_pytest_errors_output(file_path):
36
+ print(file_path)
37
+ error_tests = {}
38
+ error_count = 0
39
+ with open(file_path, 'r') as file:
40
+ for line in file:
41
+ match = re.match(r'^ERROR (tests/.*) - (.*): (.*)$', line)
42
+ if match:
43
+ error_count += 1
44
+ _, test_error, reason = match.groups()
45
+ error_tests[reason] = error_tests.get(reason, []) + [test_error]
46
+ for k,v in sorted(error_tests.items(), key=lambda x:len(x[1])):
47
+ print(f"{len(v):4} errored out because of `{v[0]}` -> {k}")
48
+ print("Number of errors:", error_count)
49
+ if error_count>0:
50
+ exit(1)
51
+
52
+ def main():
53
+ parser = argparse.ArgumentParser()
54
+ parser.add_argument("--file", help="file to parse")
55
+ parser.add_argument("--skip", action="store_true", help="show skipped reasons")
56
+ parser.add_argument("--fail", action="store_true", help="show failed tests")
57
+ parser.add_argument("--errors", action="store_true", help="show failed tests")
58
+ args = parser.parse_args()
59
+
60
+ if args.skip:
61
+ parse_pytest_output(args.file)
62
+
63
+ if args.fail:
64
+ parse_pytest_failure_output(args.file)
65
+
66
+ if args.errors:
67
+ parse_pytest_errors_output(args.file)
68
+
69
+
70
+ if __name__ == "__main__":
71
+ main()
.gitattributes CHANGED
@@ -1,35 +1,11 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.py eol=lf
2
+ *.rst eol=lf
3
+ *.md eol=lf
4
+ *.mdx eol=lftests/fixtures/spiece.model filter=lfs diff=lfs merge=lfs -text
5
+ tests/fixtures/test_sentencepiece.model filter=lfs diff=lfs merge=lfs -text
6
+ tests/fixtures/test_sentencepiece_bpe.model filter=lfs diff=lfs merge=lfs -text
7
+ tests/fixtures/test_sentencepiece_bpe_char.model filter=lfs diff=lfs merge=lfs -text
8
+ tests/fixtures/test_sentencepiece_no_bos.model filter=lfs diff=lfs merge=lfs -text
9
+ tests/fixtures/test_sentencepiece_with_bytefallback.model filter=lfs diff=lfs merge=lfs -text
10
+ tests/fixtures/tests_samples/COCO/000000004016.png filter=lfs diff=lfs merge=lfs -text
11
+ tests/fixtures/tests_samples/COCO/000000039769.png filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.github/ISSUE_TEMPLATE/bug-report.yml ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "\U0001F41B Bug Report"
2
+ description: Submit a bug report to help us improve transformers
3
+ labels: [ "bug" ]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for taking the time to fill out this bug report! 🤗
9
+
10
+ Before you submit your bug report:
11
+
12
+ - If it is your first time submitting, be sure to check our [bug report guidelines](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md#did-you-find-a-bug)
13
+ - Try our [docs bot](https://huggingface.co/spaces/huggingchat/hf-docs-chat) -- it might be able to help you with your issue
14
+
15
+ - type: textarea
16
+ id: system-info
17
+ attributes:
18
+ label: System Info
19
+ description: Please share your system info with us. You can run the command `transformers env` and copy-paste its output below.
20
+ placeholder: transformers version, platform, python version, ...
21
+ validations:
22
+ required: true
23
+
24
+ - type: textarea
25
+ id: who-can-help
26
+ attributes:
27
+ label: Who can help?
28
+ description: |
29
+ Your issue will be replied to more quickly if you can figure out the right person to tag with @
30
+ If you know how to use git blame, that is the easiest way, otherwise, here is a rough guide of **who to tag**.
31
+
32
+ All issues are read by one of the core maintainers, so if you don't know who to tag, just leave this blank and
33
+ a core maintainer will ping the right person.
34
+
35
+ Please tag fewer than 3 people.
36
+
37
+ Models:
38
+
39
+ - text models: @ArthurZucker @Cyrilvallez
40
+ - vision models: @yonigozlan @molbap
41
+ - audio models: @eustlb @ebezzam @vasqu
42
+ - multimodal models: @zucchini-nlp
43
+ - graph models: @clefourrier
44
+
45
+ Library:
46
+
47
+ - generate: @zucchini-nlp (visual-language models) or @gante (all others)
48
+ - continuous batching: @remi-or @ArthurZucker @McPatate
49
+ - pipelines: @Rocketknight1
50
+ - tokenizers: @ArthurZucker and @itazap
51
+ - trainer: @SunMarc
52
+ - attention: @vasqu @ArthurZucker @CyrilVallez
53
+ - model loading (from pretrained, etc): @CyrilVallez
54
+ - distributed: @3outeille @ArthurZucker
55
+ - CIs: @ydshieh
56
+
57
+ Integrations:
58
+
59
+ - ray/raytune: @richardliaw, @amogkam
60
+ - Big Model Inference: @SunMarc
61
+ - quantization: @SunMarc @MekkCyber
62
+ - kernels: @MekkCyber @drbh
63
+ - peft: @BenjaminBossan @githubnemo
64
+
65
+ Devices/Backends:
66
+
67
+ - AMD ROCm: @ivarflakstad
68
+ - Intel XPU: @IlyasMoutawwakil
69
+ - Ascend NPU: @ivarflakstad
70
+
71
+ Documentation: @stevhliu
72
+
73
+ Model hub:
74
+
75
+ - for issues with a model, report at https://discuss.huggingface.co/ and tag the model's creator.
76
+
77
+ Research projects are not maintained and should be taken as is.
78
+
79
+ placeholder: "@Username ..."
80
+
81
+ - type: checkboxes
82
+ id: information-scripts-examples
83
+ attributes:
84
+ label: Information
85
+ description: 'The problem arises when using:'
86
+ options:
87
+ - label: "The official example scripts"
88
+ - label: "My own modified scripts"
89
+
90
+ - type: checkboxes
91
+ id: information-tasks
92
+ attributes:
93
+ label: Tasks
94
+ description: "The tasks I am working on are:"
95
+ options:
96
+ - label: "An officially supported task in the `examples` folder (such as GLUE/SQuAD, ...)"
97
+ - label: "My own task or dataset (give details below)"
98
+
99
+ - type: textarea
100
+ id: reproduction
101
+ validations:
102
+ required: true
103
+ attributes:
104
+ label: Reproduction
105
+ description: |
106
+ Please provide a code sample that reproduces the problem you ran into. It can be a Colab link or just a code snippet.
107
+ Please include relevant config information with your code, for example your Trainers, TRL, Peft, and DeepSpeed configs.
108
+ If you have code snippets, error messages, stack traces please provide them here as well.
109
+ Important! Use code tags to correctly format your code. See https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting
110
+ Do not use screenshots, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.
111
+
112
+ placeholder: |
113
+ Steps to reproduce the behavior:
114
+
115
+ 1.
116
+ 2.
117
+ 3.
118
+
119
+
120
+ - type: textarea
121
+ id: expected-behavior
122
+ validations:
123
+ required: true
124
+ attributes:
125
+ label: Expected behavior
126
+ description: "A clear and concise description of what you would expect to happen."
.github/ISSUE_TEMPLATE/config.yml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ blank_issues_enabled: true
2
+ version: 2.1
3
+ contact_links:
4
+ - name: Model checkpoints on the Hugging Face Hub
5
+ url: https://huggingface.co/models
6
+ about: Open a Pull request / Discussion related to a specific model checkpoint directly on the Hugging Face Hub
7
+ - name: Website Related
8
+ url: https://github.com/huggingface/hub-docs/issues
9
+ about: Feature requests and bug reports related to the website
10
+ - name: Forum
11
+ url: https://discuss.huggingface.co/
12
+ about: General usage questions and community discussions
.github/ISSUE_TEMPLATE/feature-request.yml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "\U0001F680 Feature request"
2
+ description: Submit a proposal/request for a new transformers feature
3
+ labels: [ "Feature request" ]
4
+ body:
5
+ - type: textarea
6
+ id: feature-request
7
+ validations:
8
+ required: true
9
+ attributes:
10
+ label: Feature request
11
+ description: |
12
+ A clear and concise description of the feature proposal. Please provide a link to the paper and code in case they exist.
13
+
14
+ - type: textarea
15
+ id: motivation
16
+ validations:
17
+ required: true
18
+ attributes:
19
+ label: Motivation
20
+ description: |
21
+ Please outline the motivation for the proposal. Is your feature request related to a problem? e.g., I'm always frustrated when [...]. If this is related to another GitHub issue, please link here too.
22
+
23
+
24
+ - type: textarea
25
+ id: contribution
26
+ validations:
27
+ required: true
28
+ attributes:
29
+ label: Your contribution
30
+ description: |
31
+ Is there any way that you could help, e.g. by submitting a PR? Make sure to read the CONTRIBUTING.MD [readme](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md)
.github/ISSUE_TEMPLATE/i18n.md ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: 🌐 Translating a new language?
3
+ about: Start a new translation effort in your language
4
+ title: '[i18n-<languageCode>] Translating docs to <languageName>'
5
+ labels: WIP
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ <!--
11
+ Note: Please search to see if an issue already exists for the language you are trying to translate.
12
+ -->
13
+
14
+ Hi!
15
+
16
+ Let's bring the documentation to all the <languageName>-speaking community 🌐 (currently 0 out of 267 complete)
17
+
18
+ Who would want to translate? Please follow the 🤗 [TRANSLATING guide](https://github.com/huggingface/transformers/blob/main/docs/TRANSLATING.md). Here is a list of the files ready for translation. Let us know in this issue if you'd like to translate any, and we'll add your name to the list.
19
+
20
+ Some notes:
21
+
22
+ * Please translate using an informal tone (imagine you are talking with a friend about transformers 🤗).
23
+ * Please translate in a gender-neutral way.
24
+ * Add your translations to the folder called `<languageCode>` inside the [source folder](https://github.com/huggingface/transformers/tree/main/docs/source).
25
+ * Register your translation in `<languageCode>/_toctree.yml`; please follow the order of the [English version](https://github.com/huggingface/transformers/blob/main/docs/source/en/_toctree.yml).
26
+ * Once you're finished, open a pull request and tag this issue by including #issue-number in the description, where issue-number is the number of this issue. Please ping @stevhliu for review.
27
+ * 🙋 If you'd like others to help you with the translation, you can also post in the 🤗 [forums](https://discuss.huggingface.co/).
28
+
29
+ ## Get Started section
30
+
31
+ - [ ] [index.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/index.md) https://github.com/huggingface/transformers/pull/20180
32
+ - [ ] [quicktour.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/quicktour.md) (waiting for initial PR to go through)
33
+ - [ ] [installation.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/installation.md).
34
+
35
+ ## Tutorial section
36
+ - [ ] [pipeline_tutorial.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/pipeline_tutorial.md)
37
+ - [ ] [autoclass_tutorial.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/autoclass_tutorial.md)
38
+ - [ ] [preprocessing.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/preprocessing.md)
39
+ - [ ] [training.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/training.md)
40
+ - [ ] [accelerate.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/accelerate.md)
41
+ - [ ] [model_sharing.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/model_sharing.md)
42
+ - [ ] [multilingual.md](https://github.com/huggingface/transformers/blob/main/docs/source/en/multilingual.md)
43
+
44
+ <!--
45
+ Keep on adding more as you go 🔥
46
+ -->
.github/ISSUE_TEMPLATE/migration.yml ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "\U0001F4DA Migration from pytorch-pretrained-bert or pytorch-transformers"
2
+ description: Report a problem when migrating from pytorch-pretrained-bert or pytorch-transformers to transformers
3
+ labels: [ "migration" ]
4
+ body:
5
+ - type: textarea
6
+ id: system-info
7
+ attributes:
8
+ label: System Info
9
+ description: Please share your system info with us. You can run the command `transformers env` and copy-paste its output below.
10
+ render: shell
11
+ placeholder: transformers version, platform, python version, ...
12
+ validations:
13
+ required: true
14
+
15
+ - type: checkboxes
16
+ id: information-scripts-examples
17
+ attributes:
18
+ label: Information
19
+ description: 'The problem arises when using:'
20
+ options:
21
+ - label: "The official example scripts"
22
+ - label: "My own modified scripts"
23
+
24
+ - type: checkboxes
25
+ id: information-tasks
26
+ attributes:
27
+ label: Tasks
28
+ description: "The tasks I am working on are:"
29
+ options:
30
+ - label: "An officially supported task in the `examples` folder (such as GLUE/SQuAD, ...)"
31
+ - label: "My own task or dataset (give details below)"
32
+
33
+ - type: textarea
34
+ id: reproduction
35
+ validations:
36
+ required: true
37
+ attributes:
38
+ label: Reproduction
39
+ description: |
40
+ Please provide a code sample that reproduces the problem you ran into. It can be a Colab link or just a code snippet.
41
+ If you have code snippets, error messages, stack traces please provide them here as well.
42
+ Important! Use code tags to correctly format your code. See https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting
43
+ Do not use screenshots, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.
44
+
45
+ placeholder: |
46
+ Steps to reproduce the behavior:
47
+
48
+ 1.
49
+ 2.
50
+ 3.
51
+
52
+
53
+ - type: textarea
54
+ id: expected-behavior
55
+ validations:
56
+ required: true
57
+ attributes:
58
+ label: Expected behavior
59
+ description: "A clear and concise description of what you would expect to happen."
60
+ render: shell
61
+
62
+ - type: checkboxes
63
+ id: checklist
64
+ attributes:
65
+ label: Checklist
66
+ options:
67
+ - label: "I have read the migration guide in the readme.
68
+ ([pytorch-transformers](https://github.com/huggingface/transformers#migrating-from-pytorch-transformers-to-transformers);
69
+ [pytorch-pretrained-bert](https://github.com/huggingface/transformers#migrating-from-pytorch-pretrained-bert-to-transformers))"
70
+ required: true
71
+ - label: "I checked if a related official extension example runs on my machine."
72
+ required: true
.github/ISSUE_TEMPLATE/new-model-addition.yml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "\U0001F31F New model addition"
2
+ description: Submit a proposal/request to implement a new model
3
+ labels: [ "New model" ]
4
+
5
+ body:
6
+ - type: textarea
7
+ id: description-request
8
+ validations:
9
+ required: true
10
+ attributes:
11
+ label: Model description
12
+ description: |
13
+ Put any and all important information relative to the model
14
+
15
+ - type: checkboxes
16
+ id: information-tasks
17
+ attributes:
18
+ label: Open source status
19
+ description: |
20
+ Please note that if the model implementation isn't available or if the weights aren't open-source, we are less likely to implement it in `transformers`.
21
+ options:
22
+ - label: "The model implementation is available"
23
+ - label: "The model weights are available"
24
+
25
+ - type: textarea
26
+ id: additional-info
27
+ attributes:
28
+ label: Provide useful links for the implementation
29
+ description: |
30
+ Please provide information regarding the implementation, the weights, and the authors.
31
+ Please mention the authors by @gh-username if you're aware of their usernames.
.github/PULL_REQUEST_TEMPLATE.md ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # What does this PR do?
2
+
3
+ <!--
4
+ Congratulations! You've made it this far! You're not quite done yet though.
5
+
6
+ Once merged, your PR is going to appear in the release notes with the title you set, so make sure it's a great title that fully reflects the extent of your awesome contribution.
7
+
8
+ Then, please replace this with a description of the change and which issue is fixed (if applicable). Please also include relevant motivation and context. List any dependencies (if any) that are required for this change.
9
+
10
+ Once you're done, someone will review your PR shortly (see the section "Who can review?" below to tag some potential reviewers). They may suggest changes to make the code even better. If no one reviewed your PR after a week has passed, don't hesitate to post a new comment @-mentioning the same persons---sometimes notifications get lost.
11
+ -->
12
+
13
+ <!-- Remove if not applicable -->
14
+
15
+ Fixes # (issue)
16
+
17
+
18
+ ## Before submitting
19
+ - [ ] This PR fixes a typo or improves the docs (you can dismiss the other checks if that's the case).
20
+ - [ ] Did you read the [contributor guideline](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md#create-a-pull-request),
21
+ Pull Request section?
22
+ - [ ] Was this discussed/approved via a Github issue or the [forum](https://discuss.huggingface.co/)? Please add a link
23
+ to it if that's the case.
24
+ - [ ] Did you make sure to update the documentation with your changes? Here are the
25
+ [documentation guidelines](https://github.com/huggingface/transformers/tree/main/docs), and
26
+ [here are tips on formatting docstrings](https://github.com/huggingface/transformers/tree/main/docs#writing-source-documentation).
27
+ - [ ] Did you write any new necessary tests?
28
+
29
+
30
+ ## Who can review?
31
+
32
+ Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
33
+ members/contributors who may be interested in your PR.
34
+
35
+ <!-- Your PR will be replied to more quickly if you can figure out the right person to tag with @
36
+
37
+ If you know how to use git blame, that is the easiest way, otherwise, here is a rough guide of **who to tag**.
38
+ Please tag fewer than 3 people.
39
+
40
+ Models:
41
+
42
+ - text models: @ArthurZucker @Cyrilvallez
43
+ - vision models: @yonigozlan @molbap
44
+ - audio models: @eustlb @ebezzam @vasqu
45
+ - multimodal models: @zucchini-nlp
46
+ - graph models: @clefourrier
47
+
48
+ Library:
49
+
50
+ - generate: @zucchini-nlp (visual-language models) or @gante (all others)
51
+ - continuous batching: @remi-or @ArthurZucker @McPatate
52
+ - pipelines: @Rocketknight1
53
+ - tokenizers: @ArthurZucker and @itazap
54
+ - trainer: @SunMarc
55
+ - attention: @vasqu @ArthurZucker @CyrilVallez
56
+ - model loading (from pretrained, etc): @CyrilVallez
57
+ - distributed: @3outeille @ArthurZucker
58
+ - CIs: @ydshieh
59
+
60
+ Integrations:
61
+
62
+ - ray/raytune: @richardliaw, @amogkam
63
+ - Big Model Inference: @SunMarc
64
+ - quantization: @SunMarc @MekkCyber
65
+ - kernels: @MekkCyber @drbh
66
+ - peft: @BenjaminBossan @githubnemo
67
+
68
+ Devices/Backends:
69
+
70
+ - AMD ROCm: @ivarflakstad
71
+ - Intel XPU: @IlyasMoutawwakil
72
+ - Ascend NPU: @ivarflakstad
73
+
74
+ Documentation: @stevhliu
75
+
76
+ Research projects are not maintained and should be taken as is.
77
+
78
+ -->
.github/conda/build.sh ADDED
@@ -0,0 +1 @@
 
 
1
+ $PYTHON setup.py install # Python command to install the script.
.github/conda/meta.yaml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% set name = "transformers" %}
2
+
3
+ package:
4
+ name: "{{ name|lower }}"
5
+ version: "{{ TRANSFORMERS_VERSION }}"
6
+
7
+ source:
8
+ path: ../../
9
+
10
+ build:
11
+ noarch: python
12
+
13
+ requirements:
14
+ host:
15
+ - python
16
+ - pip
17
+ - numpy >=1.17
18
+ - dataclasses
19
+ - huggingface_hub
20
+ - packaging
21
+ - filelock
22
+ - requests
23
+ - tqdm >=4.27
24
+ - sacremoses
25
+ - regex !=2019.12.17
26
+ - protobuf
27
+ - tokenizers >=0.11.1,!=0.11.3,<0.13
28
+ - pyyaml >=5.1
29
+ - safetensors
30
+ - fsspec
31
+ run:
32
+ - python
33
+ - numpy >=1.17
34
+ - dataclasses
35
+ - huggingface_hub
36
+ - packaging
37
+ - filelock
38
+ - requests
39
+ - tqdm >=4.27
40
+ - sacremoses
41
+ - regex !=2019.12.17
42
+ - protobuf
43
+ - tokenizers >=0.11.1,!=0.11.3,<0.13
44
+ - pyyaml >=5.1
45
+ - safetensors
46
+ - fsspec
47
+
48
+ test:
49
+ imports:
50
+ - transformers
51
+
52
+ about:
53
+ home: https://huggingface.co
54
+ license: Apache License 2.0
55
+ license_file: LICENSE
56
+ summary: "🤗Transformers: State-of-the-art Natural Language Processing for Pytorch and TensorFlow 2.0."
.github/copilot-instructions.md ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # copilot-instructions.md Guide for Hugging Face Transformers
2
+
3
+ This copilot-instructions.md file provides guidance for code agents working with this codebase.
4
+
5
+ ## Core Project Structure
6
+
7
+ - `/src/transformers`: This contains the core source code for the library
8
+ - `/models`: Code for individual models. Models inherit from base classes in the root `/src/transformers` directory.
9
+ - `/tests`: This contains the core test classes for the library. These are usually inherited rather than directly run.
10
+ - `/models`: Tests for individual models. Model tests inherit from common tests in the root `/tests` directory.
11
+ - `/docs`: This contains the documentation for the library, including guides, tutorials, and API references.
12
+
13
+ ## Coding Conventions for Hugging Face Transformers
14
+
15
+ - PRs should be as brief as possible. Bugfix PRs in particular can often be only one or two lines long, and do not need large comments, docstrings or new functions in this case. Aim to minimize the size of the diff.
16
+ - When writing tests, they should be added to an existing file. The only exception is for PRs to add a new model, when a new test directory should be created for that model.
17
+ - Code style is enforced in the CI. You can install the style tools with `pip install -e .[quality]`. You can then run `make fixup` to apply style and consistency fixes to your code.
18
+
19
+ ## Copying and inheritance
20
+
21
+ Many models in the codebase have similar code, but it is not shared by inheritance because we want each model file to be self-contained.
22
+ We use two mechanisms to keep this code in sync:
23
+
24
+ - "Copied from" syntax. Functions or entire classes can have a comment at the top like this: `# Copied from transformers.models.llama.modeling_llama.rotate_half` or `# Copied from transformers.models.t5.modeling_t5.T5LayerNorm with T5->MT5`
25
+ These comments are actively checked by the style tools, and copies will automatically be updated when the base code is updated. If you need to update a copied function, you should
26
+ either update the base function and use `make fixup` to propagate the change to all copies, or simply remove the `# Copied from` comment if that is inappropriate.
27
+ - "Modular" files. These files briefly define models by composing them using inheritance from other models. They are not meant to be used directly. Instead, the style tools
28
+ automatically generate a complete modeling file, like `modeling_bert.py`, from the modular file like `modular_bert.py`. If a model has a modular file, the modeling file
29
+ should never be edited directly! Instead, changes should be made in the modular file, and then you should run `make fixup` to update the modeling file automatically.
30
+
31
+ When adding new models, you should prefer `modular` style and inherit as many classes as possible from existing models.
32
+
33
+ ## Testing
34
+
35
+ After making changes, you should usually run `make fixup` to ensure any copies and modular files are updated, and then test all affected models. This includes both
36
+ the model you made the changes in and any other models that were updated by `make fixup`. Tests can be run with `pytest tests/models/[name]/test_modeling_[name].py`
37
+ If your changes affect code in other classes like tokenizers or processors, you should run those tests instead, like `test_processing_[name].py` or `test_tokenization_[name].py`.
38
+
39
+ In order to run tests, you may need to install dependencies. You can do this with `pip install -e .[testing]`. You will probably also need to `pip install torch accelerate` if your environment does not already have them.
.github/scripts/assign_reviewers.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2025 the HuggingFace Inc. team. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import json
17
+ import os
18
+ import re
19
+ from collections import Counter
20
+ from pathlib import Path
21
+
22
+ import github
23
+ from github import Github
24
+
25
+
26
+ def pattern_to_regex(pattern):
27
+ if pattern.startswith("/"):
28
+ start_anchor = True
29
+ pattern = re.escape(pattern[1:])
30
+ else:
31
+ start_anchor = False
32
+ pattern = re.escape(pattern)
33
+ # Replace `*` with "any number of non-slash characters"
34
+ pattern = pattern.replace(r"\*", "[^/]*")
35
+ if start_anchor:
36
+ pattern = r"^\/?" + pattern # Allow an optional leading slash after the start of the string
37
+ return pattern
38
+
39
+ def get_file_owners(file_path, codeowners_lines):
40
+ # Process lines in reverse (last matching pattern takes precedence)
41
+ for line in reversed(codeowners_lines):
42
+ # Skip comments and empty lines, strip inline comments
43
+ line = line.split('#')[0].strip()
44
+ if not line:
45
+ continue
46
+
47
+ # Split into pattern and owners
48
+ parts = line.split()
49
+ pattern = parts[0]
50
+ # Can be empty, e.g. for dummy files with explicitly no owner!
51
+ owners = [owner.removeprefix("@") for owner in parts[1:]]
52
+
53
+ # Check if file matches pattern
54
+ file_regex = pattern_to_regex(pattern)
55
+ if re.search(file_regex, file_path) is not None:
56
+ return owners # Remember, can still be empty!
57
+ return [] # Should never happen, but just in case
58
+
59
+ def pr_author_is_in_hf(pr_author, codeowners_lines):
60
+ # Check if the PR author is in the codeowners file
61
+ for line in codeowners_lines:
62
+ line = line.split('#')[0].strip()
63
+ if not line:
64
+ continue
65
+
66
+ # Split into pattern and owners
67
+ parts = line.split()
68
+ owners = [owner.removeprefix("@") for owner in parts[1:]]
69
+
70
+ if pr_author in owners:
71
+ return True
72
+ return False
73
+
74
+ def main():
75
+ script_dir = Path(__file__).parent.absolute()
76
+ with open(script_dir / "codeowners_for_review_action") as f:
77
+ codeowners_lines = f.readlines()
78
+
79
+ g = Github(os.environ['GITHUB_TOKEN'])
80
+ repo = g.get_repo("huggingface/transformers")
81
+ with open(os.environ['GITHUB_EVENT_PATH']) as f:
82
+ event = json.load(f)
83
+
84
+ # The PR number is available in the event payload
85
+ pr_number = event['pull_request']['number']
86
+ pr = repo.get_pull(pr_number)
87
+ pr_author = pr.user.login
88
+ if pr_author_is_in_hf(pr_author, codeowners_lines):
89
+ print(f"PR author {pr_author} is in codeowners, skipping review request.")
90
+ return
91
+
92
+ existing_reviews = list(pr.get_reviews())
93
+ if existing_reviews:
94
+ print(f"Already has reviews: {[r.user.login for r in existing_reviews]}")
95
+ return
96
+
97
+ users_requested, teams_requested = pr.get_review_requests()
98
+ users_requested = list(users_requested)
99
+ if users_requested:
100
+ print(f"Reviewers already requested: {users_requested}")
101
+ return
102
+
103
+ locs_per_owner = Counter()
104
+ for file in pr.get_files():
105
+ owners = get_file_owners(file.filename, codeowners_lines)
106
+ for owner in owners:
107
+ locs_per_owner[owner] += file.changes
108
+
109
+ # Assign the top 2 based on locs changed as reviewers, but skip the owner if present
110
+ locs_per_owner.pop(pr_author, None)
111
+ top_owners = locs_per_owner.most_common(2)
112
+ print("Top owners", top_owners)
113
+ top_owners = [owner[0] for owner in top_owners]
114
+ try:
115
+ pr.create_review_request(top_owners)
116
+ except github.GithubException as e:
117
+ print(f"Failed to request review for {top_owners}: {e}")
118
+
119
+
120
+
121
+ if __name__ == "__main__":
122
+ main()
.github/scripts/codeowners_for_review_action ADDED
@@ -0,0 +1,369 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Top-level rules are matched only if nothing else matches
2
+ * @Rocketknight1 @ArthurZucker # if no one is pinged based on the other rules, he will do the dispatch
3
+ *.md @stevhliu
4
+ *tokenization* @ArthurZucker
5
+ docs/ @stevhliu
6
+ /benchmark/ @McPatate
7
+ /docker/ @ydshieh @ArthurZucker
8
+
9
+ # More high-level globs catch cases when specific rules later don't apply
10
+ /src/transformers/models/*/processing* @molbap @yonigozlan
11
+ /src/transformers/models/*/image_processing* @yonigozlan
12
+ /src/transformers/models/*/image_processing_*_fast* @yonigozlan
13
+
14
+ # Owners of subsections of the library
15
+ /src/transformers/generation/ @gante
16
+ /src/transformers/pipeline/ @Rocketknight1 @yonigozlan
17
+ /src/transformers/integrations/ @SunMarc @MekkCyber @zach-huggingface
18
+ /src/transformers/quantizers/ @SunMarc @MekkCyber
19
+ tests/ @ydshieh
20
+ tests/generation/ @gante
21
+
22
+ /src/transformers/models/auto/ @ArthurZucker
23
+ /src/transformers/utils/ @ArthurZucker @Rocketknight1
24
+ /src/transformers/loss/ @ArthurZucker
25
+
26
+ # Specific files come after the sections/globs, so they take priority
27
+ /.circleci/config.yml @ArthurZucker @ydshieh
28
+ /utils/tests_fetcher.py @ydshieh
29
+ trainer.py @zach-huggingface @SunMarc
30
+ trainer_utils.py @zach-huggingface @SunMarc
31
+ /utils/modular_model_converter.py @Cyrilvallez @ArthurZucker
32
+
33
+ # Owners of individual models are specific / high priority, and so they come last
34
+ # mod* captures modeling and modular files
35
+
36
+ # Text models
37
+ /src/transformers/models/albert/mod*_albert* @ArthurZucker
38
+ /src/transformers/models/bamba/mod*_bamba* @ArthurZucker
39
+ /src/transformers/models/bart/mod*_bart* @ArthurZucker
40
+ /src/transformers/models/barthez/mod*_barthez* @ArthurZucker
41
+ /src/transformers/models/bartpho/mod*_bartpho* @ArthurZucker
42
+ /src/transformers/models/bert/mod*_bert* @ArthurZucker
43
+ /src/transformers/models/bert_generation/mod*_bert_generation* @ArthurZucker
44
+ /src/transformers/models/bert_japanese/mod*_bert_japanese* @ArthurZucker
45
+ /src/transformers/models/bertweet/mod*_bertweet* @ArthurZucker
46
+ /src/transformers/models/big_bird/mod*_big_bird* @ArthurZucker
47
+ /src/transformers/models/bigbird_pegasus/mod*_bigbird_pegasus* @ArthurZucker
48
+ /src/transformers/models/biogpt/mod*_biogpt* @ArthurZucker
49
+ /src/transformers/models/blenderbot/mod*_blenderbot* @ArthurZucker
50
+ /src/transformers/models/blenderbot_small/mod*_blenderbot_small* @ArthurZucker
51
+ /src/transformers/models/bloom/mod*_bloom* @ArthurZucker
52
+ /src/transformers/models/bort/mod*_bort* @ArthurZucker
53
+ /src/transformers/models/byt5/mod*_byt5* @ArthurZucker
54
+ /src/transformers/models/camembert/mod*_camembert* @ArthurZucker
55
+ /src/transformers/models/canine/mod*_canine* @ArthurZucker
56
+ /src/transformers/models/codegen/mod*_codegen* @ArthurZucker
57
+ /src/transformers/models/code_llama/mod*_code_llama* @ArthurZucker
58
+ /src/transformers/models/cohere/mod*_cohere* @ArthurZucker
59
+ /src/transformers/models/cohere2/mod*_cohere2* @ArthurZucker
60
+ /src/transformers/models/convbert/mod*_convbert* @ArthurZucker
61
+ /src/transformers/models/cpm/mod*_cpm* @ArthurZucker
62
+ /src/transformers/models/cpmant/mod*_cpmant* @ArthurZucker
63
+ /src/transformers/models/ctrl/mod*_ctrl* @ArthurZucker
64
+ /src/transformers/models/dbrx/mod*_dbrx* @ArthurZucker
65
+ /src/transformers/models/deberta/mod*_deberta* @ArthurZucker
66
+ /src/transformers/models/deberta_v2/mod*_deberta_v2* @ArthurZucker
67
+ /src/transformers/models/dialogpt/mod*_dialogpt* @ArthurZucker
68
+ /src/transformers/models/diffllama/mod*_diffllama* @ArthurZucker
69
+ /src/transformers/models/distilbert/mod*_distilbert* @ArthurZucker
70
+ /src/transformers/models/dpr/mod*_dpr* @ArthurZucker
71
+ /src/transformers/models/electra/mod*_electra* @ArthurZucker
72
+ /src/transformers/models/encoder_decoder/mod*_encoder_decoder* @ArthurZucker
73
+ /src/transformers/models/ernie/mod*_ernie* @ArthurZucker
74
+ /src/transformers/models/ernie_m/mod*_ernie_m* @ArthurZucker
75
+ /src/transformers/models/esm/mod*_esm* @ArthurZucker
76
+ /src/transformers/models/falcon/mod*_falcon* @ArthurZucker
77
+ /src/transformers/models/falcon3/mod*_falcon3* @ArthurZucker
78
+ /src/transformers/models/falcon_mamba/mod*_falcon_mamba* @ArthurZucker
79
+ /src/transformers/models/fastspeech2_conformer/mod*_fastspeech2_conformer* @ArthurZucker
80
+ /src/transformers/models/flan_t5/mod*_flan_t5* @ArthurZucker
81
+ /src/transformers/models/flan_ul2/mod*_flan_ul2* @ArthurZucker
82
+ /src/transformers/models/flaubert/mod*_flaubert* @ArthurZucker
83
+ /src/transformers/models/fnet/mod*_fnet* @ArthurZucker
84
+ /src/transformers/models/fsmt/mod*_fsmt* @ArthurZucker
85
+ /src/transformers/models/funnel/mod*_funnel* @ArthurZucker
86
+ /src/transformers/models/fuyu/mod*_fuyu* @ArthurZucker
87
+ /src/transformers/models/gemma/mod*_gemma* @ArthurZucker
88
+ /src/transformers/models/gemma2/mod*_gemma2* @ArthurZucker
89
+ /src/transformers/models/glm/mod*_glm* @ArthurZucker
90
+ /src/transformers/models/openai_gpt/mod*_openai_gpt* @ArthurZucker
91
+ /src/transformers/models/gpt_neo/mod*_gpt_neo* @ArthurZucker
92
+ /src/transformers/models/gpt_neox/mod*_gpt_neox* @ArthurZucker
93
+ /src/transformers/models/gpt_neox_japanese/mod*_gpt_neox_japanese* @ArthurZucker
94
+ /src/transformers/models/gptj/mod*_gptj* @ArthurZucker
95
+ /src/transformers/models/gpt2/mod*_gpt2* @ArthurZucker
96
+ /src/transformers/models/gpt_bigcode/mod*_gpt_bigcode* @ArthurZucker
97
+ /src/transformers/models/gptsan_japanese/mod*_gptsan_japanese* @ArthurZucker
98
+ /src/transformers/models/gpt_sw3/mod*_gpt_sw3* @ArthurZucker
99
+ /src/transformers/models/granite/mod*_granite* @ArthurZucker
100
+ /src/transformers/models/granitemoe/mod*_granitemoe* @ArthurZucker
101
+ /src/transformers/models/herbert/mod*_herbert* @ArthurZucker
102
+ /src/transformers/models/ibert/mod*_ibert* @ArthurZucker
103
+ /src/transformers/models/jamba/mod*_jamba* @ArthurZucker
104
+ /src/transformers/models/jetmoe/mod*_jetmoe* @ArthurZucker
105
+ /src/transformers/models/jukebox/mod*_jukebox* @ArthurZucker
106
+ /src/transformers/models/led/mod*_led* @ArthurZucker
107
+ /src/transformers/models/llama/mod*_llama* @ArthurZucker @Cyrilvallez
108
+ /src/transformers/models/longformer/mod*_longformer* @ArthurZucker
109
+ /src/transformers/models/longt5/mod*_longt5* @ArthurZucker
110
+ /src/transformers/models/luke/mod*_luke* @ArthurZucker
111
+ /src/transformers/models/m2m_100/mod*_m2m_100* @ArthurZucker
112
+ /src/transformers/models/madlad_400/mod*_madlad_400* @ArthurZucker
113
+ /src/transformers/models/mamba/mod*_mamba* @ArthurZucker
114
+ /src/transformers/models/mamba2/mod*_mamba2* @ArthurZucker
115
+ /src/transformers/models/marian/mod*_marian* @ArthurZucker
116
+ /src/transformers/models/markuplm/mod*_markuplm* @ArthurZucker
117
+ /src/transformers/models/mbart/mod*_mbart* @ArthurZucker
118
+ /src/transformers/models/mega/mod*_mega* @ArthurZucker
119
+ /src/transformers/models/megatron_bert/mod*_megatron_bert* @ArthurZucker
120
+ /src/transformers/models/megatron_gpt2/mod*_megatron_gpt2* @ArthurZucker
121
+ /src/transformers/models/mistral/mod*_mistral* @ArthurZucker
122
+ /src/transformers/models/mixtral/mod*_mixtral* @ArthurZucker
123
+ /src/transformers/models/mluke/mod*_mluke* @ArthurZucker
124
+ /src/transformers/models/mobilebert/mod*_mobilebert* @ArthurZucker
125
+ /src/transformers/models/modernbert/mod*_modernbert* @ArthurZucker
126
+ /src/transformers/models/mpnet/mod*_mpnet* @ArthurZucker
127
+ /src/transformers/models/mpt/mod*_mpt* @ArthurZucker
128
+ /src/transformers/models/mra/mod*_mra* @ArthurZucker
129
+ /src/transformers/models/mt5/mod*_mt5* @ArthurZucker
130
+ /src/transformers/models/mvp/mod*_mvp* @ArthurZucker
131
+ /src/transformers/models/myt5/mod*_myt5* @ArthurZucker
132
+ /src/transformers/models/nemotron/mod*_nemotron* @ArthurZucker
133
+ /src/transformers/models/nezha/mod*_nezha* @ArthurZucker
134
+ /src/transformers/models/nllb/mod*_nllb* @ArthurZucker
135
+ /src/transformers/models/nllb_moe/mod*_nllb_moe* @ArthurZucker
136
+ /src/transformers/models/nystromformer/mod*_nystromformer* @ArthurZucker
137
+ /src/transformers/models/olmo/mod*_olmo* @ArthurZucker
138
+ /src/transformers/models/olmo2/mod*_olmo2* @ArthurZucker
139
+ /src/transformers/models/olmoe/mod*_olmoe* @ArthurZucker
140
+ /src/transformers/models/open_llama/mod*_open_llama* @ArthurZucker
141
+ /src/transformers/models/opt/mod*_opt* @ArthurZucker
142
+ /src/transformers/models/pegasus/mod*_pegasus* @ArthurZucker
143
+ /src/transformers/models/pegasus_x/mod*_pegasus_x* @ArthurZucker
144
+ /src/transformers/models/persimmon/mod*_persimmon* @ArthurZucker
145
+ /src/transformers/models/phi/mod*_phi* @ArthurZucker
146
+ /src/transformers/models/phi3/mod*_phi3* @ArthurZucker
147
+ /src/transformers/models/phimoe/mod*_phimoe* @ArthurZucker
148
+ /src/transformers/models/phobert/mod*_phobert* @ArthurZucker
149
+ /src/transformers/models/plbart/mod*_plbart* @ArthurZucker
150
+ /src/transformers/models/prophetnet/mod*_prophetnet* @ArthurZucker
151
+ /src/transformers/models/qdqbert/mod*_qdqbert* @ArthurZucker
152
+ /src/transformers/models/qwen2/mod*_qwen2* @ArthurZucker
153
+ /src/transformers/models/qwen2_moe/mod*_qwen2_moe* @ArthurZucker
154
+ /src/transformers/models/rag/mod*_rag* @ArthurZucker
155
+ /src/transformers/models/realm/mod*_realm* @ArthurZucker
156
+ /src/transformers/models/recurrent_gemma/mod*_recurrent_gemma* @ArthurZucker
157
+ /src/transformers/models/reformer/mod*_reformer* @ArthurZucker
158
+ /src/transformers/models/rembert/mod*_rembert* @ArthurZucker
159
+ /src/transformers/models/retribert/mod*_retribert* @ArthurZucker
160
+ /src/transformers/models/roberta/mod*_roberta* @ArthurZucker
161
+ /src/transformers/models/roberta_prelayernorm/mod*_roberta_prelayernorm* @ArthurZucker
162
+ /src/transformers/models/roc_bert/mod*_roc_bert* @ArthurZucker
163
+ /src/transformers/models/roformer/mod*_roformer* @ArthurZucker
164
+ /src/transformers/models/rwkv/mod*_rwkv* @ArthurZucker
165
+ /src/transformers/models/splinter/mod*_splinter* @ArthurZucker
166
+ /src/transformers/models/squeezebert/mod*_squeezebert* @ArthurZucker
167
+ /src/transformers/models/stablelm/mod*_stablelm* @ArthurZucker
168
+ /src/transformers/models/starcoder2/mod*_starcoder2* @ArthurZucker
169
+ /src/transformers/models/switch_transformers/mod*_switch_transformers* @ArthurZucker
170
+ /src/transformers/models/t5/mod*_t5* @ArthurZucker
171
+ /src/transformers/models/t5v1.1/mod*_t5v1.1* @ArthurZucker
172
+ /src/transformers/models/tapex/mod*_tapex* @ArthurZucker
173
+ /src/transformers/models/transfo_xl/mod*_transfo_xl* @ArthurZucker
174
+ /src/transformers/models/ul2/mod*_ul2* @ArthurZucker
175
+ /src/transformers/models/umt5/mod*_umt5* @ArthurZucker
176
+ /src/transformers/models/xmod/mod*_xmod* @ArthurZucker
177
+ /src/transformers/models/xglm/mod*_xglm* @ArthurZucker
178
+ /src/transformers/models/xlm/mod*_xlm* @ArthurZucker
179
+ /src/transformers/models/xlm_prophetnet/mod*_xlm_prophetnet* @ArthurZucker
180
+ /src/transformers/models/xlm_roberta/mod*_xlm_roberta* @ArthurZucker
181
+ /src/transformers/models/xlm_roberta_xl/mod*_xlm_roberta_xl* @ArthurZucker
182
+ /src/transformers/models/xlm_v/mod*_xlm_v* @ArthurZucker
183
+ /src/transformers/models/xlnet/mod*_xlnet* @ArthurZucker
184
+ /src/transformers/models/yoso/mod*_yoso* @ArthurZucker
185
+ /src/transformers/models/zamba/mod*_zamba* @ArthurZucker
186
+
187
+ # Vision models
188
+ /src/transformers/models/beit/mod*_beit* @yonigozlan @molbap
189
+ /src/transformers/models/bit/mod*_bit* @yonigozlan @molbap
190
+ /src/transformers/models/conditional_detr/mod*_conditional_detr* @yonigozlan @molbap
191
+ /src/transformers/models/convnext/mod*_convnext* @yonigozlan @molbap
192
+ /src/transformers/models/convnextv2/mod*_convnextv2* @yonigozlan @molbap
193
+ /src/transformers/models/cvt/mod*_cvt* @yonigozlan @molbap
194
+ /src/transformers/models/deformable_detr/mod*_deformable_detr* @yonigozlan @molbap
195
+ /src/transformers/models/deit/mod*_deit* @yonigozlan @molbap
196
+ /src/transformers/models/depth_anything/mod*_depth_anything* @yonigozlan @molbap
197
+ /src/transformers/models/depth_anything_v2/mod*_depth_anything_v2* @yonigozlan @molbap
198
+ /src/transformers/models/deta/mod*_deta* @yonigozlan @molbap
199
+ /src/transformers/models/detr/mod*_detr* @yonigozlan @molbap
200
+ /src/transformers/models/dinat/mod*_dinat* @yonigozlan @molbap
201
+ /src/transformers/models/dinov2/mod*_dinov2* @yonigozlan @molbap
202
+ /src/transformers/models/dinov2_with_registers/mod*_dinov2_with_registers* @yonigozlan @molbap
203
+ /src/transformers/models/dit/mod*_dit* @yonigozlan @molbap
204
+ /src/transformers/models/dpt/mod*_dpt* @yonigozlan @molbap
205
+ /src/transformers/models/efficientformer/mod*_efficientformer* @yonigozlan @molbap
206
+ /src/transformers/models/efficientnet/mod*_efficientnet* @yonigozlan @molbap
207
+ /src/transformers/models/focalnet/mod*_focalnet* @yonigozlan @molbap
208
+ /src/transformers/models/glpn/mod*_glpn* @yonigozlan @molbap
209
+ /src/transformers/models/hiera/mod*_hiera* @yonigozlan @molbap
210
+ /src/transformers/models/ijepa/mod*_ijepa* @yonigozlan @molbap
211
+ /src/transformers/models/imagegpt/mod*_imagegpt* @yonigozlan @molbap
212
+ /src/transformers/models/levit/mod*_levit* @yonigozlan @molbap
213
+ /src/transformers/models/mask2former/mod*_mask2former* @yonigozlan @molbap
214
+ /src/transformers/models/maskformer/mod*_maskformer* @yonigozlan @molbap
215
+ /src/transformers/models/mobilenet_v1/mod*_mobilenet_v1* @yonigozlan @molbap
216
+ /src/transformers/models/mobilenet_v2/mod*_mobilenet_v2* @yonigozlan @molbap
217
+ /src/transformers/models/mobilevit/mod*_mobilevit* @yonigozlan @molbap
218
+ /src/transformers/models/mobilevitv2/mod*_mobilevitv2* @yonigozlan @molbap
219
+ /src/transformers/models/nat/mod*_nat* @yonigozlan @molbap
220
+ /src/transformers/models/poolformer/mod*_poolformer* @yonigozlan @molbap
221
+ /src/transformers/models/pvt/mod*_pvt* @yonigozlan @molbap
222
+ /src/transformers/models/pvt_v2/mod*_pvt_v2* @yonigozlan @molbap
223
+ /src/transformers/models/regnet/mod*_regnet* @yonigozlan @molbap
224
+ /src/transformers/models/resnet/mod*_resnet* @yonigozlan @molbap
225
+ /src/transformers/models/rt_detr/mod*_rt_detr* @yonigozlan @molbap
226
+ /src/transformers/models/segformer/mod*_segformer* @yonigozlan @molbap
227
+ /src/transformers/models/seggpt/mod*_seggpt* @yonigozlan @molbap
228
+ /src/transformers/models/superpoint/mod*_superpoint* @yonigozlan @molbap
229
+ /src/transformers/models/swiftformer/mod*_swiftformer* @yonigozlan @molbap
230
+ /src/transformers/models/swin/mod*_swin* @yonigozlan @molbap
231
+ /src/transformers/models/swinv2/mod*_swinv2* @yonigozlan @molbap
232
+ /src/transformers/models/swin2sr/mod*_swin2sr* @yonigozlan @molbap
233
+ /src/transformers/models/table_transformer/mod*_table_transformer* @yonigozlan @molbap
234
+ /src/transformers/models/textnet/mod*_textnet* @yonigozlan @molbap
235
+ /src/transformers/models/timm_wrapper/mod*_timm_wrapper* @yonigozlan @molbap
236
+ /src/transformers/models/upernet/mod*_upernet* @yonigozlan @molbap
237
+ /src/transformers/models/van/mod*_van* @yonigozlan @molbap
238
+ /src/transformers/models/vit/mod*_vit* @yonigozlan @molbap
239
+ /src/transformers/models/vit_hybrid/mod*_vit_hybrid* @yonigozlan @molbap
240
+ /src/transformers/models/vitdet/mod*_vitdet* @yonigozlan @molbap
241
+ /src/transformers/models/vit_mae/mod*_vit_mae* @yonigozlan @molbap
242
+ /src/transformers/models/vitmatte/mod*_vitmatte* @yonigozlan @molbap
243
+ /src/transformers/models/vit_msn/mod*_vit_msn* @yonigozlan @molbap
244
+ /src/transformers/models/vitpose/mod*_vitpose* @yonigozlan @molbap
245
+ /src/transformers/models/yolos/mod*_yolos* @yonigozlan @molbap
246
+ /src/transformers/models/zoedepth/mod*_zoedepth* @yonigozlan @molbap
247
+
248
+ # Audio models
249
+ /src/transformers/models/audio_spectrogram_transformer/mod*_audio_spectrogram_transformer* @eustlb
250
+ /src/transformers/models/bark/mod*_bark* @eustlb
251
+ /src/transformers/models/clap/mod*_clap* @eustlb
252
+ /src/transformers/models/dac/mod*_dac* @eustlb
253
+ /src/transformers/models/encodec/mod*_encodec* @eustlb
254
+ /src/transformers/models/hubert/mod*_hubert* @eustlb
255
+ /src/transformers/models/mctct/mod*_mctct* @eustlb
256
+ /src/transformers/models/mimi/mod*_mimi* @eustlb
257
+ /src/transformers/models/mms/mod*_mms* @eustlb
258
+ /src/transformers/models/moshi/mod*_moshi* @eustlb
259
+ /src/transformers/models/musicgen/mod*_musicgen* @eustlb
260
+ /src/transformers/models/musicgen_melody/mod*_musicgen_melody* @eustlb
261
+ /src/transformers/models/pop2piano/mod*_pop2piano* @eustlb
262
+ /src/transformers/models/seamless_m4t/mod*_seamless_m4t* @eustlb
263
+ /src/transformers/models/seamless_m4t_v2/mod*_seamless_m4t_v2* @eustlb
264
+ /src/transformers/models/sew/mod*_sew* @eustlb
265
+ /src/transformers/models/sew_d/mod*_sew_d* @eustlb
266
+ /src/transformers/models/speech_to_text/mod*_speech_to_text* @eustlb
267
+ /src/transformers/models/speech_to_text_2/mod*_speech_to_text_2* @eustlb
268
+ /src/transformers/models/speecht5/mod*_speecht5* @eustlb
269
+ /src/transformers/models/unispeech/mod*_unispeech* @eustlb
270
+ /src/transformers/models/unispeech_sat/mod*_unispeech_sat* @eustlb
271
+ /src/transformers/models/univnet/mod*_univnet* @eustlb
272
+ /src/transformers/models/vits/mod*_vits* @eustlb
273
+ /src/transformers/models/wav2vec2/mod*_wav2vec2* @eustlb
274
+ /src/transformers/models/wav2vec2_bert/mod*_wav2vec2_bert* @eustlb
275
+ /src/transformers/models/wav2vec2_conformer/mod*_wav2vec2_conformer* @eustlb
276
+ /src/transformers/models/wav2vec2_phoneme/mod*_wav2vec2_phoneme* @eustlb
277
+ /src/transformers/models/wavlm/mod*_wavlm* @eustlb
278
+ /src/transformers/models/whisper/mod*_whisper* @eustlb
279
+ /src/transformers/models/xls_r/mod*_xls_r* @eustlb
280
+ /src/transformers/models/xlsr_wav2vec2/mod*_xlsr_wav2vec2* @eustlb
281
+
282
+ # Video models
283
+ /src/transformers/models/timesformer/mod*_timesformer* @Rocketknight1
284
+ /src/transformers/models/videomae/mod*_videomae* @Rocketknight1
285
+ /src/transformers/models/vivit/mod*_vivit* @Rocketknight1
286
+
287
+ # Multimodal models
288
+ /src/transformers/models/align/mod*_align* @zucchini-nlp
289
+ /src/transformers/models/altclip/mod*_altclip* @zucchini-nlp
290
+ /src/transformers/models/aria/mod*_aria* @zucchini-nlp
291
+ /src/transformers/models/blip/mod*_blip* @zucchini-nlp
292
+ /src/transformers/models/blip_2/mod*_blip_2* @zucchini-nlp
293
+ /src/transformers/models/bridgetower/mod*_bridgetower* @zucchini-nlp
294
+ /src/transformers/models/bros/mod*_bros* @zucchini-nlp
295
+ /src/transformers/models/chameleon/mod*_chameleon* @zucchini-nlp
296
+ /src/transformers/models/chinese_clip/mod*_chinese_clip* @zucchini-nlp
297
+ /src/transformers/models/clip/mod*_clip* @zucchini-nlp
298
+ /src/transformers/models/clipseg/mod*_clipseg* @zucchini-nlp
299
+ /src/transformers/models/clvp/mod*_clvp* @zucchini-nlp
300
+ /src/transformers/models/colpali/mod*_colpali* @zucchini-nlp @yonigozlan
301
+ /src/transformers/models/data2vec/mod*_data2vec* @zucchini-nlp
302
+ /src/transformers/models/deplot/mod*_deplot* @zucchini-nlp
303
+ /src/transformers/models/donut/mod*_donut* @zucchini-nlp
304
+ /src/transformers/models/flava/mod*_flava* @zucchini-nlp
305
+ /src/transformers/models/git/mod*_git* @zucchini-nlp
306
+ /src/transformers/models/grounding_dino/mod*_grounding_dino* @yonigozlan
307
+ /src/transformers/models/groupvit/mod*_groupvit* @zucchini-nlp
308
+ /src/transformers/models/idefics/mod*_idefics* @zucchini-nlp
309
+ /src/transformers/models/idefics2/mod*_idefics2* @zucchini-nlp
310
+ /src/transformers/models/idefics3/mod*_idefics3* @zucchini-nlp
311
+ /src/transformers/models/instructblip/mod*_instructblip* @zucchini-nlp
312
+ /src/transformers/models/instructblipvideo/mod*_instructblipvideo* @zucchini-nlp
313
+ /src/transformers/models/kosmos_2/mod*_kosmos_2* @zucchini-nlp
314
+ /src/transformers/models/layoutlm/mod*_layoutlm* @NielsRogge
315
+ /src/transformers/models/layoutlmv2/mod*_layoutlmv2* @NielsRogge
316
+ /src/transformers/models/layoutlmv3/mod*_layoutlmv3* @NielsRogge
317
+ /src/transformers/models/layoutxlm/mod*_layoutxlm* @NielsRogge
318
+ /src/transformers/models/lilt/mod*_lilt* @zucchini-nlp
319
+ /src/transformers/models/llava/mod*_llava* @zucchini-nlp @arthurzucker
320
+ /src/transformers/models/llava_next/mod*_llava_next* @zucchini-nlp
321
+ /src/transformers/models/llava_next_video/mod*_llava_next_video* @zucchini-nlp
322
+ /src/transformers/models/llava_onevision/mod*_llava_onevision* @zucchini-nlp
323
+ /src/transformers/models/lxmert/mod*_lxmert* @zucchini-nlp
324
+ /src/transformers/models/matcha/mod*_matcha* @zucchini-nlp
325
+ /src/transformers/models/mgp_str/mod*_mgp_str* @zucchini-nlp
326
+ /src/transformers/models/mllama/mod*_mllama* @zucchini-nlp
327
+ /src/transformers/models/nougat/mod*_nougat* @NielsRogge
328
+ /src/transformers/models/omdet_turbo/mod*_omdet_turbo* @yonigozlan
329
+ /src/transformers/models/oneformer/mod*_oneformer* @zucchini-nlp
330
+ /src/transformers/models/owlvit/mod*_owlvit* @yonigozlan
331
+ /src/transformers/models/owlv2/mod*_owlv2* @yonigozlan
332
+ /src/transformers/models/paligemma/mod*_paligemma* @zucchini-nlp @molbap
333
+ /src/transformers/models/perceiver/mod*_perceiver* @zucchini-nlp
334
+ /src/transformers/models/pix2struct/mod*_pix2struct* @zucchini-nlp
335
+ /src/transformers/models/pixtral/mod*_pixtral* @zucchini-nlp @ArthurZucker
336
+ /src/transformers/models/qwen2_audio/mod*_qwen2_audio* @zucchini-nlp @ArthurZucker
337
+ /src/transformers/models/qwen2_vl/mod*_qwen2_vl* @zucchini-nlp @ArthurZucker
338
+ /src/transformers/models/sam/mod*_sam* @zucchini-nlp @ArthurZucker
339
+ /src/transformers/models/siglip/mod*_siglip* @zucchini-nlp
340
+ /src/transformers/models/speech_encoder_decoder/mod*_speech_encoder_decoder* @zucchini-nlp
341
+ /src/transformers/models/tapas/mod*_tapas* @NielsRogge
342
+ /src/transformers/models/trocr/mod*_trocr* @zucchini-nlp
343
+ /src/transformers/models/tvlt/mod*_tvlt* @zucchini-nlp
344
+ /src/transformers/models/tvp/mod*_tvp* @zucchini-nlp
345
+ /src/transformers/models/udop/mod*_udop* @zucchini-nlp
346
+ /src/transformers/models/video_llava/mod*_video_llava* @zucchini-nlp
347
+ /src/transformers/models/vilt/mod*_vilt* @zucchini-nlp
348
+ /src/transformers/models/vipllava/mod*_vipllava* @zucchini-nlp
349
+ /src/transformers/models/vision_encoder_decoder/mod*_vision_encoder_decoder* @Rocketknight1
350
+ /src/transformers/models/vision_text_dual_encoder/mod*_vision_text_dual_encoder* @Rocketknight1
351
+ /src/transformers/models/visual_bert/mod*_visual_bert* @zucchini-nlp
352
+ /src/transformers/models/xclip/mod*_xclip* @zucchini-nlp
353
+
354
+ # Reinforcement learning models
355
+ /src/transformers/models/decision_transformer/mod*_decision_transformer* @Rocketknight1
356
+ /src/transformers/models/trajectory_transformer/mod*_trajectory_transformer* @Rocketknight1
357
+
358
+ # Time series models
359
+ /src/transformers/models/autoformer/mod*_autoformer* @Rocketknight1
360
+ /src/transformers/models/informer/mod*_informer* @Rocketknight1
361
+ /src/transformers/models/patchtsmixer/mod*_patchtsmixer* @Rocketknight1
362
+ /src/transformers/models/patchtst/mod*_patchtst* @Rocketknight1
363
+ /src/transformers/models/time_series_transformer/mod*_time_series_transformer* @Rocketknight1
364
+
365
+ # Graph models
366
+ /src/transformers/models/graphormer/mod*_graphormer* @clefourrier
367
+
368
+ # Finally, files with no owners that shouldn't generate pings, usually automatically generated and checked in the CI
369
+ utils/dummy*
.github/workflows/TROUBLESHOOT.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Troubleshooting
2
+
3
+ This is a document explaining how to deal with various issues on github-actions self-hosted CI. The entries may include actual solutions or pointers to Issues that cover those.
4
+
5
+ ## GitHub Actions (self-hosted CI)
6
+
7
+ * Deepspeed
8
+
9
+ - if jit build hangs, clear out `rm -rf ~/.cache/torch_extensions/` reference: https://github.com/huggingface/transformers/pull/12723
.github/workflows/add-model-like.yml ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Add model like runner
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - none # put main here when this is fixed
7
+ #pull_request:
8
+ # paths:
9
+ # - "src/**"
10
+ # - "tests/**"
11
+ # - ".github/**"
12
+ # types: [opened, synchronize, reopened]
13
+
14
+ jobs:
15
+ run_tests_templates_like:
16
+ name: "Add new model like template tests"
17
+ runs-on: ubuntu-22.04
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ sudo apt -y update && sudo apt install -y libsndfile1-dev
24
+
25
+ - name: Load cached virtual environment
26
+ uses: actions/cache@v4
27
+ id: cache
28
+ with:
29
+ path: ~/venv/
30
+ key: v4-tests_model_like-${{ hashFiles('setup.py') }}
31
+
32
+ - name: Create virtual environment on cache miss
33
+ if: steps.cache.outputs.cache-hit != 'true'
34
+ run: |
35
+ python -m venv ~/venv && . ~/venv/bin/activate
36
+ pip install --upgrade pip!=21.3
37
+ pip install -e .[dev]
38
+
39
+ - name: Check transformers location
40
+ # make `transformers` available as package (required since we use `-e` flag) and check it's indeed from the repo.
41
+ run: |
42
+ . ~/venv/bin/activate
43
+ python setup.py develop
44
+ transformers_install=$(pip list -e | grep transformers)
45
+ transformers_install_array=($transformers_install)
46
+ transformers_loc=${transformers_install_array[-1]}
47
+ transformers_repo_loc=$(pwd .)
48
+ if [ "$transformers_loc" != "$transformers_repo_loc" ]; then
49
+ echo "transformers is from $transformers_loc but it shoud be from $transformers_repo_loc/src."
50
+ echo "A fix is required. Stop testing."
51
+ exit 1
52
+ fi
53
+
54
+ - name: Create model files
55
+ run: |
56
+ . ~/venv/bin/activate
57
+ transformers add-new-model-like --config_file tests/fixtures/add_distilbert_like_config.json --path_to_repo .
58
+ make style
59
+ make fix-copies
60
+
61
+ - name: Run all PyTorch modeling test
62
+ run: |
63
+ . ~/venv/bin/activate
64
+ python -m pytest -n 2 --dist=loadfile -s --make-reports=tests_new_models tests/bert_new/test_modeling_bert_new.py
65
+
66
+ - name: Run style changes
67
+ run: |
68
+ . ~/venv/bin/activate
69
+ make style && make quality && make repo-consistency
70
+
71
+ - name: Failure short reports
72
+ if: ${{ always() }}
73
+ run: cat reports/tests_new_models/failures_short.txt
74
+
75
+ - name: Test suite reports artifacts
76
+ if: ${{ always() }}
77
+ uses: actions/upload-artifact@v4
78
+ with:
79
+ name: run_all_tests_new_models_test_reports
80
+ path: reports/tests_new_models
.github/workflows/assign-reviewers.yml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Assign PR Reviewers
2
+ on:
3
+ pull_request_target:
4
+ branches:
5
+ - main
6
+ types: [ready_for_review]
7
+
8
+ jobs:
9
+ assign_reviewers:
10
+ permissions:
11
+ pull-requests: write
12
+ runs-on: ubuntu-22.04
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: '3.13'
19
+ - name: Install dependencies
20
+ run: |
21
+ python -m pip install --upgrade pip
22
+ pip install PyGithub
23
+ - name: Run assignment script
24
+ env:
25
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26
+ run: python .github/scripts/assign_reviewers.py
.github/workflows/benchmark.yml ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Self-hosted runner (benchmark)
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ types: [ opened, labeled, reopened, synchronize ]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
11
+ cancel-in-progress: true
12
+
13
+ env:
14
+ HF_HOME: /mnt/cache
15
+ DATASET_ID: hf-benchmarks/transformers
16
+ MODEL_ID: meta-llama/Llama-3.1-8B-Instruct
17
+
18
+ jobs:
19
+ benchmark:
20
+ name: Benchmark
21
+ strategy:
22
+ matrix:
23
+ # group: [aws-g5-4xlarge-cache, aws-p4d-24xlarge-plus] (A100 runner is not enabled)
24
+ group: [aws-g5-4xlarge-cache]
25
+ runs-on:
26
+ group: ${{ matrix.group }}
27
+ if: |
28
+ (github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'run-benchmark') )||
29
+ (github.event_name == 'push' && github.ref == 'refs/heads/main')
30
+ container:
31
+ image: huggingface/transformers-all-latest-gpu
32
+ options: --gpus all --privileged --ipc host
33
+ steps:
34
+ - name: Get repo
35
+ uses: actions/checkout@v5
36
+ with:
37
+ fetch-depth: 1
38
+
39
+ - name: Install benchmark script dependencies
40
+ run: python3 -m pip install -r benchmark_v2/requirements.txt kernels
41
+
42
+ - name: Reinstall transformers in edit mode (remove the one installed during docker image build)
43
+ run: python3 -m pip uninstall -y transformers && python3 -m pip install -e ".[torch]"
44
+
45
+ - name: Run benchmark
46
+ run: |
47
+ git config --global --add safe.directory /__w/transformers/transformers
48
+ if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
49
+ commit_id=$(echo "${{ github.event.pull_request.head.sha }}")
50
+ elif [ "$GITHUB_EVENT_NAME" = "push" ]; then
51
+ commit_id=$GITHUB_SHA
52
+ fi
53
+ commit_msg=$(git show -s --format=%s | cut -c1-70)
54
+ python3 benchmark_v2/run_benchmarks.py -b 32 -s 128 -n 256 --level 2 --branch-name "$BRANCH_NAME" --commit-id "$commit_id" --commit-message "$commit_msg" --model-id "$MODEL_ID" --log-level INFO --push-result-to-dataset "$DATASET_ID"
55
+ env:
56
+ HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
57
+ PUSH_TO_HUB_TOKEN: ${{ secrets.PUSH_TO_HUB_TOKEN }}
58
+ # Enable this to see debug logs
59
+ # HF_HUB_VERBOSITY: debug
60
+ # TRANSFORMERS_VERBOSITY: debug
61
+ BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
.github/workflows/benchmark_v2.yml ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Benchmark v2 Framework
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ env:
7
+ HF_HOME: /mnt/cache
8
+ TRANSFORMERS_IS_CI: yes
9
+ # For gated repositories, we still need to agree to share information on the Hub repo. page in order to get access.
10
+ # This token is created under the bot `hf-transformers-bot`.
11
+ HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
12
+
13
+ jobs:
14
+ benchmark-v2:
15
+ name: Benchmark v2
16
+ runs-on: ${{ inputs.runner }}
17
+ if: |
18
+ (github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'run-benchmark')) ||
19
+ (github.event_name == 'schedule')
20
+ container:
21
+ image: ${{ inputs.container_image }}
22
+ options: ${{ inputs.container_options }}
23
+ steps:
24
+ - name: Get repo
25
+ uses: actions/checkout@v4
26
+ with:
27
+ ref: ${{ inputs.commit_sha || github.sha }}
28
+
29
+ - name: Install benchmark dependencies
30
+ run: |
31
+ python3 -m pip install -r benchmark_v2/requirements.txt
32
+
33
+ - name: Reinstall transformers in edit mode
34
+ run: |
35
+ python3 -m pip uninstall -y transformers
36
+ python3 -m pip install -e ".[torch]"
37
+
38
+ - name: Show installed libraries and their versions
39
+ run: |
40
+ python3 -m pip list
41
+ python3 -c "import torch; print(f'PyTorch version: {torch.__version__}')"
42
+ python3 -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}')"
43
+ python3 -c "import torch; print(f'CUDA device count: {torch.cuda.device_count()}')" || true
44
+ nvidia-smi || true
45
+
46
+ - name: Run benchmark v2
47
+ working-directory: benchmark_v2
48
+ run: |
49
+ echo "Running benchmarks"
50
+ python3 run_benchmarks.py \
51
+ --commit-id '${{ inputs.commit_sha || github.sha }}' \
52
+ --run-id '${{ inputs.run_id }}' \
53
+ --push-to-hub '${{ inputs.benchmark_repo_id}}' \
54
+ --token '${{ secrets.TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN }}' \
55
+ --log-level INFO
56
+ env:
57
+ HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
.github/workflows/benchmark_v2_a10_caller.yml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Benchmark v2 Scheduled Runner - A10 Single-GPU
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ benchmark-v2-default:
8
+ name: Benchmark v2 - Default Models
9
+ uses: ./.github/workflows/benchmark_v2.yml
10
+ with:
11
+ runner: aws-g5-4xlarge-cache-use1-public-80
12
+ container_image: huggingface/transformers-all-latest-gpu
13
+ container_options: --gpus all --privileged --ipc host --shm-size "16gb"
14
+ commit_sha: ${{ github.sha }}
15
+ run_id: ${{ github.run_id }}
16
+ benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks
17
+ secrets: inherit
.github/workflows/benchmark_v2_mi325_caller.yml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Benchmark v2 Scheduled Runner - MI325 Single-GPU
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ benchmark-v2-default:
8
+ name: Benchmark v2 - Default Models
9
+ uses: ./.github/workflows/benchmark_v2.yml
10
+ with:
11
+ runner: amd-mi325-ci-1gpu
12
+ container_image: huggingface/transformers-pytorch-amd-gpu
13
+ container_options: --device /dev/kfd --device /dev/dri --env ROCR_VISIBLE_DEVICES --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache
14
+ commit_sha: ${{ github.sha }}
15
+ run_id: ${{ github.run_id }}
16
+ benchmark_repo_id: hf-internal-testing/transformers-daily-benchmarks
17
+ secrets: inherit
.github/workflows/build-ci-docker-images.yml ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build pr ci-docker
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - push-ci-image # for now let's only build on this branch
7
+ repository_dispatch:
8
+ workflow_call:
9
+ inputs:
10
+ image_postfix:
11
+ required: true
12
+ type: string
13
+ schedule:
14
+ - cron: "6 0 * * *"
15
+
16
+
17
+ concurrency:
18
+ group: ${{ github.workflow }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ build:
23
+ runs-on: ubuntu-22.04
24
+
25
+ if: ${{ contains(github.event.head_commit.message, '[build-ci-image]') || contains(github.event.head_commit.message, '[push-ci-image]') && '!cancelled()' || github.event_name == 'schedule' }}
26
+
27
+ strategy:
28
+ matrix:
29
+ file: ["quality", "consistency", "custom-tokenizers", "torch-light", "exotic-models", "examples-torch"]
30
+ continue-on-error: true
31
+
32
+ steps:
33
+ -
34
+ name: Set tag
35
+ run: |
36
+ if ${{contains(github.event.head_commit.message, '[build-ci-image]')}}; then
37
+ echo "TAG=huggingface/transformers-${{ matrix.file }}:dev" >> "$GITHUB_ENV"
38
+ echo "setting it to DEV!"
39
+ else
40
+ echo "TAG=huggingface/transformers-${{ matrix.file }}" >> "$GITHUB_ENV"
41
+
42
+ fi
43
+ -
44
+ name: Set up Docker Buildx
45
+ uses: docker/setup-buildx-action@v3
46
+ -
47
+ name: Check out code
48
+ uses: actions/checkout@v4
49
+ -
50
+ name: Login to DockerHub
51
+ uses: docker/login-action@v3
52
+ with:
53
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
54
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
55
+ -
56
+ name: Build ${{ matrix.file }}.dockerfile
57
+ uses: docker/build-push-action@v5
58
+ with:
59
+ context: ./docker
60
+ build-args: |
61
+ REF=${{ github.sha }}
62
+ file: "./docker/${{ matrix.file }}.dockerfile"
63
+ push: ${{ contains(github.event.head_commit.message, 'ci-image]') || github.event_name == 'schedule' }}
64
+ tags: ${{ env.TAG }}
65
+
66
+ notify:
67
+ runs-on: ubuntu-22.04
68
+ if: ${{ contains(github.event.head_commit.message, '[build-ci-image]') || contains(github.event.head_commit.message, '[push-ci-image]') && '!cancelled()' || github.event_name == 'schedule' }}
69
+ steps:
70
+ - name: Post to Slack
71
+ if: ${{ contains(github.event.head_commit.message, '[push-ci-image]') && github.event_name != 'schedule' }}
72
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
73
+ with:
74
+ slack_channel: "#transformers-ci-circleci-images"
75
+ title: 🤗 New docker images for CircleCI are pushed.
76
+ status: ${{ job.status }}
77
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
.github/workflows/build-docker-images.yml ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build docker images (scheduled)
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - build_ci_docker_image*
7
+ repository_dispatch:
8
+ workflow_dispatch:
9
+ workflow_call:
10
+ inputs:
11
+ image_postfix:
12
+ required: true
13
+ type: string
14
+ schedule:
15
+ - cron: "17 0 * * *"
16
+
17
+ concurrency:
18
+ group: docker-images-builds
19
+ cancel-in-progress: false
20
+
21
+ jobs:
22
+ latest-docker:
23
+ name: "Latest PyTorch [dev]"
24
+ runs-on:
25
+ group: aws-general-8-plus
26
+ steps:
27
+ -
28
+ name: Set up Docker Buildx
29
+ uses: docker/setup-buildx-action@v3
30
+ -
31
+ name: Check out code
32
+ uses: actions/checkout@v4
33
+ -
34
+ name: Login to DockerHub
35
+ uses: docker/login-action@v3
36
+ with:
37
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
38
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
39
+ -
40
+ name: Build and push
41
+ uses: docker/build-push-action@v5
42
+ with:
43
+ context: ./docker/transformers-all-latest-gpu
44
+ build-args: |
45
+ REF=main
46
+ push: true
47
+ tags: huggingface/transformers-all-latest-gpu${{ inputs.image_postfix }}
48
+
49
+ - name: Post to Slack
50
+ if: always()
51
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
52
+ with:
53
+ slack_channel: ${{ secrets.CI_SLACK_CHANNEL_DOCKER }}
54
+ title: 🤗 Results of the transformers-all-latest-gpu docker build
55
+ status: ${{ job.status }}
56
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
57
+
58
+ flash-attn-ci-image:
59
+ name: "PyTorch with Flash Attn [dev]"
60
+ runs-on:
61
+ group: aws-general-8-plus
62
+ steps:
63
+ -
64
+ name: Set up Docker Buildx
65
+ uses: docker/setup-buildx-action@v3
66
+ -
67
+ name: Check out code
68
+ uses: actions/checkout@v4
69
+ -
70
+ name: Login to DockerHub
71
+ uses: docker/login-action@v3
72
+ with:
73
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
74
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
75
+ -
76
+ name: Build and push
77
+ uses: docker/build-push-action@v5
78
+ with:
79
+ context: ./docker/transformers-all-latest-gpu
80
+ build-args: |
81
+ REF=main
82
+ PYTORCH=2.8.0
83
+ TORCHCODEC=0.7.0
84
+ FLASH_ATTN=yes
85
+ push: true
86
+ tags: huggingface/transformers-all-latest-gpu${{ inputs.image_postfix }}:flash-attn
87
+
88
+ - name: Post to Slack
89
+ if: always()
90
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
91
+ with:
92
+ slack_channel: ${{ secrets.CI_SLACK_CHANNEL_DOCKER }}
93
+ title: 🤗 Results of the transformers-all-latest-gpu docker build
94
+ status: ${{ job.status }}
95
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
96
+
97
+ latest-torch-deepspeed-docker:
98
+ name: "Latest PyTorch + DeepSpeed"
99
+ runs-on:
100
+ group: aws-general-8-plus
101
+ steps:
102
+ -
103
+ name: Set up Docker Buildx
104
+ uses: docker/setup-buildx-action@v3
105
+ -
106
+ name: Check out code
107
+ uses: actions/checkout@v4
108
+ -
109
+ name: Login to DockerHub
110
+ uses: docker/login-action@v3
111
+ with:
112
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
113
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
114
+ -
115
+ name: Build and push
116
+ uses: docker/build-push-action@v5
117
+ with:
118
+ context: ./docker/transformers-pytorch-deepspeed-latest-gpu
119
+ build-args: |
120
+ REF=main
121
+ push: true
122
+ tags: huggingface/transformers-pytorch-deepspeed-latest-gpu${{ inputs.image_postfix }}
123
+
124
+ - name: Post to Slack
125
+ if: always()
126
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
127
+ with:
128
+ slack_channel: ${{ secrets.CI_SLACK_CHANNEL_DOCKER}}
129
+ title: 🤗 Results of the transformers-pytorch-deepspeed-latest-gpu docker build
130
+ status: ${{ job.status }}
131
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
132
+
133
+ doc-builder:
134
+ name: "Doc builder"
135
+ runs-on:
136
+ group: aws-general-8-plus
137
+ steps:
138
+ -
139
+ name: Set up Docker Buildx
140
+ uses: docker/setup-buildx-action@v3
141
+ -
142
+ name: Check out code
143
+ uses: actions/checkout@v4
144
+ -
145
+ name: Login to DockerHub
146
+ uses: docker/login-action@v3
147
+ with:
148
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
149
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
150
+ -
151
+ name: Build and push
152
+ uses: docker/build-push-action@v5
153
+ with:
154
+ context: ./docker/transformers-doc-builder
155
+ push: true
156
+ tags: huggingface/transformers-doc-builder
157
+
158
+ - name: Post to Slack
159
+ if: always()
160
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
161
+ with:
162
+ slack_channel: ${{ secrets.CI_SLACK_CHANNEL_DOCKER }}
163
+ title: 🤗 Results of the huggingface/transformers-doc-builder docker build
164
+ status: ${{ job.status }}
165
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
166
+
167
+ latest-pytorch-amd:
168
+ name: "Latest PyTorch (AMD) [dev]"
169
+ runs-on:
170
+ group: aws-highcpu-32-priv
171
+ steps:
172
+ -
173
+ name: Set up Docker Buildx
174
+ uses: docker/setup-buildx-action@v3
175
+ -
176
+ name: Check out code
177
+ uses: actions/checkout@v4
178
+ -
179
+ name: Login to DockerHub
180
+ uses: docker/login-action@v3
181
+ with:
182
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
183
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
184
+ -
185
+ name: Build and push
186
+ uses: docker/build-push-action@v5
187
+ with:
188
+ context: ./docker/transformers-pytorch-amd-gpu
189
+ build-args: |
190
+ REF=main
191
+ push: true
192
+ tags: huggingface/transformers-pytorch-amd-gpu${{ inputs.image_postfix }}
193
+
194
+ - name: Post to Slack
195
+ if: always()
196
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
197
+ with:
198
+ slack_channel: ${{ secrets.CI_SLACK_CHANNEL_DOCKER }}
199
+ title: 🤗 Results of the huggingface/transformers-pytorch-amd-gpu build
200
+ status: ${{ job.status }}
201
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
202
+
203
+ cache-latest-pytorch-amd:
204
+ name: "Cache Latest Pytorch (AMD) Image"
205
+ needs: latest-pytorch-amd
206
+ runs-on:
207
+ group: amd-mi325-1gpu
208
+ steps:
209
+ -
210
+ name: Login to DockerHub
211
+ uses: docker/login-action@v3
212
+ with:
213
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
214
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
215
+
216
+ -
217
+ name: Pull and save docker image to cache
218
+ run: |
219
+ image="huggingface/transformers-pytorch-amd-gpu"
220
+ final_path="/mnt/image-cache/transformers-pytorch-amd-gpu.tar"
221
+ tmp_path="${final_path}.tmp"
222
+
223
+ echo "Pulling image: ${image}"
224
+ docker pull "${image}"
225
+
226
+ echo "Saving to temp file: ${tmp_path}"
227
+ docker save "${image}" -o "${tmp_path}"
228
+
229
+ echo "Moving to final path: ${final_path}"
230
+ mv -f "${tmp_path}" "${final_path}"
231
+
232
+ echo "Cache populated successfully at ${final_path}"
233
+
234
+ latest-pytorch-deepspeed-amd:
235
+ name: "PyTorch + DeepSpeed (AMD) [dev]"
236
+ runs-on:
237
+ group: aws-general-8-plus
238
+ steps:
239
+ -
240
+ name: Set up Docker Buildx
241
+ uses: docker/setup-buildx-action@v3
242
+ -
243
+ name: Check out code
244
+ uses: actions/checkout@v4
245
+ -
246
+ name: Login to DockerHub
247
+ uses: docker/login-action@v3
248
+ with:
249
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
250
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
251
+ -
252
+ name: Build and push
253
+ uses: docker/build-push-action@v5
254
+ with:
255
+ context: ./docker/transformers-pytorch-deepspeed-amd-gpu
256
+ build-args: |
257
+ REF=main
258
+ push: true
259
+ tags: huggingface/transformers-pytorch-deepspeed-amd-gpu${{ inputs.image_postfix }}
260
+
261
+ - name: Post to Slack
262
+ if: always()
263
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
264
+ with:
265
+ slack_channel: ${{ secrets.CI_SLACK_CHANNEL_DOCKER }}
266
+ title: 🤗 Results of the transformers-pytorch-deepspeed-amd-gpu build
267
+ status: ${{ job.status }}
268
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
269
+
270
+ latest-quantization-torch-docker:
271
+ name: "Latest Pytorch + Quantization [dev]"
272
+ runs-on:
273
+ group: aws-general-8-plus
274
+ steps:
275
+ -
276
+ name: Set up Docker Buildx
277
+ uses: docker/setup-buildx-action@v3
278
+ -
279
+ name: Check out code
280
+ uses: actions/checkout@v4
281
+ -
282
+ name: Login to DockerHub
283
+ uses: docker/login-action@v3
284
+ with:
285
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
286
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
287
+ -
288
+ name: Build and push
289
+ uses: docker/build-push-action@v5
290
+ with:
291
+ context: ./docker/transformers-quantization-latest-gpu
292
+ build-args: |
293
+ REF=main
294
+ push: true
295
+ tags: huggingface/transformers-quantization-latest-gpu${{ inputs.image_postfix }}
296
+
297
+ - name: Post to Slack
298
+ if: always()
299
+ uses: huggingface/hf-workflows/.github/actions/post-slack@main
300
+ with:
301
+ slack_channel: ${{ secrets.CI_SLACK_CHANNEL_DOCKER }}
302
+ title: 🤗 Results of the transformers-quantization-latest-gpu build
303
+ status: ${{ job.status }}
304
+ slack_token: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
.github/workflows/build-nightly-ci-docker-images.yml ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build docker images (Nightly CI)
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ job:
7
+ required: true
8
+ type: string
9
+ push:
10
+ branches:
11
+ - build_nightly_ci_docker_image*
12
+
13
+ concurrency:
14
+ group: docker-images-builds
15
+ cancel-in-progress: false
16
+
17
+ jobs:
18
+ latest-with-torch-nightly-docker:
19
+ name: "Nightly PyTorch"
20
+ if: inputs.job == 'latest-with-torch-nightly-docker' || inputs.job == ''
21
+ runs-on:
22
+ group: aws-general-8-plus
23
+ steps:
24
+ -
25
+ name: Set up Docker Buildx
26
+ uses: docker/setup-buildx-action@v2
27
+ -
28
+ name: Check out code
29
+ uses: actions/checkout@v4
30
+ -
31
+ name: Login to DockerHub
32
+ uses: docker/login-action@v2
33
+ with:
34
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
35
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
36
+ -
37
+ name: Build and push
38
+ uses: docker/build-push-action@v3
39
+ with:
40
+ context: ./docker/transformers-all-latest-gpu
41
+ build-args: |
42
+ REF=main
43
+ PYTORCH=pre
44
+ push: true
45
+ tags: huggingface/transformers-all-latest-torch-nightly-gpu
46
+
47
+ nightly-torch-deepspeed-docker:
48
+ name: "Nightly PyTorch + DeepSpeed"
49
+ if: inputs.job == 'nightly-torch-deepspeed-docker' || inputs.job == ''
50
+ runs-on:
51
+ group: aws-g4dn-2xlarge-cache
52
+ steps:
53
+ -
54
+ name: Set up Docker Buildx
55
+ uses: docker/setup-buildx-action@v2
56
+ -
57
+ name: Check out code
58
+ uses: actions/checkout@v4
59
+ -
60
+ name: Login to DockerHub
61
+ uses: docker/login-action@v2
62
+ with:
63
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
64
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
65
+ -
66
+ name: Build and push
67
+ uses: docker/build-push-action@v3
68
+ with:
69
+ context: ./docker/transformers-pytorch-deepspeed-nightly-gpu
70
+ build-args: |
71
+ REF=main
72
+ push: true
73
+ tags: huggingface/transformers-pytorch-deepspeed-nightly-gpu
.github/workflows/build-past-ci-docker-images.yml ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build docker images (Past CI)
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - build_past_ci_docker_image*
7
+
8
+ concurrency:
9
+ group: docker-images-builds
10
+ cancel-in-progress: false
11
+
12
+ jobs:
13
+ past-pytorch-docker:
14
+ name: "Past PyTorch Docker"
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ version: ["1.13", "1.12", "1.11"]
19
+ runs-on:
20
+ group: aws-general-8-plus
21
+ steps:
22
+ -
23
+ name: Set up Docker Buildx
24
+ uses: docker/setup-buildx-action@v2
25
+ -
26
+ name: Check out code
27
+ uses: actions/checkout@v4
28
+ -
29
+ id: get-base-image
30
+ name: Get Base Image
31
+ env:
32
+ framework_version: ${{ matrix.version }}
33
+ run: |
34
+ echo "base_image=$(python3 -c 'import os; from utils.past_ci_versions import past_versions_testing; base_image = past_versions_testing["pytorch"][os.environ["framework_version"]]["base_image"]; print(base_image)')" >> $GITHUB_OUTPUT
35
+ -
36
+ name: Print Base Image
37
+ run: |
38
+ echo ${{ steps.get-base-image.outputs.base_image }}
39
+ -
40
+ name: Login to DockerHub
41
+ uses: docker/login-action@v2
42
+ with:
43
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
44
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
45
+ -
46
+ name: Build and push
47
+ uses: docker/build-push-action@v3
48
+ with:
49
+ context: ./docker/transformers-past-gpu
50
+ build-args: |
51
+ REF=main
52
+ BASE_DOCKER_IMAGE=${{ steps.get-base-image.outputs.base_image }}
53
+ FRAMEWORK=pytorch
54
+ VERSION=${{ matrix.version }}
55
+ push: true
56
+ tags: huggingface/transformers-pytorch-past-${{ matrix.version }}-gpu
57
+
58
+ past-tensorflow-docker:
59
+ name: "Past TensorFlow Docker"
60
+ strategy:
61
+ fail-fast: false
62
+ matrix:
63
+ version: ["2.11", "2.10", "2.9", "2.8", "2.7", "2.6", "2.5"]
64
+ runs-on:
65
+ group: aws-general-8-plus
66
+ steps:
67
+ -
68
+ name: Set up Docker Buildx
69
+ uses: docker/setup-buildx-action@v2
70
+ -
71
+ name: Check out code
72
+ uses: actions/checkout@v4
73
+ -
74
+ id: get-base-image
75
+ name: Get Base Image
76
+ env:
77
+ framework_version: ${{ matrix.version }}
78
+ run: |
79
+ echo "base_image=$(python3 -c 'import os; from utils.past_ci_versions import past_versions_testing; base_image = past_versions_testing["tensorflow"][os.environ["framework_version"]]["base_image"]; print(base_image)')" >> $GITHUB_OUTPUT
80
+ -
81
+ name: Print Base Image
82
+ run: |
83
+ echo ${{ steps.get-base-image.outputs.base_image }}
84
+ -
85
+ name: Login to DockerHub
86
+ uses: docker/login-action@v2
87
+ with:
88
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
89
+ password: ${{ secrets.DOCKERHUB_PASSWORD }}
90
+ -
91
+ name: Build and push
92
+ uses: docker/build-push-action@v3
93
+ with:
94
+ context: ./docker/transformers-past-gpu
95
+ build-args: |
96
+ REF=main
97
+ BASE_DOCKER_IMAGE=${{ steps.get-base-image.outputs.base_image }}
98
+ FRAMEWORK=tensorflow
99
+ VERSION=${{ matrix.version }}
100
+ push: true
101
+ tags: huggingface/transformers-tensorflow-past-${{ matrix.version }}-gpu
.github/workflows/build_documentation.yml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build documentation
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - main
8
+ - doc-builder*
9
+ - v*-release
10
+ - use_templates
11
+
12
+ jobs:
13
+ build:
14
+ uses: huggingface/doc-builder/.github/workflows/build_main_documentation.yml@main
15
+ with:
16
+ commit_sha: ${{ github.sha }}
17
+ package: transformers
18
+ notebook_folder: transformers_doc
19
+ languages: en
20
+ custom_container: huggingface/transformers-doc-builder
21
+ secrets:
22
+ token: ${{ secrets.HUGGINGFACE_PUSH }}
23
+ hf_token: ${{ secrets.HF_DOC_BUILD_PUSH }}
24
+
25
+ build_other_lang:
26
+ uses: huggingface/doc-builder/.github/workflows/build_main_documentation.yml@main
27
+ with:
28
+ commit_sha: ${{ github.sha }}
29
+ package: transformers
30
+ notebook_folder: transformers_doc
31
+ languages: ar de es fr hi it ja ko pt zh
32
+ custom_container: huggingface/transformers-doc-builder
33
+ secrets:
34
+ token: ${{ secrets.HUGGINGFACE_PUSH }}
35
+ hf_token: ${{ secrets.HF_DOC_BUILD_PUSH }}
.github/workflows/build_pr_documentation.yml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build PR Documentation
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ concurrency:
7
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
8
+ cancel-in-progress: true
9
+
10
+ jobs:
11
+ build:
12
+ uses: huggingface/doc-builder/.github/workflows/build_pr_documentation.yml@main
13
+ with:
14
+ commit_sha: ${{ github.event.pull_request.head.sha }}
15
+ pr_number: ${{ github.event.number }}
16
+ package: transformers
17
+ languages: en
.github/workflows/check-workflow-permissions.yml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: Check Permissions Advisor
3
+
4
+ on:
5
+ workflow_dispatch:
6
+ inputs:
7
+ workflow_name:
8
+ description: 'Workflow file name'
9
+ type: string
10
+ run_count:
11
+ description: 'Number of runs to analyze'
12
+ type: string
13
+ default: "10"
14
+
15
+ jobs:
16
+ advisor:
17
+ uses: huggingface/security-workflows/.github/workflows/permissions-advisor-reusable.yml@main
18
+ permissions:
19
+ actions: read
20
+ contents: read
21
+ with:
22
+ workflow_name: ${{ inputs.workflow_name }}
23
+ run_count: ${{ fromJSON(inputs.run_count) }}
.github/workflows/check_failed_tests.yml ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Process failed tests
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ docker:
7
+ required: true
8
+ type: string
9
+ job:
10
+ required: true
11
+ type: string
12
+ slack_report_channel:
13
+ required: true
14
+ type: string
15
+ ci_event:
16
+ required: true
17
+ type: string
18
+ report_repo_id:
19
+ required: true
20
+ type: string
21
+ commit_sha:
22
+ required: false
23
+ type: string
24
+ pr_number:
25
+ required: false
26
+ type: string
27
+ outputs:
28
+ report:
29
+ description: "Content of the report of new failures"
30
+ value: ${{ jobs.process_new_failures_with_commit_info.outputs.report }}
31
+
32
+ env:
33
+ HF_HOME: /mnt/cache
34
+ TRANSFORMERS_IS_CI: yes
35
+ OMP_NUM_THREADS: 8
36
+ MKL_NUM_THREADS: 8
37
+ RUN_SLOW: yes
38
+ # For gated repositories, we still need to agree to share information on the Hub repo. page in order to get access.
39
+ # This token is created under the bot `hf-transformers-bot`.
40
+ HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
41
+ TF_FORCE_GPU_ALLOW_GROWTH: true
42
+ CUDA_VISIBLE_DEVICES: 0,1
43
+
44
+
45
+ jobs:
46
+ check_new_failures:
47
+ name: "Find commits for new failing tests"
48
+ strategy:
49
+ matrix:
50
+ run_idx: [1]
51
+ runs-on:
52
+ group: aws-g5-4xlarge-cache
53
+ outputs:
54
+ process: ${{ steps.check_file.outputs.process }}
55
+ container:
56
+ image: ${{ inputs.docker }}
57
+ options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/
58
+ steps:
59
+ - uses: actions/download-artifact@v4
60
+ with:
61
+ name: ci_results_${{ inputs.job }}
62
+ path: /transformers/ci_results_${{ inputs.job }}
63
+
64
+ - name: Check file
65
+ id: check_file
66
+ working-directory: /transformers
67
+ env:
68
+ job: ${{ inputs.job }}
69
+ run: |
70
+ if [ -f "ci_results_${job}/new_failures.json" ]; then
71
+ echo "\`ci_results_${job}/new_failures.json\` exists, continue ..."
72
+ echo "process=true" >> $GITHUB_ENV
73
+ echo "process=true" >> $GITHUB_OUTPUT
74
+ else
75
+ echo "\`ci_results_${job}/new_failures.json\` doesn't exist, abort."
76
+ echo "process=false" >> $GITHUB_ENV
77
+ echo "process=false" >> $GITHUB_OUTPUT
78
+ fi
79
+
80
+ - uses: actions/download-artifact@v4
81
+ if: ${{ env.process == 'true' }}
82
+ with:
83
+ pattern: setup_values*
84
+ path: setup_values
85
+ merge-multiple: true
86
+
87
+ - name: Prepare some setup values
88
+ if: ${{ env.process == 'true' }}
89
+ run: |
90
+ if [ -f setup_values/prev_workflow_run_id.txt ]; then
91
+ echo "PREV_WORKFLOW_RUN_ID=$(cat setup_values/prev_workflow_run_id.txt)" >> $GITHUB_ENV
92
+ else
93
+ echo "PREV_WORKFLOW_RUN_ID=" >> $GITHUB_ENV
94
+ fi
95
+
96
+ - name: Update clone
97
+ working-directory: /transformers
98
+ if: ${{ env.process == 'true' }}
99
+ env:
100
+ commit_sha: ${{ inputs.commit_sha || github.sha }}
101
+ run: |
102
+ git fetch origin "$commit_sha" && git checkout "$commit_sha"
103
+
104
+ - name: Get `START_SHA`
105
+ working-directory: /transformers/utils
106
+ if: ${{ env.process == 'true' }}
107
+ env:
108
+ commit_sha: ${{ inputs.commit_sha || github.sha }}
109
+ run: |
110
+ echo "START_SHA=$commit_sha" >> $GITHUB_ENV
111
+
112
+ # This is used if the CI is triggered from a pull request `self-comment-ci.yml` (after security check is verified)
113
+ - name: Extract the base commit on `main` (of the merge commit created by Github) if it is a PR
114
+ id: pr_info
115
+ if: ${{ env.process == 'true' && inputs.pr_number != '' }}
116
+ uses: actions/github-script@v6
117
+ with:
118
+ script: |
119
+ const { data: pr } = await github.rest.pulls.get({
120
+ owner: context.repo.owner,
121
+ repo: context.repo.repo,
122
+ pull_number: ${{ inputs.pr_number }}
123
+ });
124
+
125
+ const { data: merge_commit } = await github.rest.repos.getCommit({
126
+ owner: pr.base.repo.owner.login,
127
+ repo: pr.base.repo.name,
128
+ ref: '${{ inputs.commit_sha }}',
129
+ });
130
+
131
+ core.setOutput('merge_commit_base_sha', merge_commit.parents[0].sha);
132
+
133
+ # Usually, `END_SHA` should be the commit of the last previous workflow run of the **SAME** (scheduled) workflow.
134
+ # (This is why we don't need to specify `workflow_id` which would be fetched automatically in the python script.)
135
+ - name: Get `END_SHA` from previous CI runs of the same workflow
136
+ working-directory: /transformers/utils
137
+ if: ${{ env.process == 'true' && inputs.pr_number == '' }}
138
+ env:
139
+ ACCESS_TOKEN: ${{ secrets.ACCESS_REPO_INFO_TOKEN }}
140
+ run: |
141
+ echo "END_SHA=$(TOKEN="$ACCESS_TOKEN" python3 -c 'import os; from get_previous_daily_ci import get_last_daily_ci_run_commit; commit=get_last_daily_ci_run_commit(token=os.environ["TOKEN"], workflow_run_id=os.environ["PREV_WORKFLOW_RUN_ID"]); print(commit)')" >> $GITHUB_ENV
142
+
143
+ # However, for workflow runs triggered by `issue_comment` (for pull requests), we want to check against the
144
+ # parent commit (on `main`) of the `merge_commit` (dynamically created by GitHub). In this case, the goal is to
145
+ # see if a reported failing test is actually ONLY failing on the `merge_commit`.
146
+ - name: Set `END_SHA`
147
+ if: ${{ env.process == 'true' && inputs.pr_number != '' }}
148
+ env:
149
+ merge_commit_base_sha: ${{ steps.pr_info.outputs.merge_commit_base_sha }}
150
+ run: |
151
+ echo "END_SHA=$merge_commit_base_sha" >> $GITHUB_ENV
152
+
153
+ - name: Reinstall transformers in edit mode (remove the one installed during docker image build)
154
+ working-directory: /transformers
155
+ if: ${{ env.process == 'true' }}
156
+ run: python3 -m pip uninstall -y transformers && python3 -m pip install -e .
157
+
158
+ - name: NVIDIA-SMI
159
+ if: ${{ env.process == 'true' }}
160
+ run: |
161
+ nvidia-smi
162
+
163
+ - name: Environment
164
+ working-directory: /transformers
165
+ if: ${{ env.process == 'true' }}
166
+ run: |
167
+ python3 utils/print_env.py
168
+
169
+ - name: Install pytest-flakefinder
170
+ if: ${{ env.process == 'true' }}
171
+ run: python3 -m pip install pytest-flakefinder
172
+
173
+ - name: Show installed libraries and their versions
174
+ working-directory: /transformers
175
+ if: ${{ env.process == 'true' }}
176
+ run: pip freeze
177
+
178
+ - name: Check failed tests
179
+ working-directory: /transformers
180
+ if: ${{ env.process == 'true' }}
181
+ env:
182
+ job: ${{ inputs.job }}
183
+ run_idx: ${{ matrix.run_idx }}
184
+ run: python3 utils/check_bad_commit.py --start_commit "$START_SHA" --end_commit "$END_SHA" --file "ci_results_${job}/new_failures.json" --output_file "new_failures_with_bad_commit_${job}_${run_idx}.json"
185
+
186
+ - name: Show results
187
+ working-directory: /transformers
188
+ if: ${{ env.process == 'true' }}
189
+ env:
190
+ job: ${{ inputs.job }}
191
+ run_idx: ${{ matrix.run_idx }}
192
+ run: |
193
+ ls -l "new_failures_with_bad_commit_${job}_${run_idx}.json"
194
+ cat "new_failures_with_bad_commit_${job}_${run_idx}.json"
195
+
196
+ - name: Upload artifacts
197
+ uses: actions/upload-artifact@v4
198
+ with:
199
+ name: new_failures_with_bad_commit_${{ inputs.job }}_${{ matrix.run_idx }}
200
+ path: /transformers/new_failures_with_bad_commit_${{ inputs.job }}_${{ matrix.run_idx }}.json
201
+
202
+ process_new_failures_with_commit_info:
203
+ name: "process bad commit reports"
204
+ needs: check_new_failures
205
+ if: needs.check_new_failures.outputs.process == 'true'
206
+ runs-on:
207
+ group: aws-g5-4xlarge-cache
208
+ outputs:
209
+ report: ${{ steps.set_output.outputs.report }}
210
+ container:
211
+ image: ${{ inputs.docker }}
212
+ options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/
213
+ steps:
214
+ - uses: actions/download-artifact@v4
215
+ with:
216
+ name: ci_results_${{ inputs.job }}
217
+ path: /transformers/ci_results_${{ inputs.job }}
218
+
219
+ - uses: actions/download-artifact@v4
220
+ with:
221
+ pattern: new_failures_with_bad_commit_${{ inputs.job }}*
222
+ path: /transformers/new_failures_with_bad_commit_${{ inputs.job }}
223
+ merge-multiple: true
224
+
225
+ - name: Check files
226
+ working-directory: /transformers
227
+ env:
228
+ job: ${{ inputs.job }}
229
+ run: |
230
+ ls -la /transformers
231
+ ls -la "/transformers/new_failures_with_bad_commit_${job}"
232
+
233
+ # Currently, we only run with a single runner by using `run_idx: [1]`. We might try to run with multiple runners
234
+ # to further reduce the false positive caused by flaky tests, which requires further processing to merge reports.
235
+ - name: Merge files
236
+ shell: bash
237
+ working-directory: /transformers
238
+ env:
239
+ job: ${{ inputs.job }}
240
+ run: |
241
+ cp "/transformers/new_failures_with_bad_commit_${job}/new_failures_with_bad_commit_${job}_1.json" new_failures_with_bad_commit.json
242
+
243
+ - name: Update clone
244
+ working-directory: /transformers
245
+ env:
246
+ commit_sha: ${{ inputs.commit_sha || github.sha }}
247
+ run: |
248
+ git fetch origin "$commit_sha" && git checkout "$commit_sha"
249
+
250
+ - name: Process report
251
+ shell: bash
252
+ working-directory: /transformers
253
+ env:
254
+ ACCESS_REPO_INFO_TOKEN: ${{ secrets.ACCESS_REPO_INFO_TOKEN }}
255
+ TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN: ${{ secrets.TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN }}
256
+ JOB_NAME: ${{ inputs.job }}
257
+ REPORT_REPO_ID: ${{ inputs.report_repo_id }}
258
+ run: |
259
+ {
260
+ echo 'REPORT_TEXT<<EOF'
261
+ python3 utils/process_bad_commit_report.py
262
+ echo EOF
263
+ } >> "$GITHUB_ENV"
264
+
265
+ # The output is useful if a caller needs more processing, for example, we have a chain
266
+ # self-comment-ci.yml -> self-scheduled.yml -> this one (check_failed_tests.yml),
267
+ # and `self-comment-ci.yml` needs further processing before sending a GitHub comment to the pull request page.
268
+ - name: Show results & Set outputs
269
+ id: set_output
270
+ working-directory: /transformers
271
+ run: |
272
+ ls -l new_failures_with_bad_commit.json
273
+ cat new_failures_with_bad_commit.json
274
+
275
+ {
276
+ echo 'report<<EOF'
277
+ cat new_failures_with_bad_commit.json
278
+ echo '' # Force a newline
279
+ echo EOF
280
+ } >> "$GITHUB_OUTPUT"
281
+
282
+ - name: Upload artifacts
283
+ uses: actions/upload-artifact@v4
284
+ with:
285
+ name: new_failures_with_bad_commit_${{ inputs.job }}
286
+ path: /transformers/new_failures_with_bad_commit.json
287
+
288
+ - name: Prepare Slack report title
289
+ working-directory: /transformers
290
+ env:
291
+ ci_event: ${{ inputs.ci_event }}
292
+ job: ${{ inputs.job }}
293
+ run: |
294
+ pip install slack_sdk
295
+ echo "title=$(python3 -c 'import sys; import os; sys.path.append("utils"); from utils.notification_service import job_to_test_map; ci_event = os.environ["ci_event"]; job = os.environ["job"]; test_name = job_to_test_map[job]; title = f"New failed tests of {ci_event}" + ":" + f" {test_name}"; print(title)')" >> $GITHUB_ENV
296
+
297
+ - name: Send processed report
298
+ if: ${{ !endsWith(env.REPORT_TEXT, '{}') }}
299
+ uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001
300
+ with:
301
+ # Slack channel id, channel name, or user id to post message.
302
+ # See also: https://api.slack.com/methods/chat.postMessage#channels
303
+ channel-id: '#${{ inputs.slack_report_channel }}'
304
+ # For posting a rich message using Block Kit
305
+ payload: |
306
+ {
307
+ "blocks": [
308
+ {
309
+ "type": "header",
310
+ "text": {
311
+ "type": "plain_text",
312
+ "text": "${{ env.title }}"
313
+ }
314
+ },
315
+ {
316
+ "type": "section",
317
+ "text": {
318
+ "type": "mrkdwn",
319
+ "text": "${{ env.REPORT_TEXT }}"
320
+ }
321
+ }
322
+ ]
323
+ }
324
+ env:
325
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
.github/workflows/check_tiny_models.yml ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Check Tiny Models
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - check_tiny_models*
7
+ repository_dispatch:
8
+ schedule:
9
+ - cron: "0 2 * * *"
10
+
11
+ env:
12
+ TOKEN: ${{ secrets.TRANSFORMERS_HUB_BOT_HF_TOKEN }}
13
+
14
+ jobs:
15
+ check_tiny_models:
16
+ name: Check tiny models
17
+ runs-on: ubuntu-22.04
18
+ steps:
19
+ - name: Checkout transformers
20
+ uses: actions/checkout@v4
21
+ with:
22
+ fetch-depth: 2
23
+
24
+ - uses: actions/checkout@v4
25
+ - name: Set up Python 3.8
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ # Semantic version range syntax or exact version of a Python version
29
+ python-version: '3.8'
30
+ # Optional - x64 or x86 architecture, defaults to x64
31
+ architecture: 'x64'
32
+
33
+ - name: Install
34
+ run: |
35
+ sudo apt-get -y update && sudo apt-get install -y libsndfile1-dev espeak-ng cmake
36
+ pip install --upgrade pip
37
+ python -m pip install -U .[sklearn,torch,testing,sentencepiece,torch-speech,vision,timm,video,tf-cpu]
38
+ pip install tensorflow_probability
39
+ python -m pip install -U 'natten<0.15.0'
40
+
41
+ - name: Create all tiny models (locally)
42
+ run: |
43
+ python utils/create_dummy_models.py tiny_local_models --all --num_workers 2
44
+
45
+ - name: Local tiny model reports artifacts
46
+ if: ${{ always() }}
47
+ uses: actions/upload-artifact@v4
48
+ with:
49
+ name: tiny_local_model_creation_reports
50
+ path: tiny_local_models/reports
51
+
52
+ # GitHub-hosted runners have 2-core CPUs
53
+ - name: Run pipeline tests against all new (local) tiny models
54
+ run: |
55
+ OMP_NUM_THREADS=1 TRANSFORMERS_TINY_MODEL_PATH=tiny_local_models python -m pytest --max-worker-restart=0 -n 2 --dist=loadfile -s -rA --make-reports=tests_pipelines tests/models -m is_pipeline_test -k "test_pipeline_" | tee tests_output.txt
56
+
57
+ - name: Test suite reports artifacts
58
+ if: ${{ always() }}
59
+ uses: actions/upload-artifact@v4
60
+ with:
61
+ name: tiny_local_model_creation_reports
62
+ path: reports/tests_pipelines
63
+
64
+ - name: Create + Upload tiny models for new model architecture(s)
65
+ run: |
66
+ python utils/update_tiny_models.py --num_workers 2
67
+
68
+ - name: Full report
69
+ run: cat tiny_models/reports/tiny_model_creation_report.json
70
+
71
+ - name: Failure report
72
+ run: cat tiny_models/reports/simple_failed_report.txt
73
+
74
+ - name: Summary report
75
+ run: cat tiny_models/reports/tiny_model_summary.json
76
+
77
+ - name: New tiny model creation reports artifacts
78
+ if: ${{ always() }}
79
+ uses: actions/upload-artifact@v4
80
+ with:
81
+ name: tiny_model_creation_reports
82
+ path: tiny_models/reports
.github/workflows/circleci-failure-summary-comment.yml ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: CircleCI Failure Summary Comment
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: [opened, synchronize, reopened]
6
+
7
+ jobs:
8
+ comment:
9
+ runs-on: ubuntu-22.04
10
+ permissions:
11
+ pull-requests: write
12
+ env:
13
+ TARGET_BRANCH: ${{ github.event.pull_request.head.ref }}
14
+ TARGET_SHA: ${{ github.event.pull_request.head.sha }}
15
+ PR_NUMBER: ${{ github.event.pull_request.number }}
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.13"
24
+
25
+ - name: Install dependencies
26
+ run: python -m pip install requests huggingface_hub
27
+
28
+ - name: Wait for CircleCI check suite completion
29
+ env:
30
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31
+ COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
32
+ GITHUB_REPOSITORY: ${{ github.repository }}
33
+ run: |
34
+ # Exit on error, undefined variables, or pipe failures
35
+ set -euo pipefail
36
+
37
+ echo "Waiting for CircleCI check suite to complete..."
38
+ # Timeout after 30 minutes (1800 seconds)
39
+ end=$((SECONDS + 1800))
40
+
41
+ while [ $SECONDS -lt $end ]; do
42
+ # Query GitHub API for check suites associated with this commit
43
+ # || echo "" allows retry on transient API failures instead of exiting
44
+ suite_json=$(gh api "repos/${GITHUB_REPOSITORY}/commits/${COMMIT_SHA}/check-suites" \
45
+ --jq '.check_suites[] | select(.app.slug == "circleci-checks")' || echo "")
46
+
47
+ if [ -z "$suite_json" ]; then
48
+ echo "CircleCI check suite not found yet, retrying..."
49
+ else
50
+ status=$(echo "$suite_json" | jq -r '.status')
51
+ conclusion=$(echo "$suite_json" | jq -r '.conclusion // empty')
52
+ echo "CircleCI status: $status, conclusion: $conclusion"
53
+
54
+ # Check suite is done when status is "completed" AND conclusion is set
55
+ if [ "$status" = "completed" ] && [ -n "$conclusion" ]; then
56
+ echo "Check suite completed successfully"
57
+ exit 0
58
+ fi
59
+ fi
60
+
61
+ # Poll every 20 seconds
62
+ sleep 20
63
+ done
64
+
65
+ echo "ERROR: Timed out waiting for CircleCI check suite"
66
+ exit 1
67
+
68
+ - name: Get CircleCI run's artifacts and upload them to Hub
69
+ id: circleci
70
+ env:
71
+ COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
72
+ REPO: ${{ github.repository }}
73
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74
+ run: |
75
+ # Step 1: Get CircleCI check suite ID
76
+ echo "Getting check suites for commit ${COMMIT_SHA}..."
77
+ check_suites=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
78
+ "https://api.github.com/repos/${REPO}/commits/${COMMIT_SHA}/check-suites")
79
+
80
+ circleci_suite_id=$(echo "$check_suites" | jq -r '.check_suites[] | select(.app.slug == "circleci-checks") | .id' | head -n 1)
81
+ echo "CircleCI check suite ID: ${circleci_suite_id}"
82
+
83
+ # Step 2: Get check runs from the CircleCI suite
84
+ echo "Getting check runs for suite ${circleci_suite_id}..."
85
+ check_runs=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
86
+ "https://api.github.com/repos/${REPO}/check-suites/${circleci_suite_id}/check-runs")
87
+
88
+ # Step 3: Extract workflow ID from the "run_tests" check run
89
+ workflow_id=$(echo "$check_runs" | jq -r '.check_runs[] | select(.name == "run_tests") | .details_url' | grep -oP 'workflows/\K[a-f0-9-]+')
90
+ echo "CircleCI Workflow ID: ${workflow_id}"
91
+
92
+ # Step 4: Get all jobs in the workflow
93
+ echo "Getting jobs for workflow ${workflow_id}..."
94
+ jobs=$(curl -s \
95
+ "https://circleci.com/api/v2/workflow/${workflow_id}/job")
96
+
97
+ # Step 5: Extract collection_job details
98
+ collection_job_number=$(echo "$jobs" | jq -r '.items[] | select(.name == "collection_job") | .job_number')
99
+ collection_job_id=$(echo "$jobs" | jq -r '.items[] | select(.name == "collection_job") | .id')
100
+ echo "CircleCI Collection job number: ${collection_job_number}"
101
+ echo "CircleCI Collection job ID: ${collection_job_id}"
102
+
103
+ # Step 6: Get artifacts list
104
+ echo "Getting artifacts for job ${collection_job_number}..."
105
+ artifacts=$(curl -s \
106
+ "https://circleci.com/api/v2/project/gh/${REPO}/${collection_job_number}/artifacts")
107
+
108
+ echo "$artifacts" | jq '.'
109
+
110
+ # Step 7: Download failure_summary.json specifically
111
+ failure_summary_url=$(echo "$artifacts" | jq -r '.items[] | select(.path == "outputs/failure_summary.json") | .url')
112
+
113
+ if [ -z "$failure_summary_url" ]; then
114
+ echo "failure_summary.json not found in artifacts - PR may not have latest main merged. Skipping."
115
+ echo "artifact_found=false" >> $GITHUB_OUTPUT
116
+ exit 0
117
+ fi
118
+
119
+ echo "Downloading failure_summary.json from: ${failure_summary_url}"
120
+ mkdir -p outputs
121
+ curl -s -L "${failure_summary_url}" -o outputs/failure_summary.json
122
+ ls -la outputs
123
+
124
+ echo "Downloaded failure_summary.json successfully"
125
+
126
+ # Verify the file was downloaded
127
+ if [ ! -f outputs/failure_summary.json ]; then
128
+ echo "Failed to download failure_summary.json - skipping."
129
+ echo "artifact_found=false" >> $GITHUB_OUTPUT
130
+ exit 0
131
+ fi
132
+
133
+ echo "File size: $(wc -c < outputs/failure_summary.json) bytes"
134
+
135
+ # Export variables for next steps
136
+ echo "artifact_found=true" >> $GITHUB_OUTPUT
137
+ echo "workflow_id=${workflow_id}" >> $GITHUB_OUTPUT
138
+ echo "collection_job_number=${collection_job_number}" >> $GITHUB_OUTPUT
139
+
140
+ - name: Upload summaries to Hub
141
+ if: steps.circleci.outputs.artifact_found == 'true'
142
+ env:
143
+ HF_TOKEN: ${{ secrets.HF_CI_WRITE_TOKEN }}
144
+ CIRCLECI_RESULTS_DATASET_ID: "transformers-community/circleci-test-results"
145
+ PR_NUMBER: ${{ github.event.pull_request.number }}
146
+ COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
147
+ run: |
148
+ python << 'EOF'
149
+ import os
150
+ from pathlib import Path
151
+ from huggingface_hub import HfApi
152
+
153
+ # Setup paths
154
+ pr_number = os.environ["PR_NUMBER"]
155
+ commit_short = os.environ["COMMIT_SHA"][:12]
156
+ folder_path = f"pr-{pr_number}/sha-{commit_short}"
157
+
158
+ # Create folder and move file
159
+ Path(folder_path).mkdir(parents=True, exist_ok=True)
160
+ Path("outputs/failure_summary.json").rename(f"{folder_path}/failure_summary.json")
161
+
162
+ # Upload to Hub
163
+ dataset_id = os.environ["CIRCLECI_RESULTS_DATASET_ID"]
164
+ api = HfApi(token=os.environ["HF_TOKEN"])
165
+ api.upload_folder(
166
+ commit_message=f"Update CircleCI artifacts for PR {pr_number} ({commit_short})",
167
+ folder_path=folder_path,
168
+ path_in_repo=folder_path,
169
+ repo_id=dataset_id,
170
+ repo_type="dataset",
171
+ )
172
+
173
+ print(f"Uploaded {folder_path} to {dataset_id}")
174
+ EOF
175
+
176
+ - name: Delete existing CircleCI summary comments
177
+ if: steps.circleci.outputs.artifact_found == 'true'
178
+ env:
179
+ PR_NUMBER: ${{ github.event.pull_request.number }}
180
+ uses: actions/github-script@v7
181
+ with:
182
+ script: |
183
+ const PR_NUMBER = parseInt(process.env.PR_NUMBER, 10);
184
+
185
+ // Get all comments on the PR
186
+ const { data: comments } = await github.rest.issues.listComments({
187
+ owner: context.repo.owner,
188
+ repo: context.repo.repo,
189
+ issue_number: PR_NUMBER
190
+ });
191
+
192
+ // Find existing bot comments that start with "View the CircleCI Test Summary for this PR:"
193
+ const existingComments = comments.filter(comment =>
194
+ comment.user.login === 'github-actions[bot]' &&
195
+ comment.body.startsWith('View the CircleCI Test Summary for this PR:')
196
+ );
197
+
198
+ // Delete all matching comments
199
+ for (const comment of existingComments) {
200
+ console.log(`Deleting comment #${comment.id}`);
201
+ await github.rest.issues.deleteComment({
202
+ owner: context.repo.owner,
203
+ repo: context.repo.repo,
204
+ comment_id: comment.id
205
+ });
206
+ }
207
+
208
+ console.log(`Deleted ${existingComments.length} old CircleCI summary comment(s)`);
209
+
210
+ - name: Post comment with helper link
211
+ if: steps.circleci.outputs.artifact_found == 'true'
212
+ env:
213
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
214
+ GITHUB_REPOSITORY: ${{ github.repository }}
215
+ PR_NUMBER: ${{ github.event.pull_request.number }}
216
+ PR_SHA: ${{ github.event.pull_request.head.sha }}
217
+ run: |
218
+ COMMIT_SHORT="${PR_SHA:0:12}"
219
+ SUMMARY_FILE="pr-${PR_NUMBER}/sha-${COMMIT_SHORT}/failure_summary.json"
220
+
221
+ if [ ! -f "$SUMMARY_FILE" ]; then
222
+ echo "failure_summary.json missing, skipping comment."
223
+ exit 0
224
+ fi
225
+
226
+ failures=$(jq '.failures | length' "$SUMMARY_FILE")
227
+ if [ "$failures" -eq 0 ]; then
228
+ echo "No failures detected, skipping PR comment."
229
+ exit 0
230
+ fi
231
+
232
+ # Build Space URL with encoded parameters
233
+ repo_enc=$(jq -rn --arg v "$GITHUB_REPOSITORY" '$v|@uri')
234
+ pr_enc=$(jq -rn --arg v "$PR_NUMBER" '$v|@uri')
235
+ sha_short="${PR_SHA:0:6}"
236
+ sha_enc=$(jq -rn --arg v "$sha_short" '$v|@uri')
237
+ SPACE_URL="https://huggingface.co/spaces/transformers-community/circle-ci-viz?pr=${pr_enc}&sha=${sha_enc}"
238
+
239
+ # Post comment (using printf for proper newlines)
240
+ gh api \
241
+ --method POST \
242
+ -H "Accept: application/vnd.github+json" \
243
+ -H "X-GitHub-Api-Version: 2022-11-28" \
244
+ "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \
245
+ -f body="$(printf "View the CircleCI Test Summary for this PR:\n\n%s" "$SPACE_URL")"
.github/workflows/codeql.yml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: CodeQL Security Analysis
3
+
4
+ on:
5
+ push:
6
+ branches: ["main", "fix_security_issue_*"]
7
+ # pull_request:
8
+ # branches: ["main"]
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ codeql:
13
+ name: CodeQL Analysis
14
+ uses: huggingface/security-workflows/.github/workflows/codeql-reusable.yml@main
15
+ permissions:
16
+ security-events: write
17
+ packages: read
18
+ actions: read
19
+ contents: read
20
+ with:
21
+ languages: '["actions"]'
22
+ queries: 'security-extended,security-and-quality'
23
+ runner: 'ubuntu-latest'
.github/workflows/collated-reports.yml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: CI collated reports
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ job:
7
+ required: true
8
+ type: string
9
+ report_repo_id:
10
+ required: true
11
+ type: string
12
+ machine_type:
13
+ required: true
14
+ type: string
15
+ gpu_name:
16
+ description: Name of the GPU used for the job. Its enough that the value contains the name of the GPU, e.g. "noise-h100-more-noise". Case insensitive.
17
+ required: true
18
+ type: string
19
+
20
+ jobs:
21
+ collated_reports:
22
+ name: Collated reports
23
+ runs-on: ubuntu-22.04
24
+ if: always()
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ - uses: actions/download-artifact@v4
28
+
29
+ - name: Collated reports
30
+ shell: bash
31
+ env:
32
+ ACCESS_REPO_INFO_TOKEN: ${{ secrets.ACCESS_REPO_INFO_TOKEN }}
33
+ CI_SHA: ${{ github.sha }}
34
+ TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN: ${{ secrets.TRANSFORMERS_CI_RESULTS_UPLOAD_TOKEN }}
35
+ run: |
36
+ pip install huggingface_hub
37
+ python3 utils/collated_reports.py \
38
+ --path . \
39
+ --machine-type ${{ inputs.machine_type }} \
40
+ --commit-hash ${{ env.CI_SHA }} \
41
+ --job ${{ inputs.job }} \
42
+ --report-repo-id ${{ inputs.report_repo_id }} \
43
+ --gpu-name ${{ inputs.gpu_name }}
.github/workflows/doctest_job.yml ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Doctest job
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ job_splits:
7
+ required: true
8
+ type: string
9
+ split_keys:
10
+ required: true
11
+ type: string
12
+
13
+ env:
14
+ HF_HOME: /mnt/cache
15
+ TRANSFORMERS_IS_CI: yes
16
+ RUN_SLOW: yes
17
+ OMP_NUM_THREADS: 16
18
+ MKL_NUM_THREADS: 16
19
+ TF_FORCE_GPU_ALLOW_GROWTH: true
20
+
21
+ jobs:
22
+ run_doctests:
23
+ name: " "
24
+ strategy:
25
+ max-parallel: 8 # 8 jobs at a time
26
+ fail-fast: false
27
+ matrix:
28
+ split_keys: ${{ fromJson(inputs.split_keys) }}
29
+ runs-on:
30
+ group: aws-g5-4xlarge-cache
31
+ container:
32
+ image: huggingface/transformers-all-latest-gpu
33
+ options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/
34
+ steps:
35
+ - name: Update clone
36
+ working-directory: /transformers
37
+ run: git fetch && git checkout ${{ github.sha }}
38
+
39
+ - name: Reinstall transformers in edit mode (remove the one installed during docker image build)
40
+ working-directory: /transformers
41
+ run: python3 -m pip uninstall -y transformers && python3 -m pip install -e .[flax]
42
+
43
+ - name: GPU visibility
44
+ working-directory: /transformers
45
+ run: |
46
+ python3 utils/print_env.py
47
+
48
+ - name: Show installed libraries and their versions
49
+ run: pip freeze
50
+
51
+ - name: Get doctest files
52
+ working-directory: /transformers
53
+ run: |
54
+ echo "${{ toJson(fromJson(inputs.job_splits)[matrix.split_keys]) }}" > doc_tests.txt
55
+ cat doc_tests.txt
56
+
57
+ - name: Set `split_keys`
58
+ shell: bash
59
+ run: |
60
+ echo "${{ matrix.split_keys }}"
61
+ split_keys=${{ matrix.split_keys }}
62
+ split_keys=${split_keys//'/'/'_'}
63
+ echo "split_keys"
64
+ echo "split_keys=$split_keys" >> $GITHUB_ENV
65
+
66
+ - name: Run doctests
67
+ working-directory: /transformers
68
+ run: |
69
+ cat doc_tests.txt
70
+ python3 -m pytest -v --make-reports doc_tests_gpu_${{ env.split_keys }} --doctest-modules $(cat doc_tests.txt) -sv --doctest-continue-on-failure --doctest-glob="*.md"
71
+
72
+ - name: Failure short reports
73
+ if: ${{ failure() }}
74
+ continue-on-error: true
75
+ run: cat /transformers/reports/doc_tests_gpu_${{ env.split_keys }}/failures_short.txt
76
+
77
+ - name: "Test suite reports artifacts: doc_tests_gpu_test_reports_${{ env.split_keys }}"
78
+ if: ${{ always() }}
79
+ uses: actions/upload-artifact@v4
80
+ with:
81
+ name: doc_tests_gpu_test_reports_${{ env.split_keys }}
82
+ path: /transformers/reports/doc_tests_gpu_${{ env.split_keys }}
.github/workflows/doctests.yml ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Doctests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - run_doctest*
7
+ repository_dispatch:
8
+ schedule:
9
+ - cron: "17 2 * * *"
10
+
11
+ env:
12
+ NUM_SLICES: 3
13
+
14
+ jobs:
15
+ setup:
16
+ name: Setup
17
+ runs-on:
18
+ group: aws-g5-4xlarge-cache
19
+ container:
20
+ image: huggingface/transformers-all-latest-gpu
21
+ options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/
22
+ outputs:
23
+ job_splits: ${{ steps.set-matrix.outputs.job_splits }}
24
+ split_keys: ${{ steps.set-matrix.outputs.split_keys }}
25
+ steps:
26
+ - name: Update clone
27
+ working-directory: /transformers
28
+ run: |
29
+ git fetch && git checkout ${{ github.sha }}
30
+
31
+ - name: Reinstall transformers in edit mode (remove the one installed during docker image build)
32
+ working-directory: /transformers
33
+ run: python3 -m pip uninstall -y transformers && python3 -m pip install -e .
34
+
35
+ - name: Show installed libraries and their versions
36
+ working-directory: /transformers
37
+ run: pip freeze
38
+
39
+ - name: Check values for matrix
40
+ working-directory: /transformers
41
+ run: |
42
+ python3 utils/split_doctest_jobs.py
43
+ python3 utils/split_doctest_jobs.py --only_return_keys --num_splits ${{ env.NUM_SLICES }}
44
+
45
+ - id: set-matrix
46
+ working-directory: /transformers
47
+ name: Set values for matrix
48
+ run: |
49
+ echo "job_splits=$(python3 utils/split_doctest_jobs.py)" >> $GITHUB_OUTPUT
50
+ echo "split_keys=$(python3 utils/split_doctest_jobs.py --only_return_keys --num_splits ${{ env.NUM_SLICES }})" >> $GITHUB_OUTPUT
51
+
52
+ call_doctest_job:
53
+ name: "Call doctest jobs"
54
+ needs: setup
55
+ strategy:
56
+ max-parallel: 1 # 1 split at a time (in `doctest_job.yml`, we set `8` to run 8 jobs at the same time)
57
+ fail-fast: false
58
+ matrix:
59
+ split_keys: ${{ fromJson(needs.setup.outputs.split_keys) }}
60
+ uses: ./.github/workflows/doctest_job.yml
61
+ with:
62
+ job_splits: ${{ needs.setup.outputs.job_splits }}
63
+ split_keys: ${{ toJson(matrix.split_keys) }}
64
+ secrets: inherit
65
+
66
+ send_results:
67
+ name: Send results to webhook
68
+ runs-on: ubuntu-22.04
69
+ if: always()
70
+ needs: [call_doctest_job]
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+ - uses: actions/download-artifact@v4
74
+ - name: Send message to Slack
75
+ env:
76
+ CI_SLACK_BOT_TOKEN: ${{ secrets.CI_SLACK_BOT_TOKEN }}
77
+ ACCESS_REPO_INFO_TOKEN: ${{ secrets.ACCESS_REPO_INFO_TOKEN }}
78
+ # Use `CI_SLACK_CHANNEL_DUMMY_TESTS` when doing experimentation
79
+ SLACK_REPORT_CHANNEL: ${{ secrets.CI_SLACK_CHANNEL_ID_DAILY_DOCS }}
80
+ run: |
81
+ pip install slack_sdk
82
+ python utils/notification_service_doc_tests.py
83
+
84
+ - name: "Upload results"
85
+ if: ${{ always() }}
86
+ uses: actions/upload-artifact@v4
87
+ with:
88
+ name: doc_test_results
89
+ path: doc_test_results
.github/workflows/get-pr-info.yml ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Get PR commit SHA
2
+ on:
3
+ workflow_call:
4
+ inputs:
5
+ pr_number:
6
+ required: true
7
+ type: string
8
+ outputs:
9
+ PR_HEAD_REPO_FULL_NAME:
10
+ description: "The full name of the repository from which the pull request is created"
11
+ value: ${{ jobs.get-pr-info.outputs.PR_HEAD_REPO_FULL_NAME }}
12
+ PR_BASE_REPO_FULL_NAME:
13
+ description: "The full name of the repository to which the pull request is created"
14
+ value: ${{ jobs.get-pr-info.outputs.PR_BASE_REPO_FULL_NAME }}
15
+ PR_HEAD_REPO_OWNER:
16
+ description: "The owner of the repository from which the pull request is created"
17
+ value: ${{ jobs.get-pr-info.outputs.PR_HEAD_REPO_OWNER }}
18
+ PR_BASE_REPO_OWNER:
19
+ description: "The owner of the repository to which the pull request is created"
20
+ value: ${{ jobs.get-pr-info.outputs.PR_BASE_REPO_OWNER }}
21
+ PR_HEAD_REPO_NAME:
22
+ description: "The name of the repository from which the pull request is created"
23
+ value: ${{ jobs.get-pr-info.outputs.PR_HEAD_REPO_NAME }}
24
+ PR_BASE_REPO_NAME:
25
+ description: "The name of the repository to which the pull request is created"
26
+ value: ${{ jobs.get-pr-info.outputs.PR_BASE_REPO_NAME }}
27
+ PR_HEAD_REF:
28
+ description: "The branch name of the pull request in the head repository"
29
+ value: ${{ jobs.get-pr-info.outputs.PR_HEAD_REF }}
30
+ PR_BASE_REF:
31
+ description: "The branch name in the base repository (to merge into)"
32
+ value: ${{ jobs.get-pr-info.outputs.PR_BASE_REF }}
33
+ PR_HEAD_SHA:
34
+ description: "The head sha of the pull request branch in the head repository"
35
+ value: ${{ jobs.get-pr-info.outputs.PR_HEAD_SHA }}
36
+ PR_BASE_SHA:
37
+ description: "The head sha of the target branch in the base repository"
38
+ value: ${{ jobs.get-pr-info.outputs.PR_BASE_SHA }}
39
+ PR_MERGE_COMMIT_SHA:
40
+ description: "The sha of the merge commit for the pull request (created by GitHub) in the base repository"
41
+ value: ${{ jobs.get-pr-info.outputs.PR_MERGE_COMMIT_SHA }}
42
+ PR_MERGE_COMMIT_BASE_SHA:
43
+ description: "The sha of the parent commit of the merge commit on the target branch in the base repository"
44
+ value: ${{ jobs.get-pr-info.outputs.PR_MERGE_COMMIT_BASE_SHA }}
45
+ PR_HEAD_COMMIT_DATE:
46
+ description: "The date of the head sha of the pull request branch in the head repository"
47
+ value: ${{ jobs.get-pr-info.outputs.PR_HEAD_COMMIT_DATE }}
48
+ PR_MERGE_COMMIT_DATE:
49
+ description: "The date of the merge commit for the pull request (created by GitHub) in the base repository"
50
+ value: ${{ jobs.get-pr-info.outputs.PR_MERGE_COMMIT_DATE }}
51
+ PR_HEAD_COMMIT_TIMESTAMP:
52
+ description: "The timestamp of the head sha of the pull request branch in the head repository"
53
+ value: ${{ jobs.get-pr-info.outputs.PR_HEAD_COMMIT_TIMESTAMP }}
54
+ PR_MERGE_COMMIT_TIMESTAMP:
55
+ description: "The timestamp of the merge commit for the pull request (created by GitHub) in the base repository"
56
+ value: ${{ jobs.get-pr-info.outputs.PR_MERGE_COMMIT_TIMESTAMP }}
57
+ PR:
58
+ description: "The PR"
59
+ value: ${{ jobs.get-pr-info.outputs.PR }}
60
+ PR_FILES:
61
+ description: "The files touched in the PR"
62
+ value: ${{ jobs.get-pr-info.outputs.PR_FILES }}
63
+
64
+
65
+ jobs:
66
+ get-pr-info:
67
+ runs-on: ubuntu-22.04
68
+ name: Get PR commit SHA better
69
+ outputs:
70
+ PR_HEAD_REPO_FULL_NAME: ${{ steps.pr_info.outputs.head_repo_full_name }}
71
+ PR_BASE_REPO_FULL_NAME: ${{ steps.pr_info.outputs.base_repo_full_name }}
72
+ PR_HEAD_REPO_OWNER: ${{ steps.pr_info.outputs.head_repo_owner }}
73
+ PR_BASE_REPO_OWNER: ${{ steps.pr_info.outputs.base_repo_owner }}
74
+ PR_HEAD_REPO_NAME: ${{ steps.pr_info.outputs.head_repo_name }}
75
+ PR_BASE_REPO_NAME: ${{ steps.pr_info.outputs.base_repo_name }}
76
+ PR_HEAD_REF: ${{ steps.pr_info.outputs.head_ref }}
77
+ PR_BASE_REF: ${{ steps.pr_info.outputs.base_ref }}
78
+ PR_HEAD_SHA: ${{ steps.pr_info.outputs.head_sha }}
79
+ PR_BASE_SHA: ${{ steps.pr_info.outputs.base_sha }}
80
+ PR_MERGE_COMMIT_BASE_SHA: ${{ steps.pr_info.outputs.merge_commit_base_sha }}
81
+ PR_MERGE_COMMIT_SHA: ${{ steps.pr_info.outputs.merge_commit_sha }}
82
+ PR_HEAD_COMMIT_DATE: ${{ steps.pr_info.outputs.head_commit_date }}
83
+ PR_MERGE_COMMIT_DATE: ${{ steps.pr_info.outputs.merge_commit_date }}
84
+ PR_HEAD_COMMIT_TIMESTAMP: ${{ steps.get_timestamps.outputs.head_commit_timestamp }}
85
+ PR_MERGE_COMMIT_TIMESTAMP: ${{ steps.get_timestamps.outputs.merge_commit_timestamp }}
86
+ PR: ${{ steps.pr_info.outputs.pr }}
87
+ PR_FILES: ${{ steps.pr_info.outputs.files }}
88
+ if: ${{ inputs.pr_number != '' }}
89
+ steps:
90
+ - name: Extract PR details
91
+ id: pr_info
92
+ uses: actions/github-script@v6
93
+ with:
94
+ script: |
95
+ const { data: pr } = await github.rest.pulls.get({
96
+ owner: context.repo.owner,
97
+ repo: context.repo.repo,
98
+ pull_number: ${{ inputs.pr_number }}
99
+ });
100
+
101
+ const { data: head_commit } = await github.rest.repos.getCommit({
102
+ owner: pr.head.repo.owner.login,
103
+ repo: pr.head.repo.name,
104
+ ref: pr.head.ref
105
+ });
106
+
107
+ const { data: merge_commit } = await github.rest.repos.getCommit({
108
+ owner: pr.base.repo.owner.login,
109
+ repo: pr.base.repo.name,
110
+ ref: pr.merge_commit_sha,
111
+ });
112
+
113
+ const { data: files } = await github.rest.pulls.listFiles({
114
+ owner: context.repo.owner,
115
+ repo: context.repo.repo,
116
+ pull_number: ${{ inputs.pr_number }}
117
+ });
118
+
119
+ core.setOutput('head_repo_full_name', pr.head.repo.full_name);
120
+ core.setOutput('base_repo_full_name', pr.base.repo.full_name);
121
+ core.setOutput('head_repo_owner', pr.head.repo.owner.login);
122
+ core.setOutput('base_repo_owner', pr.base.repo.owner.login);
123
+ core.setOutput('head_repo_name', pr.head.repo.name);
124
+ core.setOutput('base_repo_name', pr.base.repo.name);
125
+ core.setOutput('head_ref', pr.head.ref);
126
+ core.setOutput('base_ref', pr.base.ref);
127
+ core.setOutput('head_sha', pr.head.sha);
128
+ core.setOutput('base_sha', pr.base.sha);
129
+ core.setOutput('merge_commit_base_sha', merge_commit.parents[0].sha);
130
+ core.setOutput('merge_commit_sha', pr.merge_commit_sha);
131
+ core.setOutput('pr', pr);
132
+
133
+ core.setOutput('head_commit_date', head_commit.commit.committer.date);
134
+ core.setOutput('merge_commit_date', merge_commit.commit.committer.date);
135
+
136
+ core.setOutput('files', files);
137
+
138
+ console.log('PR head commit:', {
139
+ head_commit: head_commit,
140
+ commit: head_commit.commit,
141
+ date: head_commit.commit.committer.date
142
+ });
143
+
144
+ console.log('PR merge commit:', {
145
+ merge_commit: merge_commit,
146
+ commit: merge_commit.commit,
147
+ date: merge_commit.commit.committer.date
148
+ });
149
+
150
+ console.log('PR Info:', {
151
+ pr_info: pr
152
+ });
153
+
154
+ - name: Convert dates to timestamps
155
+ id: get_timestamps
156
+ env:
157
+ head_commit_date: ${{ steps.pr_info.outputs.head_commit_date }}
158
+ merge_commit_date: ${{ steps.pr_info.outputs.merge_commit_date }}
159
+ run: |
160
+ echo "$head_commit_date"
161
+ echo "$merge_commit_date"
162
+ head_commit_timestamp=$(date -d "$head_commit_date" +%s)
163
+ merge_commit_timestamp=$(date -d "$merge_commit_date" +%s)
164
+ echo "$head_commit_timestamp"
165
+ echo "$merge_commit_timestamp"
166
+ echo "head_commit_timestamp=$head_commit_timestamp" >> $GITHUB_OUTPUT
167
+ echo "merge_commit_timestamp=$merge_commit_timestamp" >> $GITHUB_OUTPUT
.github/workflows/get-pr-number.yml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Get PR number
2
+ on:
3
+ workflow_call:
4
+ outputs:
5
+ PR_NUMBER:
6
+ description: "The extracted PR number"
7
+ value: ${{ jobs.get-pr-number.outputs.PR_NUMBER }}
8
+
9
+ jobs:
10
+ get-pr-number:
11
+ runs-on: ubuntu-22.04
12
+ name: Get PR number
13
+ outputs:
14
+ PR_NUMBER: ${{ steps.set_pr_number.outputs.PR_NUMBER }}
15
+ steps:
16
+ - name: Get PR number
17
+ shell: bash
18
+ env:
19
+ issue_number: ${{ github.event.issue.number }}
20
+ is_pull_request_issue: ${{ github.event.issue.pull_request != null }}
21
+ pr_number: ${{ github.event.pull_request.number }}
22
+ is_pull_request: ${{ github.event.pull_request != null }}
23
+ event_number: ${{ github.event.number }}
24
+ run: |
25
+ if [[ "$issue_number" != "" && "$is_pull_request_issue" == "true" ]]; then
26
+ echo "PR_NUMBER=$issue_number" >> $GITHUB_ENV
27
+ elif [[ "$pr_number" != "" ]]; then
28
+ echo "PR_NUMBER=$pr_number" >> $GITHUB_ENV
29
+ elif [[ "$is_pull_request" == "true" ]]; then
30
+ echo "PR_NUMBER=$event_number" >> $GITHUB_ENV
31
+ else
32
+ echo "PR_NUMBER=" >> $GITHUB_ENV
33
+ fi
34
+
35
+ - name: Check PR number
36
+ shell: bash
37
+ run: |
38
+ echo "$PR_NUMBER"
39
+
40
+ - name: Set PR number
41
+ id: set_pr_number
42
+ run: echo "PR_NUMBER=$PR_NUMBER" >> "$GITHUB_OUTPUT"
.github/workflows/model_jobs.yml ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: model jobs
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ folder_slices:
7
+ required: true
8
+ type: string
9
+ machine_type:
10
+ required: true
11
+ type: string
12
+ slice_id:
13
+ required: true
14
+ type: number
15
+ docker:
16
+ required: true
17
+ type: string
18
+ commit_sha:
19
+ required: false
20
+ type: string
21
+ report_name_prefix:
22
+ required: false
23
+ default: run_models_gpu
24
+ type: string
25
+ runner_type:
26
+ required: false
27
+ type: string
28
+ report_repo_id:
29
+ required: false
30
+ type: string
31
+ pytest_marker:
32
+ required: false
33
+ type: string
34
+
35
+ env:
36
+ HF_HOME: /mnt/cache
37
+ TRANSFORMERS_IS_CI: yes
38
+ OMP_NUM_THREADS: 8
39
+ MKL_NUM_THREADS: 8
40
+ RUN_SLOW: yes
41
+ # For gated repositories, we still need to agree to share information on the Hub repo. page in order to get access.
42
+ # This token is created under the bot `hf-transformers-bot`.
43
+ HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
44
+ TF_FORCE_GPU_ALLOW_GROWTH: true
45
+ CUDA_VISIBLE_DEVICES: 0,1
46
+
47
+ jobs:
48
+ run_models_gpu:
49
+ name: " "
50
+ strategy:
51
+ max-parallel: 8
52
+ fail-fast: false
53
+ matrix:
54
+ folders: ${{ fromJson(inputs.folder_slices)[inputs.slice_id] }}
55
+ runs-on:
56
+ group: '${{ inputs.machine_type }}'
57
+ container:
58
+ image: ${{ inputs.docker }}
59
+ options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/
60
+ outputs:
61
+ machine_type: ${{ steps.set_machine_type.outputs.machine_type }}
62
+ steps:
63
+ - name: Echo input and matrix info
64
+ shell: bash
65
+ env:
66
+ folder_slices: ${{ inputs.folder_slices }}
67
+ matrix_folders: ${{ matrix.folders }}
68
+ slice_data: ${{ toJson(fromJson(inputs.folder_slices)[inputs.slice_id]) }}
69
+ run: |
70
+ echo "$folder_slices"
71
+ echo "$matrix_folders"
72
+ echo "$slice_data"
73
+
74
+ - name: Echo folder ${{ matrix.folders }}
75
+ shell: bash
76
+ # For folders like `models/bert`, set an env. var. (`matrix_folders`) to `models_bert`, which will be used to
77
+ # set the artifact folder names (because the character `/` is not allowed).
78
+ env:
79
+ matrix_folders_raw: ${{ matrix.folders }}
80
+ run: |
81
+ echo "$matrix_folders_raw"
82
+ matrix_folders="${matrix_folders_raw/'models/'/'models_'}"
83
+ echo "$matrix_folders"
84
+ echo "matrix_folders=$matrix_folders" >> $GITHUB_ENV
85
+
86
+ - name: Update clone
87
+ working-directory: /transformers
88
+ env:
89
+ commit_sha: ${{ inputs.commit_sha || github.sha }}
90
+ run: |
91
+ git fetch origin "$commit_sha" && git checkout "$commit_sha"
92
+
93
+ - name: Reinstall transformers in edit mode (remove the one installed during docker image build)
94
+ working-directory: /transformers
95
+ run: python3 -m pip uninstall -y transformers && python3 -m pip install -e .
96
+
97
+ - name: Update / Install some packages (for Past CI)
98
+ if: ${{ contains(inputs.docker, '-past-') }}
99
+ working-directory: /transformers
100
+ run: |
101
+ python3 -m pip install -U datasets
102
+
103
+ - name: Update / Install some packages (for Past CI)
104
+ if: ${{ contains(inputs.docker, '-past-') && contains(inputs.docker, '-pytorch-') }}
105
+ working-directory: /transformers
106
+ run: |
107
+ python3 -m pip install --no-cache-dir git+https://github.com/huggingface/accelerate@main#egg=accelerate
108
+
109
+ - name: NVIDIA-SMI
110
+ run: |
111
+ nvidia-smi
112
+
113
+ - name: Environment
114
+ working-directory: /transformers
115
+ run: |
116
+ python3 utils/print_env.py
117
+
118
+ - name: Show installed libraries and their versions
119
+ working-directory: /transformers
120
+ run: pip freeze
121
+
122
+ - name: Set `machine_type` for report and artifact names
123
+ id: set_machine_type
124
+ working-directory: /transformers
125
+ shell: bash
126
+ env:
127
+ input_machine_type: ${{ inputs.machine_type }}
128
+ run: |
129
+ echo "$input_machine_type"
130
+
131
+ if [ "$input_machine_type" = "aws-g5-4xlarge-cache" ]; then
132
+ machine_type=single-gpu
133
+ elif [ "$input_machine_type" = "aws-g5-12xlarge-cache" ]; then
134
+ machine_type=multi-gpu
135
+ else
136
+ machine_type="$input_machine_type"
137
+ fi
138
+
139
+ echo "$machine_type"
140
+ echo "machine_type=$machine_type" >> $GITHUB_ENV
141
+ echo "machine_type=$machine_type" >> $GITHUB_OUTPUT
142
+
143
+ - name: Create report directory if it doesn't exist
144
+ shell: bash
145
+ env:
146
+ report_name_prefix: ${{ inputs.report_name_prefix }}
147
+ run: |
148
+ mkdir -p "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports"
149
+ echo "dummy" > "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports/dummy.txt"
150
+ ls -la "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports"
151
+
152
+ - name: Run all tests on GPU
153
+ working-directory: /transformers
154
+ env:
155
+ report_name_prefix: ${{ inputs.report_name_prefix }}
156
+ pytest_marker: ${{ inputs.pytest_marker }}
157
+ model: ${{ matrix.folders }}
158
+ run: |
159
+ script -q -c "PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports python3 -m pytest -rsfE -v -m '${pytest_marker}' --make-reports=${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports tests/${model}" test_outputs.txt
160
+ ls -la
161
+ # Extract the exit code from the output file
162
+ EXIT_CODE=$(tail -1 test_outputs.txt | grep -o 'COMMAND_EXIT_CODE="[0-9]*"' | cut -d'"' -f2)
163
+ exit ${EXIT_CODE:-1}
164
+
165
+ - name: Failure short reports
166
+ if: ${{ failure() }}
167
+ # This step is only to show information on Github Actions log.
168
+ # Always mark this step as successful, even if the report directory or the file `failures_short.txt` in it doesn't exist
169
+ continue-on-error: true
170
+ env:
171
+ report_name_prefix: ${{ inputs.report_name_prefix }}
172
+ run: cat "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports/failures_short.txt"
173
+
174
+ - name: Captured information
175
+ if: ${{ failure() }}
176
+ continue-on-error: true
177
+ env:
178
+ report_name_prefix: ${{ inputs.report_name_prefix }}
179
+ run: |
180
+ cat "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports/captured_info.txt"
181
+
182
+ - name: Copy test_outputs.txt
183
+ if: ${{ always() }}
184
+ continue-on-error: true
185
+ env:
186
+ report_name_prefix: ${{ inputs.report_name_prefix }}
187
+ run: |
188
+ cp /transformers/test_outputs.txt "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports"
189
+
190
+ - name: "Test suite reports artifacts: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports"
191
+ if: ${{ always() }}
192
+ uses: actions/upload-artifact@v4
193
+ with:
194
+ name: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports
195
+ path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports
196
+
197
+ collated_reports:
198
+ name: Collated Reports
199
+ if: ${{ always() && inputs.runner_type != '' }}
200
+ needs: run_models_gpu
201
+ uses: huggingface/transformers/.github/workflows/collated-reports.yml@main
202
+ with:
203
+ job: run_models_gpu
204
+ report_repo_id: ${{ inputs.report_repo_id }}
205
+ gpu_name: ${{ inputs.runner_type }}
206
+ machine_type: ${{ needs.run_models_gpu.outputs.machine_type }}
207
+ secrets: inherit
.github/workflows/model_jobs_intel_gaudi.yml ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: model jobs
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ folder_slices:
7
+ required: true
8
+ type: string
9
+ slice_id:
10
+ required: true
11
+ type: number
12
+ runner:
13
+ required: true
14
+ type: string
15
+ machine_type:
16
+ required: true
17
+ type: string
18
+ report_name_prefix:
19
+ required: false
20
+ default: run_models_gpu
21
+ type: string
22
+
23
+ env:
24
+ RUN_SLOW: yes
25
+ PT_HPU_LAZY_MODE: 0
26
+ TRANSFORMERS_IS_CI: yes
27
+ PT_ENABLE_INT64_SUPPORT: 1
28
+ HF_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
29
+ HF_HOME: /mnt/cache/.cache/huggingface
30
+
31
+ jobs:
32
+ run_models_gpu:
33
+ name: " "
34
+ strategy:
35
+ max-parallel: 8
36
+ fail-fast: false
37
+ matrix:
38
+ folders: ${{ fromJson(inputs.folder_slices)[inputs.slice_id] }}
39
+ runs-on:
40
+ group: ${{ inputs.runner }}
41
+ container:
42
+ image: vault.habana.ai/gaudi-docker/1.21.1/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest
43
+ options: --runtime=habana
44
+ -v /mnt/cache/.cache/huggingface:/mnt/cache/.cache/huggingface
45
+ --env OMPI_MCA_btl_vader_single_copy_mechanism=none
46
+ --env HABANA_VISIBLE_DEVICES
47
+ --env HABANA_VISIBLE_MODULES
48
+ --cap-add=sys_nice
49
+ --shm-size=64G
50
+ steps:
51
+ - name: Echo input and matrix info
52
+ shell: bash
53
+ run: |
54
+ echo "${{ inputs.folder_slices }}"
55
+ echo "${{ matrix.folders }}"
56
+ echo "${{ toJson(fromJson(inputs.folder_slices)[inputs.slice_id]) }}"
57
+
58
+ - name: Echo folder ${{ matrix.folders }}
59
+ shell: bash
60
+ run: |
61
+ echo "${{ matrix.folders }}"
62
+ matrix_folders=${{ matrix.folders }}
63
+ matrix_folders=${matrix_folders/'models/'/'models_'}
64
+ echo "$matrix_folders"
65
+ echo "matrix_folders=$matrix_folders" >> $GITHUB_ENV
66
+
67
+ - name: Checkout
68
+ uses: actions/checkout@v4
69
+ with:
70
+ fetch-depth: 0
71
+
72
+ - name: Install dependencies
73
+ run: |
74
+ pip install -e .[testing,torch] "numpy<2.0.0" scipy scikit-learn
75
+
76
+ - name: HL-SMI
77
+ run: |
78
+ hl-smi
79
+ echo "HABANA_VISIBLE_DEVICES=${HABANA_VISIBLE_DEVICES}"
80
+ echo "HABANA_VISIBLE_MODULES=${HABANA_VISIBLE_MODULES}"
81
+
82
+ - name: Environment
83
+ run: python3 utils/print_env.py
84
+
85
+ - name: Show installed libraries and their versions
86
+ run: pip freeze
87
+
88
+ - name: Set `machine_type` for report and artifact names
89
+ shell: bash
90
+ run: |
91
+ if [ "${{ inputs.machine_type }}" = "1gaudi" ]; then
92
+ machine_type=single-gpu
93
+ elif [ "${{ inputs.machine_type }}" = "2gaudi" ]; then
94
+ machine_type=multi-gpu
95
+ else
96
+ machine_type=${{ inputs.machine_type }}
97
+ fi
98
+ echo "machine_type=$machine_type" >> $GITHUB_ENV
99
+
100
+ - name: Run all tests on Gaudi
101
+ run: python3 -m pytest -v --make-reports=${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports tests/${{ matrix.folders }}
102
+
103
+ - name: Failure short reports
104
+ if: ${{ failure() }}
105
+ continue-on-error: true
106
+ run: cat reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/failures_short.txt
107
+
108
+ - name: Run test
109
+ shell: bash
110
+ run: |
111
+ mkdir -p reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports
112
+ echo "hello" > reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports/hello.txt
113
+ echo "${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports"
114
+
115
+ - name: "Test suite reports artifacts: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports"
116
+ if: ${{ always() }}
117
+ uses: actions/upload-artifact@v4
118
+ with:
119
+ name: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports
120
+ path: reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ matrix.folders }}_test_reports
.github/workflows/new_model_pr_merged_notification.yml ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Used to notify core maintainers about new model PR being merged
2
+ name: New model PR merged notification
3
+
4
+ on:
5
+ push:
6
+ branches:
7
+ - main
8
+ paths:
9
+ - 'src/transformers/models/*/modeling_*'
10
+
11
+ jobs:
12
+ notify_new_model:
13
+ name: Notify new model
14
+ runs-on: ubuntu-22.04
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+ - name: Check new model
20
+ shell: bash
21
+ run: |
22
+ python -m pip install gitpython
23
+ python -c 'from utils.pr_slow_ci_models import get_new_model; new_model = get_new_model(diff_with_last_commit=True); print(new_model)' | tee output.txt
24
+ echo "NEW_MODEL=$(tail -n 1 output.txt)" >> $GITHUB_ENV
25
+ echo "COMMIT_SHA=$(git log -1 --format=%H)" >> $GITHUB_ENV
26
+
27
+ - name: print commit sha
28
+ if: ${{ env.NEW_MODEL != ''}}
29
+ shell: bash
30
+ run: |
31
+ echo "$COMMIT_SHA"
32
+
33
+ - name: print new model
34
+ if: ${{ env.NEW_MODEL != ''}}
35
+ shell: bash
36
+ run: |
37
+ echo "$NEW_MODEL"
38
+
39
+ - name: Notify
40
+ if: ${{ env.NEW_MODEL != ''}}
41
+ uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001
42
+ with:
43
+ # Slack channel id, channel name, or user id to post message.
44
+ # See also: https://api.slack.com/methods/chat.postMessage#channels
45
+ channel-id: transformers-new-model-notification
46
+ # For posting a rich message using Block Kit
47
+ payload: |
48
+ {
49
+ "blocks": [
50
+ {
51
+ "type": "header",
52
+ "text": {
53
+ "type": "plain_text",
54
+ "text": "New model!",
55
+ "emoji": true
56
+ }
57
+ },
58
+ {
59
+ "type": "section",
60
+ "text": {
61
+ "type": "mrkdwn",
62
+ "text": "<https://github.com/huggingface/transformers/commit/${{ env.COMMIT_SHA }}|New model: ${{ env.NEW_MODEL }}> GH_ArthurZucker, GH_lysandrejik, GH_ydshieh\ncommit SHA: ${{ env.COMMIT_SHA }}"
63
+ }
64
+ }
65
+ ]
66
+ }
67
+ env:
68
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_CIFEEDBACK_BOT_TOKEN }}
.github/workflows/pr-repo-consistency-bot.yml ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: PR Repo. Consistency Bot
2
+
3
+ on:
4
+ issue_comment:
5
+ types:
6
+ - created
7
+ branches-ignore:
8
+ - main
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.event.issue.number }}-${{ startsWith(github.event.comment.body, '@bot /repo') }}
11
+ cancel-in-progress: true
12
+ permissions: read-all
13
+
14
+
15
+ jobs:
16
+ get-pr-number:
17
+ name: Get PR number
18
+ if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "eustlb", "MekkCyber", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "remi-or", "itazap", "3outeille", "IlyasMoutawwakil"]'), github.actor) && startsWith(github.event.comment.body, '@bot /repo') }}
19
+ uses: ./.github/workflows/get-pr-number.yml
20
+
21
+ get-pr-info:
22
+ name: Get PR commit SHA
23
+ needs: get-pr-number
24
+ if: ${{ needs.get-pr-number.outputs.PR_NUMBER != ''}}
25
+ uses: ./.github/workflows/get-pr-info.yml
26
+ with:
27
+ pr_number: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
28
+
29
+ check-timestamps:
30
+ name: Check timestamps (security check)
31
+ runs-on: ubuntu-22.04
32
+ needs: get-pr-info
33
+ outputs:
34
+ VERIFIED_PR_HEAD_SHA: ${{ needs.get-pr-info.outputs.PR_HEAD_SHA }}
35
+ steps:
36
+ - name: Verify `merge_commit` timestamp is older than the issue comment timestamp
37
+ env:
38
+ COMMENT_DATE: ${{ github.event.comment.created_at }}
39
+ PR_MERGE_COMMIT_TIMESTAMP: ${{ needs.get-pr-info.outputs.PR_MERGE_COMMIT_TIMESTAMP }}
40
+ run: |
41
+ COMMENT_TIMESTAMP=$(date -d "${COMMENT_DATE}" +"%s")
42
+ echo "COMMENT_DATE: $COMMENT_DATE"
43
+ echo "COMMENT_TIMESTAMP: $COMMENT_TIMESTAMP"
44
+ if [ $COMMENT_TIMESTAMP -le $PR_MERGE_COMMIT_TIMESTAMP ]; then
45
+ echo "Last commit on the pull request is newer than the issue comment triggering this run! Abort!";
46
+ exit -1;
47
+ fi
48
+
49
+ init_comment_with_url:
50
+ name: Init Comment on PR
51
+ runs-on: ubuntu-22.04
52
+ needs: [get-pr-number, check-timestamps]
53
+ outputs:
54
+ comment_id: ${{ steps.init_comment.outputs.comment_id }}
55
+ permissions:
56
+ pull-requests: write
57
+ steps:
58
+ - name: Delete existing bot comment if it exists
59
+ env:
60
+ PR_NUMBER: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
61
+ uses: actions/github-script@v6
62
+ with:
63
+ script: |
64
+ const PR_NUMBER = parseInt(process.env.PR_NUMBER, 10);
65
+
66
+ // Get all comments on the PR
67
+ const { data: comments } = await github.rest.issues.listComments({
68
+ owner: context.repo.owner,
69
+ repo: context.repo.repo,
70
+ issue_number: PR_NUMBER
71
+ });
72
+
73
+ // Find existing bot comments that start with "Repo. Consistency"
74
+ const existingComments = comments.filter(comment =>
75
+ comment.user.login === 'github-actions[bot]' &&
76
+ comment.body.startsWith('Repo. Consistency')
77
+ );
78
+
79
+ if (existingComments.length > 0) {
80
+ // Get the most recent comment
81
+ const mostRecentComment = existingComments
82
+ .sort((a, b) => new Date(b.created_at) - new Date(a.created_at))[0];
83
+
84
+ console.log(`Deleting most recent comment #${mostRecentComment.id}`);
85
+ await github.rest.issues.deleteComment({
86
+ owner: context.repo.owner,
87
+ repo: context.repo.repo,
88
+ comment_id: mostRecentComment.id
89
+ });
90
+ }
91
+
92
+ - name: Comment on PR with workflow run link
93
+ id: init_comment
94
+ env:
95
+ PR_NUMBER: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
96
+ uses: actions/github-script@v6
97
+ with:
98
+ script: |
99
+ const PR_NUMBER = parseInt(process.env.PR_NUMBER, 10);
100
+ const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
101
+
102
+ const { data: botComment } = await github.rest.issues.createComment({
103
+ owner: context.repo.owner,
104
+ repo: context.repo.repo,
105
+ issue_number: PR_NUMBER,
106
+ body: `Repo. Consistency fix is beginning .... [View the workflow run here](${runUrl}).`
107
+ });
108
+ core.setOutput('comment_id', botComment.id);
109
+
110
+ run-repo-consistency-checks:
111
+ runs-on: ubuntu-22.04
112
+ needs: [get-pr-info, check-timestamps, init_comment_with_url]
113
+ outputs:
114
+ changes_detected: ${{ steps.run_checks.outputs.changes_detected }}
115
+ steps:
116
+ # Checkout the trusted base repository (main branch) - this is safe
117
+ - name: Checkout base repository
118
+ uses: actions/checkout@v4
119
+ with:
120
+ ref: main
121
+
122
+ - name: Set up Python
123
+ uses: actions/setup-python@v4
124
+ with:
125
+ python-version: "3.10"
126
+
127
+ - name: Install dependencies from trusted main branch
128
+ run: |
129
+ python -m pip install --upgrade pip
130
+ pip install -e ".[quality]"
131
+ pip install --no-cache-dir --upgrade 'torch' 'torchaudio' 'torchvision' --index-url https://download.pytorch.org/whl/cpu
132
+
133
+ - name: Fetch and checkout PR code manually
134
+ env:
135
+ PR_HEAD_REPO_FULL_NAME: ${{ needs.get-pr-info.outputs.PR_HEAD_REPO_FULL_NAME }}
136
+ PR_HEAD_SHA: ${{ needs.check-timestamps.outputs.VERIFIED_PR_HEAD_SHA }}
137
+ run: |
138
+ # Create separate directory for PR code
139
+ mkdir -p pr-repo
140
+ cd pr-repo
141
+
142
+ # Initialize git and fetch only the specific commit
143
+ git init
144
+ git remote add pr-origin https://github.com/${PR_HEAD_REPO_FULL_NAME}.git
145
+ git fetch --depth=1 pr-origin ${PR_HEAD_SHA}
146
+ git checkout ${PR_HEAD_SHA}
147
+
148
+ - name: Run checks with trusted script
149
+ id: run_checks
150
+ run: |
151
+ # Copy trusted script to PR directory
152
+ cp utils/check_copies.py pr-repo/utils/check_copies.py
153
+
154
+ # Run the trusted script in PR directory
155
+ cd pr-repo
156
+ python utils/check_copies.py --fix_and_overwrite
157
+
158
+ # Check if there are changes
159
+ if [ -n "$(git status --porcelain)" ]; then
160
+ echo "changes_detected=true" >> $GITHUB_OUTPUT
161
+ else
162
+ echo "changes_detected=false" >> $GITHUB_OUTPUT
163
+ fi
164
+
165
+ - name: Save modified files
166
+ if: steps.run_checks.outputs.changes_detected == 'true'
167
+ run: |
168
+ cd pr-repo
169
+ mkdir -p ../artifact-staging
170
+ git diff --name-only > ../artifact-staging/modified-files.txt
171
+ # Copy each modified file
172
+ while IFS= read -r file; do
173
+ mkdir -p "../artifact-staging/pr-repo/$(dirname "$file")"
174
+ cp "$file" "../artifact-staging/pr-repo/$file"
175
+ done < ../artifact-staging/modified-files.txt
176
+
177
+ - name: Upload modified files
178
+ if: steps.run_checks.outputs.changes_detected == 'true'
179
+ uses: actions/upload-artifact@v4
180
+ with:
181
+ name: modified-files
182
+ path: artifact-staging/
183
+
184
+ commit-and-comment:
185
+ runs-on: ubuntu-22.04
186
+ needs: [get-pr-number, get-pr-info, check-timestamps, init_comment_with_url, run-repo-consistency-checks]
187
+ if: always()
188
+ permissions:
189
+ pull-requests: write
190
+ steps:
191
+ - name: Download modified files
192
+ if: needs.run-repo-consistency-checks.outputs.changes_detected == 'true'
193
+ uses: actions/download-artifact@v4
194
+ with:
195
+ name: modified-files
196
+
197
+ - name: Push changes via GitHub API (no checkout)
198
+ if: needs.run-repo-consistency-checks.outputs.changes_detected == 'true'
199
+ uses: actions/github-script@v6
200
+ env:
201
+ PR_HEAD_REF: ${{ needs.get-pr-info.outputs.PR_HEAD_REF }}
202
+ PR_HEAD_SHA: ${{ needs.check-timestamps.outputs.VERIFIED_PR_HEAD_SHA }}
203
+ PR_HEAD_REPO_OWNER: ${{ needs.get-pr-info.outputs.PR_HEAD_REPO_OWNER }}
204
+ PR_HEAD_REPO_NAME: ${{ needs.get-pr-info.outputs.PR_HEAD_REPO_NAME }}
205
+ with:
206
+ github-token: ${{ secrets.HF_STYLE_BOT_ACTION }}
207
+ script: |
208
+ const fs = require('fs');
209
+ const path = require('path');
210
+
211
+ const owner = process.env.PR_HEAD_REPO_OWNER;
212
+ const repo = process.env.PR_HEAD_REPO_NAME;
213
+ const baseSha = process.env.PR_HEAD_SHA;
214
+ const branch = process.env.PR_HEAD_REF;
215
+
216
+ console.log(`Creating commit on ${owner}/${repo} branch ${branch} from ${baseSha}`);
217
+
218
+ // Read list of modified files
219
+ const modifiedFiles = fs.readFileSync('modified-files.txt', 'utf8')
220
+ .trim()
221
+ .split('\n')
222
+ .filter(f => f.length > 0);
223
+
224
+ console.log(`Modified files: ${modifiedFiles.join(', ')}`);
225
+
226
+ // Get the base commit to retrieve its tree SHA (metadata only, no checkout)
227
+ const { data: baseCommit } = await github.rest.git.getCommit({
228
+ owner,
229
+ repo,
230
+ commit_sha: baseSha
231
+ });
232
+
233
+ console.log(`Base tree SHA: ${baseCommit.tree.sha}`);
234
+
235
+ // Create blobs for each modified file
236
+ const tree = [];
237
+ for (const file of modifiedFiles) {
238
+ const filePath = path.join('pr-repo', file);
239
+ const content = fs.readFileSync(filePath, 'utf8');
240
+
241
+ console.log(`Creating blob for ${file}`);
242
+ const { data: blob } = await github.rest.git.createBlob({
243
+ owner,
244
+ repo,
245
+ content: content,
246
+ encoding: 'utf-8'
247
+ });
248
+
249
+ tree.push({
250
+ path: file,
251
+ mode: '100644',
252
+ type: 'blob',
253
+ sha: blob.sha
254
+ });
255
+ }
256
+
257
+ // Create new tree based on the base tree
258
+ console.log(`Creating tree with ${tree.length} modified files`);
259
+ const { data: newTree } = await github.rest.git.createTree({
260
+ owner,
261
+ repo,
262
+ base_tree: baseCommit.tree.sha,
263
+ tree: tree
264
+ });
265
+
266
+ // Create commit
267
+ console.log(`Creating commit`);
268
+ const { data: newCommit } = await github.rest.git.createCommit({
269
+ owner,
270
+ repo,
271
+ message: 'Apply repo. consistency fixes',
272
+ tree: newTree.sha,
273
+ parents: [baseSha]
274
+ });
275
+
276
+ console.log(`Created commit: ${newCommit.sha}`);
277
+
278
+ // Update branch ref
279
+ console.log(`Updating ref heads/${branch} to ${newCommit.sha}`);
280
+ await github.rest.git.updateRef({
281
+ owner,
282
+ repo,
283
+ ref: `heads/${branch}`,
284
+ sha: newCommit.sha
285
+ });
286
+
287
+ console.log(`Successfully pushed commit to ${branch}`);
288
+
289
+ - name: Prepare final comment message
290
+ id: prepare_final_comment
291
+ if: needs.init_comment_with_url.result == 'success'
292
+ env:
293
+ CHANGES_DETECTED: ${{ needs.run-repo-consistency-checks.outputs.changes_detected }}
294
+ run: |
295
+ if [ "$CHANGES_DETECTED" = 'true' ]; then
296
+ echo "final_comment=Repo. Consistency bot fixed some files and pushed the changes." >> $GITHUB_OUTPUT
297
+ else
298
+ echo "final_comment=Repo. Consistency fix runs successfully without any file modified." >> $GITHUB_OUTPUT
299
+ fi
300
+
301
+ - name: Comment on PR
302
+ if: needs.init_comment_with_url.result == 'success'
303
+ uses: actions/github-script@v6
304
+ env:
305
+ PR_NUMBER: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
306
+ with:
307
+ script: |
308
+ const PR_NUMBER = parseInt(process.env.PR_NUMBER, 10);
309
+ await github.rest.issues.updateComment({
310
+ owner: context.repo.owner,
311
+ repo: context.repo.repo,
312
+ comment_id: ${{ needs.init_comment_with_url.outputs.comment_id }},
313
+ body: `${{ steps.prepare_final_comment.outputs.final_comment }}`
314
+ });
.github/workflows/pr-style-bot.yml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # To run this bot, comment "@bot /style" on a PR
2
+ name: Style Bot
3
+
4
+ on:
5
+ issue_comment:
6
+ types: [created]
7
+
8
+ permissions:
9
+ pull-requests: write
10
+
11
+ jobs:
12
+ style:
13
+ uses: huggingface/huggingface_hub/.github/workflows/style-bot-action.yml@main
14
+ with:
15
+ python_quality_dependencies: "[quality]"
16
+ style_command_type: "default"
17
+ secrets:
18
+ bot_token: ${{ secrets.HF_STYLE_BOT_ACTION }}
.github/workflows/pr_build_doc_with_comment.yml ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: PR - build doc via comment
2
+ on:
3
+ issue_comment:
4
+ types:
5
+ - created
6
+ branches-ignore:
7
+ - main
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.event.issue.number }}-${{ startsWith(github.event.comment.body, 'build-doc') }}
10
+ cancel-in-progress: true
11
+ permissions: {}
12
+
13
+
14
+ jobs:
15
+ get-pr-number:
16
+ name: Get PR number
17
+ if: ${{ github.event.issue.state == 'open' && contains(fromJSON('["ydshieh", "ArthurZucker", "zucchini-nlp", "molbap", "gante", "LysandreJik", "Cyrilvallez", "Rocketknight1", "SunMarc", "eustlb", "MekkCyber", "vasqu", "ivarflakstad", "stevhliu", "ebezzam", "itazap"]'), github.actor) && (startsWith(github.event.comment.body, 'build-doc')) }}
18
+ uses: ./.github/workflows/get-pr-number.yml
19
+
20
+ get-pr-info:
21
+ name: Get PR commit SHA
22
+ needs: get-pr-number
23
+ if: ${{ needs.get-pr-number.outputs.PR_NUMBER != ''}}
24
+ uses: ./.github/workflows/get-pr-info.yml
25
+ with:
26
+ pr_number: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
27
+
28
+ verity_pr_commit:
29
+ name: Verity PR commit corresponds to a specific event by comparing timestamps
30
+ if: ${{ needs.get-pr-number.outputs.PR_NUMBER != ''}}
31
+ runs-on: ubuntu-22.04
32
+ needs: get-pr-info
33
+ env:
34
+ COMMENT_DATE: ${{ github.event.comment.created_at }}
35
+ PR_MERGE_COMMIT_DATE: ${{ needs.get-pr-info.outputs.PR_MERGE_COMMIT_DATE }}
36
+ PR_MERGE_COMMIT_TIMESTAMP: ${{ needs.get-pr-info.outputs.PR_MERGE_COMMIT_TIMESTAMP }}
37
+ steps:
38
+ - run: |
39
+ COMMENT_TIMESTAMP=$(date -d "${COMMENT_DATE}" +"%s")
40
+ echo "COMMENT_DATE: $COMMENT_DATE"
41
+ echo "PR_MERGE_COMMIT_DATE: $PR_MERGE_COMMIT_DATE"
42
+ echo "COMMENT_TIMESTAMP: $COMMENT_TIMESTAMP"
43
+ echo "PR_MERGE_COMMIT_TIMESTAMP: $PR_MERGE_COMMIT_TIMESTAMP"
44
+ if [ $COMMENT_TIMESTAMP -le $PR_MERGE_COMMIT_TIMESTAMP ]; then
45
+ echo "Last commit on the pull request is newer than the issue comment triggering this run! Abort!";
46
+ exit -1;
47
+ fi
48
+
49
+ create_run:
50
+ name: Create run
51
+ needs: [get-pr-number, get-pr-info]
52
+ if: ${{ needs.get-pr-number.outputs.PR_NUMBER != '' }}
53
+ permissions:
54
+ statuses: write
55
+ runs-on: ubuntu-22.04
56
+ steps:
57
+ - name: Create Run
58
+ id: create_run
59
+ env:
60
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61
+ # Create a commit status (pending) for a run of this workflow. The status has to be updated later in `update_run_status`.
62
+ # See https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#create-a-commit-status
63
+ GITHUB_RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
64
+ run: |
65
+ gh api \
66
+ --method POST \
67
+ -H "Accept: application/vnd.github+json" \
68
+ -H "X-GitHub-Api-Version: 2022-11-28" \
69
+ repos/${{ github.repository }}/statuses/${{ needs.get-pr-info.outputs.PR_HEAD_SHA }} \
70
+ -f "target_url=$GITHUB_RUN_URL" -f "state=pending" -f "description=Custom doc building job" -f "context=custom-doc-build"
71
+
72
+ reply_to_comment:
73
+ name: Reply to the comment
74
+ if: ${{ needs.create_run.result == 'success' }}
75
+ needs: [get-pr-number, create_run]
76
+ permissions:
77
+ pull-requests: write
78
+ runs-on: ubuntu-22.04
79
+ steps:
80
+ - name: Reply to the comment
81
+ env:
82
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83
+ GITHUB_RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
84
+ run: |
85
+ gh api \
86
+ --method POST \
87
+ -H "Accept: application/vnd.github+json" \
88
+ -H "X-GitHub-Api-Version: 2022-11-28" \
89
+ repos/${{ github.repository }}/issues/${{ needs.get-pr-number.outputs.PR_NUMBER }}/comments \
90
+ -f "body=[Building docs for all languages...](${{ env.GITHUB_RUN_URL }})"
91
+
92
+ build-doc:
93
+ name: Build doc
94
+ needs: [get-pr-number, get-pr-info]
95
+ if: ${{ needs.get-pr-number.outputs.PR_NUMBER != '' }}
96
+ uses: huggingface/doc-builder/.github/workflows/build_pr_documentation.yml@main
97
+ with:
98
+ commit_sha: ${{ needs.get-pr-info.outputs.PR_HEAD_SHA }}
99
+ pr_number: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
100
+ package: transformers
101
+ languages: ar de en es fr hi it ja ko pt zh
102
+
103
+ update_run_status:
104
+ name: Update Check Run Status
105
+ needs: [ get-pr-info, create_run, build-doc ]
106
+ permissions:
107
+ statuses: write
108
+ if: ${{ always() && needs.create_run.result == 'success' }}
109
+ runs-on: ubuntu-22.04
110
+ env:
111
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
112
+ GITHUB_RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
113
+ STATUS_OK: ${{ contains(fromJSON('["skipped", "success"]'), needs.build-doc.result) }}
114
+ steps:
115
+ - name: Get `build-doc` job status
116
+ run: |
117
+ echo "${{ needs.build-doc.result }}"
118
+ echo $STATUS_OK
119
+ if [ "$STATUS_OK" = "true" ]; then
120
+ echo "STATUS=success" >> $GITHUB_ENV
121
+ else
122
+ echo "STATUS=failure" >> $GITHUB_ENV
123
+ fi
124
+
125
+ - name: Update PR commit statuses
126
+ run: |
127
+ echo "${{ needs.build-doc.result }}"
128
+ echo "${{ env.STATUS }}"
129
+ gh api \
130
+ --method POST \
131
+ -H "Accept: application/vnd.github+json" \
132
+ -H "X-GitHub-Api-Version: 2022-11-28" \
133
+ repos/${{ github.repository }}/statuses/${{ needs.get-pr-info.outputs.PR_HEAD_SHA }} \
134
+ -f "target_url=$GITHUB_RUN_URL" -f "state=${{ env.STATUS }}" -f "description=Custom doc building job" -f "context=custom-doc-build"
.github/workflows/pr_slow_ci_suggestion.yml ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: PR slow CI - Suggestion
2
+ on:
3
+ pull_request_target:
4
+ types: [opened, synchronize, reopened]
5
+
6
+ jobs:
7
+ get-pr-number:
8
+ name: Get PR number
9
+ uses: ./.github/workflows/get-pr-number.yml
10
+
11
+ get-pr-info:
12
+ name: Get PR commit SHA
13
+ needs: get-pr-number
14
+ if: ${{ needs.get-pr-number.outputs.PR_NUMBER != ''}}
15
+ uses: ./.github/workflows/get-pr-info.yml
16
+ with:
17
+ pr_number: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
18
+
19
+ get-jobs:
20
+ name: Get test files to run
21
+ runs-on: ubuntu-22.04
22
+ needs: [get-pr-number, get-pr-info]
23
+ outputs:
24
+ jobs: ${{ steps.get_jobs.outputs.jobs_to_run }}
25
+ steps:
26
+ # This checkout to the main branch
27
+ - uses: actions/checkout@v4
28
+ with:
29
+ fetch-depth: "0"
30
+
31
+ # We need to use `${{ ... }}` here to avoid `Argument list too long` error when a PR changes a lot of files.
32
+ # (We could also try to use artifact approach, but it's more involved).
33
+ # `CodeQL` doesn't identify any security issue here. Also `PR_FILES` is from `get-pr-info.yml` by using an api
34
+ # `github.rest.pulls.listFiles`, which is fine.
35
+ - name: Write pr_files file
36
+ run: |
37
+ cat > pr_files.txt << 'EOF'
38
+ ${{ needs.get-pr-info.outputs.PR_FILES }}
39
+ EOF
40
+
41
+ - name: Get repository content
42
+ id: repo_content
43
+ uses: actions/github-script@v6
44
+ with:
45
+ script: |
46
+ const fs = require('node:fs');
47
+
48
+ const { data: tests_dir } = await github.rest.repos.getContent({
49
+ owner: '${{ needs.get-pr-info.outputs.PR_HEAD_REPO_OWNER }}',
50
+ repo: '${{ needs.get-pr-info.outputs.PR_HEAD_REPO_NAME }}',
51
+ path: 'tests',
52
+ ref: '${{ needs.get-pr-info.outputs.PR_HEAD_SHA }}',
53
+ });
54
+
55
+ const { data: tests_models_dir } = await github.rest.repos.getContent({
56
+ owner: '${{ needs.get-pr-info.outputs.PR_HEAD_REPO_OWNER }}',
57
+ repo: '${{ needs.get-pr-info.outputs.PR_HEAD_REPO_NAME }}',
58
+ path: 'tests/models',
59
+ ref: '${{ needs.get-pr-info.outputs.PR_HEAD_SHA }}',
60
+ });
61
+
62
+ const { data: tests_quantization_dir } = await github.rest.repos.getContent({
63
+ owner: '${{ needs.get-pr-info.outputs.PR_HEAD_REPO_OWNER }}',
64
+ repo: '${{ needs.get-pr-info.outputs.PR_HEAD_REPO_NAME }}',
65
+ path: 'tests/quantization',
66
+ ref: '${{ needs.get-pr-info.outputs.PR_HEAD_SHA }}',
67
+ });
68
+
69
+ // Write to files instead of outputs
70
+ fs.writeFileSync('tests_dir.txt', JSON.stringify(tests_dir, null, 2));
71
+ fs.writeFileSync('tests_models_dir.txt', JSON.stringify(tests_models_dir, null, 2));
72
+ fs.writeFileSync('tests_quantization_dir.txt', JSON.stringify(tests_quantization_dir, null, 2));
73
+
74
+ - name: Run script to get jobs to run
75
+ id: get_jobs
76
+ run: |
77
+ python utils/get_pr_run_slow_jobs.py | tee output.txt
78
+ echo "jobs_to_run: $(tail -n 1 output.txt)"
79
+ echo "jobs_to_run=$(tail -n 1 output.txt)" >> $GITHUB_OUTPUT
80
+
81
+ send_comment:
82
+ # Will delete the previous comment and send a new one if:
83
+ # - either the content is changed
84
+ # - or the previous comment is 30 minutes or more old
85
+ name: Send a comment to suggest jobs to run
86
+ if: ${{ needs.get-jobs.outputs.jobs != '' }}
87
+ needs: [get-pr-number, get-jobs]
88
+ permissions:
89
+ pull-requests: write
90
+ runs-on: ubuntu-22.04
91
+ steps:
92
+ - name: Check and update comment if needed
93
+ uses: actions/github-script@v7
94
+ env:
95
+ BODY: "\n\nrun-slow: ${{ needs.get-jobs.outputs.jobs }}"
96
+ with:
97
+ script: |
98
+ const prNumber = ${{ needs.get-pr-number.outputs.PR_NUMBER }};
99
+ const commentPrefix = "**[For maintainers]** Suggested jobs to run (before merge)";
100
+ const thirtyMinutesAgo = new Date(Date.now() - 30 * 60 * 1000); // 30 minutes ago
101
+ const newBody = `${commentPrefix}${process.env.BODY}`;
102
+
103
+ // Get all comments on the PR
104
+ const { data: comments } = await github.rest.issues.listComments({
105
+ owner: context.repo.owner,
106
+ repo: context.repo.repo,
107
+ issue_number: prNumber
108
+ });
109
+
110
+ // Find existing comments that start with our prefix
111
+ const existingComments = comments.filter(comment =>
112
+ comment.user.login === 'github-actions[bot]' &&
113
+ comment.body.startsWith(commentPrefix)
114
+ );
115
+
116
+ let shouldCreateNewComment = true;
117
+ let commentsToDelete = [];
118
+
119
+ if (existingComments.length > 0) {
120
+ // Get the most recent comment
121
+ const mostRecentComment = existingComments
122
+ .sort((a, b) => new Date(b.created_at) - new Date(a.created_at))[0];
123
+
124
+ const commentDate = new Date(mostRecentComment.created_at);
125
+ const isOld = commentDate < thirtyMinutesAgo;
126
+ const isDifferentContent = mostRecentComment.body !== newBody;
127
+
128
+ console.log(`Most recent comment created: ${mostRecentComment.created_at}`);
129
+ console.log(`Is older than 30 minutes: ${isOld}`);
130
+ console.log(`Has different content: ${isDifferentContent}`);
131
+
132
+ if (isOld || isDifferentContent) {
133
+ // Delete all existing comments and create new one
134
+ commentsToDelete = existingComments;
135
+ console.log(`Will delete ${commentsToDelete.length} existing comment(s) and create new one`);
136
+ } else {
137
+ // Content is same and comment is recent, skip
138
+ shouldCreateNewComment = false;
139
+ console.log('Comment is recent and content unchanged, skipping update');
140
+ }
141
+ } else {
142
+ console.log('No existing comments found, will create new one');
143
+ }
144
+
145
+ // Delete old comments if needed
146
+ for (const comment of commentsToDelete) {
147
+ console.log(`Deleting comment #${comment.id} (created: ${comment.created_at})`);
148
+ await github.rest.issues.deleteComment({
149
+ owner: context.repo.owner,
150
+ repo: context.repo.repo,
151
+ comment_id: comment.id
152
+ });
153
+ }
154
+
155
+ // Create new comment if needed
156
+ if (shouldCreateNewComment) {
157
+ await github.rest.issues.createComment({
158
+ owner: context.repo.owner,
159
+ repo: context.repo.repo,
160
+ issue_number: prNumber,
161
+ body: newBody
162
+ });
163
+ console.log('✅ New comment created');
164
+ } else {
165
+ console.log('ℹ️ No comment update needed');
166
+ }
.github/workflows/push-important-models.yml ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Slow tests on important models (on Push - A10)
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+
7
+ jobs:
8
+ get_modified_models:
9
+ name: "Get all modified files"
10
+ runs-on: ubuntu-latest
11
+ outputs:
12
+ matrix: ${{ steps.set-matrix.outputs.matrix }}
13
+ steps:
14
+ - name: Check out code
15
+ uses: actions/checkout@v4
16
+
17
+ - name: Get changed files using `actions/github-script`
18
+ id: get-changed-files
19
+ uses: actions/github-script@v7
20
+ with:
21
+ script: |
22
+ let files = [];
23
+
24
+ // Only handle push events
25
+ if (context.eventName === 'push') {
26
+ const afterSha = context.payload.after;
27
+ const branchName = context.payload.ref.replace('refs/heads/', '');
28
+
29
+ let baseSha;
30
+
31
+ if (branchName === 'main') {
32
+ console.log('Push to main branch, comparing to parent commit');
33
+ // Get the parent commit of the pushed commit
34
+ const { data: commit } = await github.rest.repos.getCommit({
35
+ owner: context.repo.owner,
36
+ repo: context.repo.repo,
37
+ ref: afterSha
38
+ });
39
+ baseSha = commit.parents[0]?.sha;
40
+ if (!baseSha) {
41
+ throw new Error('No parent commit found for the pushed commit');
42
+ }
43
+ } else {
44
+ console.log(`Push to branch ${branchName}, comparing to main`);
45
+ baseSha = 'main';
46
+ }
47
+
48
+ const { data: comparison } = await github.rest.repos.compareCommits({
49
+ owner: context.repo.owner,
50
+ repo: context.repo.repo,
51
+ base: baseSha,
52
+ head: afterSha
53
+ });
54
+
55
+ // Include added, modified, and renamed files
56
+ files = comparison.files
57
+ .filter(file => file.status === 'added' || file.status === 'modified' || file.status === 'renamed')
58
+ .map(file => file.filename);
59
+ }
60
+
61
+ // Include all files under src/transformers/ (not just models subdirectory)
62
+ const filteredFiles = files.filter(file =>
63
+ file.startsWith('src/transformers/')
64
+ );
65
+
66
+ core.setOutput('changed_files', filteredFiles.join(' '));
67
+ core.setOutput('any_changed', filteredFiles.length > 0 ? 'true' : 'false');
68
+
69
+ - name: Parse changed files with Python
70
+ if: steps.get-changed-files.outputs.any_changed == 'true'
71
+ env:
72
+ CHANGED_FILES: ${{ steps.get-changed-files.outputs.changed_files }}
73
+ id: set-matrix
74
+ run: |
75
+ python3 - << 'EOF'
76
+ import os
77
+ import sys
78
+ import json
79
+
80
+ # Add the utils directory to Python path
81
+ sys.path.insert(0, 'utils')
82
+
83
+ # Import the important models list
84
+ from important_files import IMPORTANT_MODELS
85
+
86
+ print(f"Important models: {IMPORTANT_MODELS}")
87
+
88
+ # Get the changed files from the previous step
89
+ changed_files_str = os.environ.get('CHANGED_FILES', '')
90
+ changed_files = changed_files_str.split() if changed_files_str else []
91
+
92
+ # Filter to only Python files
93
+ python_files = [f for f in changed_files if f.endswith('.py')]
94
+ print(f"Python files changed: {python_files}")
95
+
96
+ result_models = set()
97
+
98
+ # Specific files that trigger all models
99
+ transformers_utils_files = [
100
+ 'modeling_utils.py',
101
+ 'modeling_rope_utils.py',
102
+ 'modeling_flash_attention_utils.py',
103
+ 'modeling_attn_mask_utils.py',
104
+ 'cache_utils.py',
105
+ 'masking_utils.py',
106
+ 'pytorch_utils.py'
107
+ ]
108
+
109
+ # Single loop through all Python files
110
+ for file in python_files:
111
+ # Check for files under src/transformers/models/
112
+ if file.startswith('src/transformers/models/'):
113
+ remaining_path = file[len('src/transformers/models/'):]
114
+ if '/' in remaining_path:
115
+ model_dir = remaining_path.split('/')[0]
116
+ if model_dir in IMPORTANT_MODELS:
117
+ result_models.add(model_dir)
118
+ print(f"Added model directory: {model_dir}")
119
+
120
+ # Check for specific files under src/transformers/ or src/transformers/generation/ files
121
+ elif file.startswith('src/transformers/generation/') or \
122
+ (file.startswith('src/transformers/') and os.path.basename(file) in transformers_utils_files):
123
+ print(f"Found core file: {file} - including all important models")
124
+ result_models.update(IMPORTANT_MODELS)
125
+ break # No need to continue once we include all models
126
+
127
+ # Convert to sorted list and create matrix
128
+ result_list = sorted(list(result_models))
129
+ print(f"Final model list: {result_list}")
130
+
131
+ if result_list:
132
+ matrix_json = json.dumps(result_list)
133
+ print(f"matrix={matrix_json}")
134
+
135
+ # Write to GITHUB_OUTPUT
136
+ with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
137
+ f.write(f"matrix={matrix_json}\n")
138
+ else:
139
+ print("matrix=[]")
140
+ with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
141
+ f.write("matrix=[]\n")
142
+ EOF
143
+
144
+ model-ci:
145
+ name: Model CI
146
+ uses: ./.github/workflows/self-scheduled.yml
147
+ needs: get_modified_models
148
+ if: needs.get_modified_models.outputs.matrix != '' && needs.get_modified_models.outputs.matrix != '[]'
149
+ with:
150
+ job: run_models_gpu
151
+ slack_report_channel: "#transformers-ci-push"
152
+ docker: huggingface/transformers-all-latest-gpu:flash-attn
153
+ ci_event: push
154
+ report_repo_id: hf-internal-testing/transformers_ci_push
155
+ commit_sha: ${{ github.sha }}
156
+ subdirs: ${{ needs.get_modified_models.outputs.matrix }}
157
+ secrets: inherit
.github/workflows/release-conda.yml ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Release - Conda
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v*
7
+ branches:
8
+ - conda_*
9
+
10
+ env:
11
+ ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }}
12
+
13
+ jobs:
14
+ build_and_package:
15
+ runs-on: ubuntu-22.04
16
+ defaults:
17
+ run:
18
+ shell: bash -l {0}
19
+
20
+ steps:
21
+ - name: Checkout repository
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Install miniconda
25
+ uses: conda-incubator/setup-miniconda@v2
26
+ with:
27
+ auto-update-conda: true
28
+ auto-activate-base: false
29
+ python-version: 3.8
30
+ activate-environment: "build-transformers"
31
+ channels: huggingface
32
+
33
+ - name: Setup conda env
34
+ run: |
35
+ conda install -c defaults anaconda-client conda-build
36
+
37
+ - name: Extract version
38
+ run: echo "TRANSFORMERS_VERSION=`python setup.py --version`" >> $GITHUB_ENV
39
+
40
+ - name: Build conda packages
41
+ run: |
42
+ conda info
43
+ conda list
44
+ conda-build .github/conda
45
+
46
+ - name: Upload to Anaconda
47
+ run: anaconda upload `conda-build .github/conda --output` --force
.github/workflows/release.yml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Release
2
+ on:
3
+ push:
4
+ tags:
5
+ - v*
6
+ branches:
7
+ - 'v*-release'
8
+
9
+ jobs:
10
+ build_and_test:
11
+ name: build release
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: set up python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.13"
20
+
21
+ - run: pip install setuptools
22
+ - run: pip install -e .
23
+ - run: make build-release
24
+
25
+ - run: pip uninstall -y transformers
26
+ - run: pip install dist/*.whl
27
+
28
+ - run: python -c "from transformers import *"
29
+
30
+ - run: pip install -e .[torch]
31
+ - run: python -c "from transformers import pipeline; classifier = pipeline('text-classification'); assert classifier('What a nice release')[0]['score'] > 0"
32
+
33
+ - name: Upload build artifacts
34
+ uses: actions/upload-artifact@v4
35
+ with:
36
+ name: python-dist
37
+ path: |
38
+ dist/**
39
+ build/**
40
+
41
+ upload_package:
42
+ needs: build_and_test
43
+ if: startsWith(github.ref, 'refs/tags/')
44
+ runs-on: ubuntu-latest
45
+ environment: pypi-release
46
+ permissions:
47
+ id-token: write
48
+
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - name: Download build artifacts
53
+ uses: actions/download-artifact@v4
54
+ with:
55
+ name: python-dist
56
+ path: .
57
+
58
+ - name: Publish package distributions to TestPyPI
59
+ uses: pypa/gh-action-pypi-publish@release/v1
60
+