Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .circleci/TROUBLESHOOT.md +7 -0
- .circleci/config.yml +232 -0
- .circleci/create_circleci_config.py +412 -0
- .circleci/parse_test_outputs.py +71 -0
- .gitattributes +11 -35
- .github/ISSUE_TEMPLATE/bug-report.yml +126 -0
- .github/ISSUE_TEMPLATE/config.yml +12 -0
- .github/ISSUE_TEMPLATE/feature-request.yml +31 -0
- .github/ISSUE_TEMPLATE/i18n.md +46 -0
- .github/ISSUE_TEMPLATE/migration.yml +72 -0
- .github/ISSUE_TEMPLATE/new-model-addition.yml +31 -0
- .github/PULL_REQUEST_TEMPLATE.md +78 -0
- .github/conda/build.sh +1 -0
- .github/conda/meta.yaml +56 -0
- .github/copilot-instructions.md +39 -0
- .github/scripts/assign_reviewers.py +122 -0
- .github/scripts/codeowners_for_review_action +369 -0
- .github/workflows/TROUBLESHOOT.md +9 -0
- .github/workflows/add-model-like.yml +80 -0
- .github/workflows/assign-reviewers.yml +26 -0
- .github/workflows/benchmark.yml +61 -0
- .github/workflows/benchmark_v2.yml +57 -0
- .github/workflows/benchmark_v2_a10_caller.yml +17 -0
- .github/workflows/benchmark_v2_mi325_caller.yml +17 -0
- .github/workflows/build-ci-docker-images.yml +77 -0
- .github/workflows/build-docker-images.yml +304 -0
- .github/workflows/build-nightly-ci-docker-images.yml +73 -0
- .github/workflows/build-past-ci-docker-images.yml +101 -0
- .github/workflows/build_documentation.yml +35 -0
- .github/workflows/build_pr_documentation.yml +17 -0
- .github/workflows/check-workflow-permissions.yml +23 -0
- .github/workflows/check_failed_tests.yml +325 -0
- .github/workflows/check_tiny_models.yml +82 -0
- .github/workflows/circleci-failure-summary-comment.yml +245 -0
- .github/workflows/codeql.yml +23 -0
- .github/workflows/collated-reports.yml +43 -0
- .github/workflows/doctest_job.yml +82 -0
- .github/workflows/doctests.yml +89 -0
- .github/workflows/get-pr-info.yml +167 -0
- .github/workflows/get-pr-number.yml +42 -0
- .github/workflows/model_jobs.yml +207 -0
- .github/workflows/model_jobs_intel_gaudi.yml +120 -0
- .github/workflows/new_model_pr_merged_notification.yml +68 -0
- .github/workflows/pr-repo-consistency-bot.yml +314 -0
- .github/workflows/pr-style-bot.yml +18 -0
- .github/workflows/pr_build_doc_with_comment.yml +134 -0
- .github/workflows/pr_slow_ci_suggestion.yml +166 -0
- .github/workflows/push-important-models.yml +157 -0
- .github/workflows/release-conda.yml +47 -0
- .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 |
-
*.
|
| 2 |
-
*.
|
| 3 |
-
*.
|
| 4 |
-
*.
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 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 |
+
|