mirror of
https://github.com/huggingface/transformers.git
synced 2025-07-05 22:00:09 +06:00

* Adapt FE methods to transforms library * Mixin for saving the image processor * Base processor skeleton * BatchFeature for packaging image processor outputs * Initial image processor for GLPN * REmove accidental import * Fixup and docs * Mixin for saving the image processor * Fixup and docs * Import BatchFeature from feature_extraction_utils * Fixup and docs * Fixup and docs * Fixup and docs * Fixup and docs * BatchFeature for packaging image processor outputs * Import BatchFeature from feature_extraction_utils * Import BatchFeature from feature_extraction_utils * Fixup and docs * Fixup and docs * BatchFeature for packaging image processor outputs * Import BatchFeature from feature_extraction_utils * Fixup and docs * Mixin for saving the image processor * Fixup and docs * Add rescale back and remove ImageType * fix import mistake * Fix enum var reference * Can transform and specify image data format * Remove redundant function * Update reference * Data format flag for rescale * Fix typo * Fix dimension check * Fixes to make IP and FE outputs match * Add tests for transforms * Add test for utils * Update some docstrings * Make sure in channels last before converting to PIL * Remove default to numpy batching * Fix up * Add docstring and model_input_types * Use feature processor config from hub * Alias GLPN feature extractor to image processor * Alias feature extractor mixin * Add return_numpy=False flag for resize * Fix up * Fix up * Use different frameworks safely * Safely import PIL * Call function checking if PIL available * Only import if vision available * Address Sylvain PR comments Co-authored-by: Sylvain.gugger@gmail.com * Apply suggestions from code review Co-authored-by: Sylvain Gugger <Sylvain.gugger@gmail.com> Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Update src/transformers/image_transforms.py Co-authored-by: Alara Dirik <8944735+alaradirik@users.noreply.github.com> * Update src/transformers/models/glpn/feature_extraction_glpn.py Co-authored-by: NielsRogge <48327001+NielsRogge@users.noreply.github.com> * Add in docstrings * Fix TFSwinSelfAttention to have relative position index as non-trainable weight (#18226) Signed-off-by: Seunghwan Hong <seunghwan@scatterlab.co.kr> * Refactor `TFSwinLayer` to increase serving compatibility (#18352) * Refactor `TFSwinLayer` to increase serving compatibility Signed-off-by: Seunghwan Hong <seunghwan@scatterlab.co.kr> * Fix missed parameters while refactoring Signed-off-by: Seunghwan Hong <seunghwan@scatterlab.co.kr> * Fix window_reverse to calculate batch size Signed-off-by: Seunghwan Hong <harrydrippin@gmail.com> Co-Authored-By: amyeroberts <22614925+amyeroberts@users.noreply.github.com> Co-authored-by: amyeroberts <22614925+amyeroberts@users.noreply.github.com> * Add TF prefix to TF-Res test class (#18481) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Remove py.typed (#18485) * Fix pipeline tests (#18487) * Fix pipeline tests * Make sure all pipelines tests run with init changes * Use new huggingface_hub tools for download models (#18438) * Draft new cached_file * Initial draft for config and model * Small fixes * Fix first batch of tests * Look in cache when internet is down * Fix last tests * Bad black, not fixing all quality errors * Make diff less * Implement change for TF and Flax models * Add tokenizer and feature extractor * For compatibility with main * Add utils to move the cache and auto-do it at first use. * Quality * Deal with empty commit shas * Deal with empty etag * Address review comments * Fix `test_dbmdz_english` by updating expected values (#18482) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Move cache folder to huggingface/hub for consistency with hf_hub (#18492) * Move cache folder to just huggingface * Thank you VsCode for this needless import * Move to hub * Forgot one * Update some expected values in `quicktour.mdx` for `resampy 0.3.0` (#18484) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Forgot one new_ for cache migration * disable Onnx test for google/long-t5-tglobal-base (#18454) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Typo reported by Joel Grus on TWTR (#18493) * Just re-reading the whole doc every couple of months 😬 (#18489) * Delete valohai.yaml * NLP => ML * typo * website supports https * datasets * 60k + modalities * unrelated link fixing for accelerate * Ok those links were actually broken * Fix link * Make `AutoTokenizer` auto-link * wording tweak * add at least one non-nlp task * `transformers-cli login` => `huggingface-cli login` (#18490) * zero chance anyone's using that constant no? * `transformers-cli login` => `huggingface-cli login` * `transformers-cli repo create` => `huggingface-cli repo create` * `make style` * Add seed setting to image classification example (#18519) * [DX fix] Fixing QA pipeline streaming a dataset. (#18516) * [DX fix] Fixing QA pipeline streaming a dataset. QuestionAnsweringArgumentHandler would iterate over the whole dataset effectively killing all properties of the pipeline. This restores nice properties when using `Dataset` or `Generator` since those are meant to be consumed lazily. * Handling TF better. * Clean up hub (#18497) * Clean up utils.hub * Remove imports * More fixes * Last fix * update fsdp docs (#18521) * updating fsdp documentation * typo fix * Fix compatibility with 1.12 (#17925) * Fix compatibility with 1.12 * Remove pin from examples requirements * Update torch scatter version * Fix compatibility with 1.12 * Remove pin from examples requirements * Update torch scatter version * fix torch.onnx.symbolic_opset12 import * Reject bad version Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Remove debug statement * Specify en in doc-builder README example (#18526) Co-authored-by: Ankur Goyal <ankur@impira.com> * New cache fixes: add safeguard before looking in folders (#18522) * unpin resampy (#18527) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * ✨ update to use interlibrary links instead of Markdown (#18500) * Add example of multimodal usage to pipeline tutorial (#18498) * 📝 add example of multimodal usage to pipeline tutorial * 🖍 apply feedbacks * 🖍 apply niels feedback * [VideoMAE] Add model to doc tests (#18523) * Add videomae to doc tests * Add pip install decord Co-authored-by: Niels Rogge <nielsrogge@Nielss-MacBook-Pro.local> * Update perf_train_gpu_one.mdx (#18532) * Update no_trainer.py scripts to include accelerate gradient accumulation wrapper (#18473) * Added accelerate gradient accumulation wrapper to run_image_classification_no_trainer.py example script * make fixup changes * PR comments * changed input to Acceletor based on PR comment, ran make fixup * Added comment explaining the sync_gradients statement * Fixed lr scheduler max steps * Changed run_clm_no_trainer.py script to use accelerate gradient accum wrapper * Fixed all scripts except wav2vec2 pretraining to use accelerate gradient accum wrapper * Added accelerate gradient accum wrapper for wav2vec2_pretraining_no_trainer.py script * make fixup and lr_scheduler step inserted back into run_qa_beam_search_no_trainer.py * removed changes to run_wav2vec2_pretraining_no_trainer.py script and fixed using wrong constant in qa_beam_search_no_trainer.py script * Add Spanish translation of converting_tensorflow_models.mdx (#18512) * Add file in spanish docs to be translated * Finish translation to Spanish * Improve Spanish wording * Add suggested changes from review * Spanish translation of summarization.mdx (#15947) (#18477) * Add Spanish translation of summarization.mdx * Apply suggestions from code review Co-authored-by: Omar U. Espejel <espejelomar@gmail.com> Co-authored-by: Omar U. Espejel <espejelomar@gmail.com> * Let's not cast them all (#18471) * add correct dtypes when checking for params dtype * forward contrib credits * Update src/transformers/modeling_utils.py Co-authored-by: Thomas Wang <24695242+thomasw21@users.noreply.github.com> * more comments - added more comments on why we cast only floating point parameters * Update src/transformers/modeling_utils.py Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> Co-authored-by: sgugger <35901082+sgugger@users.noreply.github.com> Co-authored-by: Thomas Wang <24695242+thomasw21@users.noreply.github.com> * fix: data2vec-vision Onnx ready-made configuration. (#18427) * feat: add the data2vec conf that are missing https://huggingface.co/docs/transformers/serialization * fix: wrong config * Add mt5 onnx config (#18394) * update features * MT5OnnxConfig added with updated with tests and docs * fix imports * fix onnc_config_cls for mt5 Co-authored-by: Thomas Chaigneau <thomas.deeptools.ai> * Minor update of `run_call_with_unpacked_inputs` (#18541) Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * BART - Fix attention mask device issue on copied models (#18540) * attempt to fix attn mask device * fix bart `_prepare_decoder_attention_mask` - add correct device - run `make fix-copies` to propagate the fix * Adding a new `align_to_words` param to qa pipeline. (#18010) * Adding a new `align_to_words` param to qa pipeline. * Update src/transformers/pipelines/question_answering.py Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Import protection. Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * 📝 update metric with evaluate (#18535) * Restore _init_weights value in no_init_weights (#18504) * Recover _init_weights value in no_init_weights For potential nested use. In addition, users might modify private no_init_weights as well. * Apply suggestions from code review Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Remove private variable change check Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Clean up comment * 📝 update documentation build section (#18548) * `bitsandbytes` - `Linear8bitLt` integration into `transformers` models (#17901) * first commit * correct replace function * add final changes - works like charm! - cannot implement tests yet - tested * clean up a bit * add bitsandbytes dependencies * working version - added import function - added bitsandbytes utils file * small fix * small fix - fix import issue * fix import issues * Apply suggestions from code review Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * refactor a bit - move bitsandbytes utils to utils - change comments on functions * reformat docstring - reformat docstring on init_empty_weights_8bit * Update src/transformers/__init__.py Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * revert bad formatting * change to bitsandbytes * refactor a bit - remove init8bit since it is useless * more refactoring - fixed init empty weights issue - added threshold param * small hack to make it work * Update src/transformers/modeling_utils.py * Update src/transformers/modeling_utils.py * revmoe the small hack * modify utils file * make style + refactor a bit * create correctly device map * add correct dtype for device map creation * Apply suggestions from code review Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * apply suggestions - remove with torch.grad - do not rely on Python bool magic! * add docstring - add docstring for new kwargs * add docstring - comment `replace_8bit_linear` function - fix weird formatting * - added more documentation - added new utility function for memory footprint tracking - colab demo to add * few modifs - typo doc - force cast into float16 when load_in_8bit is enabled * added colab link * add test architecture + docstring a bit * refactor a bit testing class * make style + refactor a bit * enhance checks - add more checks - start writing saving test * clean up a bit * male style * add more details on doc * add more tests - still needs to fix 2 tests * replace by "or" - could not fix it from GitHub GUI Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * refactor a bit testing code + add readme * make style * fix import issue * Update src/transformers/modeling_utils.py Co-authored-by: Michael Benayoun <mickbenayoun@gmail.com> * add few comments * add more doctring + make style * more docstring * raise error when loaded in 8bit * make style * add warning if loaded on CPU * add small sanity check * fix small comment * add bitsandbytes on dockerfile * Improve documentation - improve documentation from comments * add few comments * slow tests pass on the VM but not on the CI VM * Fix merge conflict * make style * another test should pass on a multi gpu setup * fix bad import in testing file * Fix slow tests - remove dummy batches - no more CUDA illegal memory errors * odify dockerfile * Update docs/source/en/main_classes/model.mdx * Update Dockerfile * Update model.mdx * Update Dockerfile * Apply suggestions from code review * few modifications - lm head can stay on disk/cpu - change model name so that test pass * change test value - change test value to the correct output - torch bmm changed to baddmm in bloom modeling when merging * modify installation guidelines * Apply suggestions from code review Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * replace `n`by `name` * merge `load_in_8bit` and `low_cpu_mem_usage` * first try - keep the lm head in full precision * better check - check the attribute `base_model_prefix` instead of computing the number of parameters * added more tests * Update src/transformers/utils/bitsandbytes.py Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Merge branch 'integration-8bit' of https://github.com/younesbelkada/transformers into integration-8bit * improve documentation - fix typos for installation - change title in the documentation Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> Co-authored-by: Michael Benayoun <mickbenayoun@gmail.com> * TF: XLA-trainable DeBERTa v2 (#18546) * fix deberta issues * add different code paths for gpu and tpu * shorter gpu take along axis * Stable Dropout without tf cond * variable must be float * Preserve hub-related kwargs in AutoModel.from_pretrained (#18545) * Preserve hub-related kwargs in AutoModel.from_pretrained * Fix tests * Remove debug statement * TF Examples Rewrite (#18451) * Finished QA example * Dodge a merge conflict * Update text classification and LM examples * Update NER example * New Keras metrics WIP, fix NER example * Update NER example * Update MC, summarization and translation examples * Add XLA warnings when shapes are variable * Make sure batch_size is consistently scaled by num_replicas * Add PushToHubCallback to all models * Add docs links for KerasMetricCallback * Add docs links for prepare_tf_dataset and jit_compile * Correct inferred model names * Don't assume the dataset has 'lang' * Don't assume the dataset has 'lang' * Write metrics in text classification * Add 'framework' to TrainingArguments and TFTrainingArguments * Export metrics in all examples and add tests * Fix training args for Flax * Update command line args for translation test * make fixup * Fix accidentally running other tests in fp16 * Remove do_train/do_eval from run_clm.py * Remove do_train/do_eval from run_mlm.py * Add tensorflow tests to circleci * Fix circleci * Update examples/tensorflow/language-modeling/run_mlm.py Co-authored-by: Joao Gante <joaofranciscocardosogante@gmail.com> * Update examples/tensorflow/test_tensorflow_examples.py Co-authored-by: Joao Gante <joaofranciscocardosogante@gmail.com> * Update examples/tensorflow/translation/run_translation.py Co-authored-by: Joao Gante <joaofranciscocardosogante@gmail.com> * Update examples/tensorflow/token-classification/run_ner.py Co-authored-by: Joao Gante <joaofranciscocardosogante@gmail.com> * Fix save path for tests * Fix some model card kwargs * Explain the magical -1000 * Actually enable tests this time * Skip text classification PR until we fix shape inference * make fixup Co-authored-by: Joao Gante <joaofranciscocardosogante@gmail.com> * Use commit hash to look in cache instead of calling head (#18534) * Use commit hash to look in cache instead of calling head * Add tests * Add attr for local configs too * Stupid typos * Fix tests * Update src/transformers/utils/hub.py Co-authored-by: Julien Chaumond <julien@huggingface.co> * Address Julien's comments Co-authored-by: Julien Chaumond <julien@huggingface.co> * `pipeline` support for `device="mps"` (or any other string) (#18494) * `pipeline` support for `device="mps"` (or any other string) * Simplify `if` nesting * Update src/transformers/pipelines/base.py Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Fix? @sgugger * passing `attr=None` is not the same as not passing `attr` 🤯 Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Update philosophy to include other preprocessing classes (#18550) * 📝 update philosophy to include other preprocessing classes * 🖍 apply feedbacks * Properly move cache when it is not in default path (#18563) * Adds CLIP to models exportable with ONNX (#18515) * onnx config for clip * default opset as 14 * changes from the original repo * input values order fix * outputs fix * remove unused import * ran make fix-copies * black format * review comments: forward ref, import fix, model change revert, .to cleanup * make style * formatting fixes * revert groupvit * comment for cast to int32 * comment fix * make .T as .t() for onnx conversion * ran make fix-copies * remove unneeded comment Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * fix copies * remove comment Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * raise atol for MT5OnnxConfig (#18560) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * fix string (#18568) * Segformer TF: fix output size in documentation (#18572) * Segformer TF: fix output size in doc * Segformer pytorch: fix output size in doc Co-authored-by: Maxime Gardoni <maxime.gardoni@ecorobotix.com> * Fix resizing bug in OWL-ViT (#18573) * Fixes resizing bug in OWL-ViT * Defaults to square resize if size is set to an int * Sets do_center_crop default value to False * Fix LayoutLMv3 documentation (#17932) * fix typos * fix sequence_length docs of LayoutLMv3Model * delete trailing white spaces * fix layoutlmv3 docs more * apply make fixup & quality * change to two versions of input docstring * apply make fixup & quality * Skip broken tests * Change BartLearnedPositionalEmbedding's forward method signature to support Opacus training (#18486) * changing BartLearnedPositionalEmbedding forward signature and references to it * removing debugging dead code (thanks style checker) * blackened modeling_bart file * removing copy inconsistencies via make fix-copies * changing references to copied signatures in Bart variants * make fix-copies once more * using expand over repeat (thanks @michaelbenayoun) * expand instead of repeat for all model copies Co-authored-by: Daniel Jones <jonesdaniel@microsoft.com> * german docs translation (#18544) * Create _config.py * Create _toctree.yml * Create index.mdx not sure about "du / ihr" oder "sie" * Create quicktour.mdx * Update _toctree.yml * Update build_documentation.yml * Update build_pr_documentation.yml * fix build * Update index.mdx * Update quicktour.mdx * Create installation.mdx * Update _toctree.yml * Deberta V2: Fix critical trace warnings to allow ONNX export (#18272) * Fix critical trace warnings to allow ONNX export * Force input to `sqrt` to be float type * Cleanup code * Remove unused import statement * Update model sew * Small refactor Co-authored-by: Michael Benayoun <mickbenayoun@gmail.com> * Use broadcasting instead of repeat * Implement suggestion Co-authored-by: Michael Benayoun <mickbenayoun@gmail.com> * Match deberta v2 changes in sew_d * Improve code quality * Update code quality * Consistency of small refactor * Match changes in sew_d Co-authored-by: Michael Benayoun <mickbenayoun@gmail.com> * [FX] _generate_dummy_input supports audio-classification models for labels (#18580) * Support audio classification architectures for labels generation, as well as provides a flag to print warnings or not * Use ENV_VARS_TRUE_VALUES * Fix docstrings with last version of hf-doc-builder styler (#18581) * Fix docstrings with last version of hf-doc-builder styler * Remove empty Parameter block * Bump nbconvert from 6.0.1 to 6.3.0 in /examples/research_projects/lxmert (#18565) Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.0.1 to 6.3.0. - [Release notes](https://github.com/jupyter/nbconvert/releases) - [Commits](https://github.com/jupyter/nbconvert/compare/6.0.1...6.3.0) --- updated-dependencies: - dependency-name: nbconvert dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump nbconvert in /examples/research_projects/visual_bert (#18566) Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.0.1 to 6.3.0. - [Release notes](https://github.com/jupyter/nbconvert/releases) - [Commits](https://github.com/jupyter/nbconvert/compare/6.0.1...6.3.0) --- updated-dependencies: - dependency-name: nbconvert dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix owlvit tests, update docstring examples (#18586) * Return the permuted hidden states if return_dict=True (#18578) * Load sharded pt to flax (#18419) * initial commit * add small test * add cross pt tf flag to test * fix quality * style * update test with new repo * fix failing test * update * fix wrong param ordering * style * update based on review * update related to recent new caching mechanism * quality * Update based on review Co-authored-by: sgugger <sylvain.gugger@gmail.com> * quality and style * Update src/transformers/modeling_flax_utils.py Co-authored-by: sgugger <sylvain.gugger@gmail.com> Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Add type hints for ViLT models (#18577) * Add type hints for Vilt models * Add missing return type for TokenClassification class * update doc for perf_train_cpu_many, add intel mpi introduction (#18576) * update doc for perf_train_cpu_many, add mpi introduction Signed-off-by: Wang, Yi A <yi.a.wang@intel.com> * Update docs/source/en/perf_train_cpu_many.mdx Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Update docs/source/en/perf_train_cpu_many.mdx Signed-off-by: Wang, Yi A <yi.a.wang@intel.com> Signed-off-by: Wang, Yi A <yi.a.wang@intel.com> Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * typos (#18594) * FSDP bug fix for `load_state_dict` (#18596) * Add `TFAutoModelForSemanticSegmentation` to the main `__init__.py` (#18600) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Generate: validate `model_kwargs` (and catch typos in generate arguments) (#18261) * validate generate model_kwargs * generate tests -- not all models have an attn mask * Supporting seq2seq models for `bitsandbytes` integration (#18579) * Supporting seq2seq models for `bitsandbytes` integration - `bitsandbytes` integration supports now seq2seq models - check if a model has tied weights as an additional check * small modification - tie the weights before looking at tied weights! * Add Donut (#18488) * First draft * Improve script * Update script * Make conversion work * Add final_layer_norm attribute to Swin's config * Add DonutProcessor * Convert more models * Improve feature extractor and convert base models * Fix bug * Improve integration tests * Improve integration tests and add model to README * Add doc test * Add feature extractor to docs * Fix integration tests * Remove register_buffer * Fix toctree and add missing attribute * Add DonutSwin * Make conversion script work * Improve conversion script * Address comment * Fix bug * Fix another bug * Remove deprecated method from docs * Make Swin and Swinv2 untouched * Fix code examples * Fix processor * Update model_type to donut-swin * Add feature extractor tests, add token2json method, improve feature extractor * Fix failing tests, remove integration test * Add do_thumbnail for consistency * Improve code examples * Add code example for document parsing * Add DonutSwin to MODEL_NAMES_MAPPING * Add model to appropriate place in toctree * Update namespace to appropriate organization Co-authored-by: Niels Rogge <nielsrogge@Nielss-MacBook-Pro.local> * Fix URLs (#18604) Co-authored-by: Niels Rogge <nielsrogge@Nielss-MacBook-Pro.local> * Update BLOOM parameter counts (#18531) * Update BLOOM parameter counts * Update BLOOM parameter counts * [doc] fix anchors (#18591) the manual anchors end up being duplicated with automatically added anchors and no longer work. * [fsmt] deal with -100 indices in decoder ids (#18592) * [fsmt] deal with -100 indices in decoder ids Fixes: https://github.com/huggingface/transformers/issues/17945 decoder ids get the default index -100, which breaks the model - like t5 and many other models add a fix to replace -100 with the correct pad index. For some reason this use case hasn't been used with this model until recently - so this issue was there since the beginning it seems. Any suggestions to how to add a simple test here? or perhaps we have something similar already? user's script is quite massive. * style * small change (#18584) * Flax Remat for LongT5 (#17994) * [Flax] Add remat (gradient checkpointing) * fix variable naming in test * flip: checkpoint using a method * fix naming * fix class naming * apply PVP's suggestions from code review * add gradient_checkpointing to examples * Add gradient_checkpointing to run_mlm_flax * Add remat to longt5 * Add gradient checkpointing test longt5 * Fix args errors * Fix remaining tests * Make fixup & quality fixes * replace kwargs * remove unecessary kwargs * Make fixup changes * revert long_t5_flax changes * Remove return_dict and copy to LongT5 * Remove test_gradient_checkpointing Co-authored-by: sanchit-gandhi <sanchit@huggingface.co> * mac m1 `mps` integration (#18598) * mac m1 `mps` integration * Update docs/source/en/main_classes/trainer.mdx Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * addressing comments * Apply suggestions from code review Co-authored-by: Dan Saattrup Nielsen <47701536+saattrupdan@users.noreply.github.com> * resolve comment Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> Co-authored-by: Dan Saattrup Nielsen <47701536+saattrupdan@users.noreply.github.com> * Change scheduled CIs to use torch 1.12.1 (#18644) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Add checks for some workflow jobs (#18583) Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * TF: Fix generation repetition penalty with XLA (#18648) * Update longt5.mdx (#18634) * Update run_translation_no_trainer.py (#18637) * Update run_translation_no_trainer.py found an error in selecting `no_decay` parameters and some small modifications when the user continues to train from a checkpoint * fixs `no_decay` and `resume_step` issue 1. change `no_decay` list 2. if use continue to train their model from provided checkpoint, the `resume_step` will not be initialized properly if `args.gradient_accumulation_steps != 1` * [bnb] Minor modifications (#18631) * bnb minor modifications - refactor documentation - add troubleshooting README - add PyPi library on DockerFile * Apply suggestions from code review Co-authored-by: Stas Bekman <stas00@users.noreply.github.com> * Apply suggestions from code review * Apply suggestions from code review * Apply suggestions from code review * put in one block - put bash instructions in one block * update readme - refactor a bit hardware requirements * change text a bit * Apply suggestions from code review Co-authored-by: Yih-Dar <2521628+ydshieh@users.noreply.github.com> * apply suggestions Co-authored-by: Yih-Dar <2521628+ydshieh@users.noreply.github.com> * add link to paper * Apply suggestions from code review Co-authored-by: Stas Bekman <stas00@users.noreply.github.com> * Update tests/mixed_int8/README.md * Apply suggestions from code review * refactor a bit * add instructions Turing & Amperer Co-authored-by: Stas Bekman <stas00@users.noreply.github.com> * add A6000 * clarify a bit * remove small part * Update tests/mixed_int8/README.md Co-authored-by: Stas Bekman <stas00@users.noreply.github.com> Co-authored-by: Yih-Dar <2521628+ydshieh@users.noreply.github.com> * Examples: add Bloom support for token classification (#18632) * examples: add Bloom support for token classification (FLAX, PyTorch and TensorFlow) * examples: remove support for Bloom in token classication (FLAX and TensorFlow currently have no support for it) * Fix Yolos ONNX export test (#18606) Co-authored-by: lewtun <lewis.c.tunstall@gmail.com> Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> * Fixup * Fix up * Move PIL default arguments inside function for safe imports * Add image utils to toctree * Update `rescale` method to reflect changes in #18677 * Update docs/source/en/internal/image_processing_utils.mdx Co-authored-by: NielsRogge <48327001+NielsRogge@users.noreply.github.com> * Address Niels PR comments * Apply suggestions from code review - remove defaults to None Co-authored-by: Sylvain Gugger <Sylvain.gugger@gmail.com> Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> * Fix docstrings and revert to PIL.Image.XXX resampling Use PIL.Image.XXX resampling values instead of PIL.Image.Resampling.XXX enum as it's only in the recent version >= 9.10 and version is not yet pinned and older version support deprecated * Some more docstrings and PIL.Image tidy up * Reorganise arguments so flags by modifiers * Few last docstring fixes Signed-off-by: Seunghwan Hong <seunghwan@scatterlab.co.kr> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Wang, Yi A <yi.a.wang@intel.com> Co-authored-by: Amy Roberts <amyeroberts@users.noreply.github.com> Co-authored-by: Sylvain Gugger <35901082+sgugger@users.noreply.github.com> Co-authored-by: Alara Dirik <8944735+alaradirik@users.noreply.github.com> Co-authored-by: NielsRogge <48327001+NielsRogge@users.noreply.github.com> Co-authored-by: Seunghwan Hong <harrydrippin@gmail.com> Co-authored-by: Yih-Dar <2521628+ydshieh@users.noreply.github.com> Co-authored-by: ydshieh <ydshieh@users.noreply.github.com> Co-authored-by: Sylvain Gugger <Sylvain.gugger@gmail.com> Co-authored-by: Julien Chaumond <julien@huggingface.co> Co-authored-by: regisss <15324346+regisss@users.noreply.github.com> Co-authored-by: Nicolas Patry <patry.nicolas@protonmail.com> Co-authored-by: Sourab Mangrulkar <13534540+pacman100@users.noreply.github.com> Co-authored-by: Ankur Goyal <ankrgyl@gmail.com> Co-authored-by: Ankur Goyal <ankur@impira.com> Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> Co-authored-by: Niels Rogge <nielsrogge@Nielss-MacBook-Pro.local> Co-authored-by: Mishig Davaadorj <dmishig@gmail.com> Co-authored-by: Rasmus Arpe Fogh Jensen <Rasmus.arpe@gmail.com> Co-authored-by: Ian Castillo <7807897+donelianc@users.noreply.github.com> Co-authored-by: AguilaCudicio <aguila.cudicio@gmail.com> Co-authored-by: Omar U. Espejel <espejelomar@gmail.com> Co-authored-by: Younes Belkada <49240599+younesbelkada@users.noreply.github.com> Co-authored-by: Thomas Wang <24695242+thomasw21@users.noreply.github.com> Co-authored-by: Niklas Hansson <niklas.sven.hansson@gmail.com> Co-authored-by: Thomas Chaigneau <t.chaigneau.tc@gmail.com> Co-authored-by: YouJiacheng <1503679330@qq.com> Co-authored-by: Michael Benayoun <mickbenayoun@gmail.com> Co-authored-by: Joao Gante <joaofranciscocardosogante@gmail.com> Co-authored-by: Matt <Rocketknight1@users.noreply.github.com> Co-authored-by: Dhruv Karan <k4r4n.dhruv@gmail.com> Co-authored-by: Michael Wyatt <mrwyattii@gmail.com> Co-authored-by: Maxime G <joihn@users.noreply.github.com> Co-authored-by: Maxime Gardoni <maxime.gardoni@ecorobotix.com> Co-authored-by: Wonseok Lee (Jack) <rollerkid02@snu.ac.kr> Co-authored-by: Dan Jones <dan.j.jones2@gmail.com> Co-authored-by: Daniel Jones <jonesdaniel@microsoft.com> Co-authored-by: flozi00 <flozi00.fz@gmail.com> Co-authored-by: iiLaurens <iiLaurens@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Arthur <48595927+ArthurZucker@users.noreply.github.com> Co-authored-by: Wang, Yi <yi.a.wang@intel.com> Co-authored-by: Stas Bekman <stas00@users.noreply.github.com> Co-authored-by: Niklas Muennighoff <n.muennighoff@gmail.com> Co-authored-by: Karim Foda <35491698+KMFODA@users.noreply.github.com> Co-authored-by: sanchit-gandhi <sanchit@huggingface.co> Co-authored-by: Dan Saattrup Nielsen <47701536+saattrupdan@users.noreply.github.com> Co-authored-by: zhoutang776 <47708118+zhoutang776@users.noreply.github.com> Co-authored-by: Stefan Schweter <stefan@schweter.it> Co-authored-by: lewtun <lewis.c.tunstall@gmail.com>
708 lines
29 KiB
Python
708 lines
29 KiB
Python
# coding=utf-8
|
|
# Copyright 2021 The HuggingFace Inc. team.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import argparse
|
|
import collections
|
|
import json
|
|
import os
|
|
import re
|
|
from contextlib import contextmanager
|
|
from pathlib import Path
|
|
|
|
from git import Repo
|
|
|
|
|
|
# This script is intended to be run from the root of the repo but you can adapt this constant if you need to.
|
|
PATH_TO_TRANFORMERS = "."
|
|
|
|
|
|
@contextmanager
|
|
def checkout_commit(repo, commit_id):
|
|
"""
|
|
Context manager that checks out a commit in the repo.
|
|
"""
|
|
current_head = repo.head.commit if repo.head.is_detached else repo.head.ref
|
|
|
|
try:
|
|
repo.git.checkout(commit_id)
|
|
yield
|
|
|
|
finally:
|
|
repo.git.checkout(current_head)
|
|
|
|
|
|
def clean_code(content):
|
|
"""
|
|
Remove docstrings, empty line or comments from `content`.
|
|
"""
|
|
# fmt: off
|
|
# Remove docstrings by splitting on triple " then triple ':
|
|
splits = content.split('\"\"\"')
|
|
content = "".join(splits[::2])
|
|
splits = content.split("\'\'\'")
|
|
# fmt: on
|
|
content = "".join(splits[::2])
|
|
|
|
# Remove empty lines and comments
|
|
lines_to_keep = []
|
|
for line in content.split("\n"):
|
|
# remove anything that is after a # sign.
|
|
line = re.sub("#.*$", "", line)
|
|
if len(line) == 0 or line.isspace():
|
|
continue
|
|
lines_to_keep.append(line)
|
|
return "\n".join(lines_to_keep)
|
|
|
|
|
|
def get_all_tests():
|
|
"""
|
|
Return a list of paths to all test folders and files under `tests`. All paths are rooted at `tests`.
|
|
|
|
- folders under `tests`: `tokenization`, `pipelines`, etc. The folder `models` is excluded.
|
|
- folders under `tests/models`: `bert`, `gpt2`, etc.
|
|
- test files under `tests`: `test_modeling_common.py`, `test_tokenization_common.py`, etc.
|
|
"""
|
|
test_root_dir = os.path.join(PATH_TO_TRANFORMERS, "tests")
|
|
|
|
# test folders/files directly under `tests` folder
|
|
tests = os.listdir(test_root_dir)
|
|
tests = sorted(
|
|
list(filter(lambda x: os.path.isdir(x) or x.startswith("tests/test_"), [f"tests/{x}" for x in tests]))
|
|
)
|
|
|
|
# model specific test folders
|
|
model_tests_folders = os.listdir(os.path.join(test_root_dir, "models"))
|
|
model_test_folders = sorted(list(filter(os.path.isdir, [f"tests/models/{x}" for x in model_tests_folders])))
|
|
|
|
tests.remove("tests/models")
|
|
tests = model_test_folders + tests
|
|
|
|
return tests
|
|
|
|
|
|
def diff_is_docstring_only(repo, branching_point, filename):
|
|
"""
|
|
Check if the diff is only in docstrings in a filename.
|
|
"""
|
|
with checkout_commit(repo, branching_point):
|
|
with open(filename, "r", encoding="utf-8") as f:
|
|
old_content = f.read()
|
|
|
|
with open(filename, "r", encoding="utf-8") as f:
|
|
new_content = f.read()
|
|
|
|
old_content_clean = clean_code(old_content)
|
|
new_content_clean = clean_code(new_content)
|
|
|
|
return old_content_clean == new_content_clean
|
|
|
|
|
|
def get_modified_python_files(diff_with_last_commit=False):
|
|
"""
|
|
Return a list of python files that have been modified between:
|
|
|
|
- the current head and the main branch if `diff_with_last_commit=False` (default)
|
|
- the current head and its parent commit otherwise.
|
|
"""
|
|
repo = Repo(PATH_TO_TRANFORMERS)
|
|
|
|
if not diff_with_last_commit:
|
|
print(f"main is at {repo.refs.main.commit}")
|
|
print(f"Current head is at {repo.head.commit}")
|
|
|
|
branching_commits = repo.merge_base(repo.refs.main, repo.head)
|
|
for commit in branching_commits:
|
|
print(f"Branching commit: {commit}")
|
|
return get_diff(repo, repo.head.commit, branching_commits)
|
|
else:
|
|
print(f"main is at {repo.head.commit}")
|
|
parent_commits = repo.head.commit.parents
|
|
for commit in parent_commits:
|
|
print(f"Parent commit: {commit}")
|
|
return get_diff(repo, repo.head.commit, parent_commits)
|
|
|
|
|
|
def get_diff(repo, base_commit, commits):
|
|
"""
|
|
Get's the diff between one or several commits and the head of the repository.
|
|
"""
|
|
print("\n### DIFF ###\n")
|
|
code_diff = []
|
|
for commit in commits:
|
|
for diff_obj in commit.diff(base_commit):
|
|
# We always add new python files
|
|
if diff_obj.change_type == "A" and diff_obj.b_path.endswith(".py"):
|
|
code_diff.append(diff_obj.b_path)
|
|
# We check that deleted python files won't break corresponding tests.
|
|
elif diff_obj.change_type == "D" and diff_obj.a_path.endswith(".py"):
|
|
code_diff.append(diff_obj.a_path)
|
|
# Now for modified files
|
|
elif diff_obj.change_type in ["M", "R"] and diff_obj.b_path.endswith(".py"):
|
|
# In case of renames, we'll look at the tests using both the old and new name.
|
|
if diff_obj.a_path != diff_obj.b_path:
|
|
code_diff.extend([diff_obj.a_path, diff_obj.b_path])
|
|
else:
|
|
# Otherwise, we check modifications are in code and not docstrings.
|
|
if diff_is_docstring_only(repo, commit, diff_obj.b_path):
|
|
print(f"Ignoring diff in {diff_obj.b_path} as it only concerns docstrings or comments.")
|
|
else:
|
|
code_diff.append(diff_obj.a_path)
|
|
|
|
return code_diff
|
|
|
|
|
|
def get_module_dependencies(module_fname):
|
|
"""
|
|
Get the dependencies of a module.
|
|
"""
|
|
with open(os.path.join(PATH_TO_TRANFORMERS, module_fname), "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
|
|
module_parts = module_fname.split(os.path.sep)
|
|
imported_modules = []
|
|
|
|
# Let's start with relative imports
|
|
relative_imports = re.findall(r"from\s+(\.+\S+)\s+import\s+([^\n]+)\n", content)
|
|
relative_imports = [mod for mod, imp in relative_imports if "# tests_ignore" not in imp]
|
|
for imp in relative_imports:
|
|
level = 0
|
|
while imp.startswith("."):
|
|
imp = imp[1:]
|
|
level += 1
|
|
|
|
if len(imp) > 0:
|
|
dep_parts = module_parts[: len(module_parts) - level] + imp.split(".")
|
|
else:
|
|
dep_parts = module_parts[: len(module_parts) - level] + ["__init__.py"]
|
|
imported_module = os.path.sep.join(dep_parts)
|
|
# We ignore the main init import as it's only for the __version__ that it's done
|
|
# and it would add everything as a dependency.
|
|
if not imported_module.endswith("transformers/__init__.py"):
|
|
imported_modules.append(imported_module)
|
|
|
|
# Let's continue with direct imports
|
|
# The import from the transformers module are ignored for the same reason we ignored the
|
|
# main init before.
|
|
direct_imports = re.findall(r"from\s+transformers\.(\S+)\s+import\s+([^\n]+)\n", content)
|
|
direct_imports = [mod for mod, imp in direct_imports if "# tests_ignore" not in imp]
|
|
for imp in direct_imports:
|
|
import_parts = imp.split(".")
|
|
dep_parts = ["src", "transformers"] + import_parts
|
|
imported_modules.append(os.path.sep.join(dep_parts))
|
|
|
|
# Now let's just check that we have proper module files, or append an init for submodules
|
|
dependencies = []
|
|
for imported_module in imported_modules:
|
|
if os.path.isfile(os.path.join(PATH_TO_TRANFORMERS, f"{imported_module}.py")):
|
|
dependencies.append(f"{imported_module}.py")
|
|
elif os.path.isdir(os.path.join(PATH_TO_TRANFORMERS, imported_module)) and os.path.isfile(
|
|
os.path.sep.join([PATH_TO_TRANFORMERS, imported_module, "__init__.py"])
|
|
):
|
|
dependencies.append(os.path.sep.join([imported_module, "__init__.py"]))
|
|
return dependencies
|
|
|
|
|
|
def get_test_dependencies(test_fname):
|
|
"""
|
|
Get the dependencies of a test file.
|
|
"""
|
|
with open(os.path.join(PATH_TO_TRANFORMERS, test_fname), "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
|
|
# Tests only have relative imports for other test files
|
|
# TODO Sylvain: handle relative imports cleanly
|
|
relative_imports = re.findall(r"from\s+(\.\S+)\s+import\s+([^\n]+)\n", content)
|
|
relative_imports = [test for test, imp in relative_imports if "# tests_ignore" not in imp]
|
|
|
|
def _convert_relative_import_to_file(relative_import):
|
|
level = 0
|
|
while relative_import.startswith("."):
|
|
level += 1
|
|
relative_import = relative_import[1:]
|
|
|
|
directory = os.path.sep.join(test_fname.split(os.path.sep)[:-level])
|
|
return os.path.join(directory, f"{relative_import.replace('.', os.path.sep)}.py")
|
|
|
|
dependencies = [_convert_relative_import_to_file(relative_import) for relative_import in relative_imports]
|
|
return [f for f in dependencies if os.path.isfile(os.path.join(PATH_TO_TRANFORMERS, f))]
|
|
|
|
|
|
def create_reverse_dependency_tree():
|
|
"""
|
|
Create a list of all edges (a, b) which mean that modifying a impacts b with a going over all module and test files.
|
|
"""
|
|
modules = [
|
|
str(f.relative_to(PATH_TO_TRANFORMERS))
|
|
for f in (Path(PATH_TO_TRANFORMERS) / "src/transformers").glob("**/*.py")
|
|
]
|
|
module_edges = [(d, m) for m in modules for d in get_module_dependencies(m)]
|
|
|
|
tests = [str(f.relative_to(PATH_TO_TRANFORMERS)) for f in (Path(PATH_TO_TRANFORMERS) / "tests").glob("**/*.py")]
|
|
test_edges = [(d, t) for t in tests for d in get_test_dependencies(t)]
|
|
|
|
return module_edges + test_edges
|
|
|
|
|
|
def get_tree_starting_at(module, edges):
|
|
"""
|
|
Returns the tree starting at a given module following all edges in the following format: [module, [list of edges
|
|
starting at module], [list of edges starting at the preceding level], ...]
|
|
"""
|
|
vertices_seen = [module]
|
|
new_edges = [edge for edge in edges if edge[0] == module and edge[1] != module]
|
|
tree = [module]
|
|
while len(new_edges) > 0:
|
|
tree.append(new_edges)
|
|
final_vertices = list(set(edge[1] for edge in new_edges))
|
|
vertices_seen.extend(final_vertices)
|
|
new_edges = [edge for edge in edges if edge[0] in final_vertices and edge[1] not in vertices_seen]
|
|
|
|
return tree
|
|
|
|
|
|
def print_tree_deps_of(module, all_edges=None):
|
|
"""
|
|
Prints the tree of modules depending on a given module.
|
|
"""
|
|
if all_edges is None:
|
|
all_edges = create_reverse_dependency_tree()
|
|
tree = get_tree_starting_at(module, all_edges)
|
|
|
|
# The list of lines is a list of tuples (line_to_be_printed, module)
|
|
# Keeping the modules lets us know where to insert each new lines in the list.
|
|
lines = [(tree[0], tree[0])]
|
|
for index in range(1, len(tree)):
|
|
edges = tree[index]
|
|
start_edges = set([edge[0] for edge in edges])
|
|
|
|
for start in start_edges:
|
|
end_edges = set([edge[1] for edge in edges if edge[0] == start])
|
|
# We will insert all those edges just after the line showing start.
|
|
pos = 0
|
|
while lines[pos][1] != start:
|
|
pos += 1
|
|
lines = lines[: pos + 1] + [(" " * (2 * index) + end, end) for end in end_edges] + lines[pos + 1 :]
|
|
|
|
for line in lines:
|
|
# We don't print the refs that where just here to help build lines.
|
|
print(line[0])
|
|
|
|
|
|
def create_reverse_dependency_map():
|
|
"""
|
|
Create the dependency map from module/test filename to the list of modules/tests that depend on it (even
|
|
recursively).
|
|
"""
|
|
modules = [
|
|
str(f.relative_to(PATH_TO_TRANFORMERS))
|
|
for f in (Path(PATH_TO_TRANFORMERS) / "src/transformers").glob("**/*.py")
|
|
]
|
|
# We grab all the dependencies of each module.
|
|
direct_deps = {m: get_module_dependencies(m) for m in modules}
|
|
|
|
# We add all the dependencies of each test file
|
|
tests = [str(f.relative_to(PATH_TO_TRANFORMERS)) for f in (Path(PATH_TO_TRANFORMERS) / "tests").glob("**/*.py")]
|
|
direct_deps.update({t: get_test_dependencies(t) for t in tests})
|
|
|
|
all_files = modules + tests
|
|
|
|
# This recurses the dependencies
|
|
something_changed = True
|
|
while something_changed:
|
|
something_changed = False
|
|
for m in all_files:
|
|
for d in direct_deps[m]:
|
|
if d not in direct_deps:
|
|
raise ValueError(f"KeyError:{d}. From {m}")
|
|
for dep in direct_deps[d]:
|
|
if dep not in direct_deps[m]:
|
|
direct_deps[m].append(dep)
|
|
something_changed = True
|
|
|
|
# Finally we can build the reverse map.
|
|
reverse_map = collections.defaultdict(list)
|
|
for m in all_files:
|
|
if m.endswith("__init__.py"):
|
|
reverse_map[m].extend(direct_deps[m])
|
|
for d in direct_deps[m]:
|
|
reverse_map[d].append(m)
|
|
|
|
return reverse_map
|
|
|
|
|
|
# Any module file that has a test name which can't be inferred automatically from its name should go here. A better
|
|
# approach is to (re-)name the test file accordingly, and second best to add the correspondence map here.
|
|
SPECIAL_MODULE_TO_TEST_MAP = {
|
|
"commands/add_new_model_like.py": "utils/test_add_new_model_like.py",
|
|
"configuration_utils.py": "test_configuration_common.py",
|
|
"convert_graph_to_onnx.py": "onnx/test_onnx.py",
|
|
"data/data_collator.py": "trainer/test_data_collator.py",
|
|
"deepspeed.py": "deepspeed/",
|
|
"feature_extraction_sequence_utils.py": "test_sequence_feature_extraction_common.py",
|
|
"feature_extraction_utils.py": "test_feature_extraction_common.py",
|
|
"file_utils.py": ["utils/test_file_utils.py", "utils/test_model_output.py"],
|
|
"image_transforms.py": "test_image_transforms.py",
|
|
"utils/generic.py": ["utils/test_file_utils.py", "utils/test_model_output.py", "utils/test_generic.py"],
|
|
"utils/hub.py": "utils/test_hub_utils.py",
|
|
"modelcard.py": "utils/test_model_card.py",
|
|
"modeling_flax_utils.py": "test_modeling_flax_common.py",
|
|
"modeling_tf_utils.py": ["test_modeling_tf_common.py", "utils/test_modeling_tf_core.py"],
|
|
"modeling_utils.py": ["test_modeling_common.py", "utils/test_offline.py"],
|
|
"models/auto/modeling_auto.py": [
|
|
"models/auto/test_modeling_auto.py",
|
|
"models/auto/test_modeling_tf_pytorch.py",
|
|
"models/bort/test_modeling_bort.py",
|
|
"models/dit/test_modeling_dit.py",
|
|
],
|
|
"models/auto/modeling_flax_auto.py": "models/auto/test_modeling_flax_auto.py",
|
|
"models/auto/modeling_tf_auto.py": [
|
|
"models/auto/test_modeling_tf_auto.py",
|
|
"models/auto/test_modeling_tf_pytorch.py",
|
|
"models/bort/test_modeling_tf_bort.py",
|
|
],
|
|
"models/gpt2/modeling_gpt2.py": [
|
|
"models/gpt2/test_modeling_gpt2.py",
|
|
"models/megatron_gpt2/test_modeling_megatron_gpt2.py",
|
|
],
|
|
"optimization.py": "optimization/test_optimization.py",
|
|
"optimization_tf.py": "optimization/test_optimization_tf.py",
|
|
"pipelines/__init__.py": "pipelines/test_pipelines_*.py",
|
|
"pipelines/base.py": "pipelines/test_pipelines_*.py",
|
|
"pipelines/text2text_generation.py": [
|
|
"pipelines/test_pipelines_text2text_generation.py",
|
|
"pipelines/test_pipelines_summarization.py",
|
|
"pipelines/test_pipelines_translation.py",
|
|
],
|
|
"pipelines/zero_shot_classification.py": "pipelines/test_pipelines_zero_shot.py",
|
|
"testing_utils.py": "utils/test_skip_decorators.py",
|
|
"tokenization_utils.py": ["test_tokenization_common.py", "tokenization/test_tokenization_utils.py"],
|
|
"tokenization_utils_base.py": ["test_tokenization_common.py", "tokenization/test_tokenization_utils.py"],
|
|
"tokenization_utils_fast.py": [
|
|
"test_tokenization_common.py",
|
|
"tokenization/test_tokenization_utils.py",
|
|
"tokenization/test_tokenization_fast.py",
|
|
],
|
|
"trainer.py": [
|
|
"trainer/test_trainer.py",
|
|
"extended/test_trainer_ext.py",
|
|
"trainer/test_trainer_distributed.py",
|
|
"trainer/test_trainer_tpu.py",
|
|
],
|
|
"train_pt_utils.py": "trainer/test_trainer_utils.py",
|
|
"utils/versions.py": "utils/test_versions_utils.py",
|
|
}
|
|
|
|
|
|
def module_to_test_file(module_fname):
|
|
"""
|
|
Returns the name of the file(s) where `module_fname` is tested.
|
|
"""
|
|
splits = module_fname.split(os.path.sep)
|
|
|
|
# Special map has priority
|
|
short_name = os.path.sep.join(splits[2:])
|
|
if short_name in SPECIAL_MODULE_TO_TEST_MAP:
|
|
test_file = SPECIAL_MODULE_TO_TEST_MAP[short_name]
|
|
if isinstance(test_file, str):
|
|
return f"tests/{test_file}"
|
|
return [f"tests/{f}" for f in test_file]
|
|
|
|
module_name = splits[-1]
|
|
# Fast tokenizers are tested in the same file as the slow ones.
|
|
if module_name.endswith("_fast.py"):
|
|
module_name = module_name.replace("_fast.py", ".py")
|
|
|
|
# Special case for pipelines submodules
|
|
if len(splits) >= 2 and splits[-2] == "pipelines":
|
|
default_test_file = f"tests/pipelines/test_pipelines_{module_name}"
|
|
# Special case for benchmarks submodules
|
|
elif len(splits) >= 2 and splits[-2] == "benchmark":
|
|
return ["tests/benchmark/test_benchmark.py", "tests/benchmark/test_benchmark_tf.py"]
|
|
# Special case for commands submodules
|
|
elif len(splits) >= 2 and splits[-2] == "commands":
|
|
return "tests/utils/test_cli.py"
|
|
# Special case for onnx submodules
|
|
elif len(splits) >= 2 and splits[-2] == "onnx":
|
|
return ["tests/onnx/test_features.py", "tests/onnx/test_onnx.py", "tests/onnx/test_onnx_v2.py"]
|
|
# Special case for utils (not the one in src/transformers, the ones at the root of the repo).
|
|
elif len(splits) > 0 and splits[0] == "utils":
|
|
default_test_file = f"tests/repo_utils/test_{module_name}"
|
|
elif len(splits) > 4 and splits[2] == "models":
|
|
default_test_file = f"tests/models/{splits[3]}/test_{module_name}"
|
|
elif len(splits) > 2 and splits[2].startswith("generation"):
|
|
default_test_file = f"tests/generation/test_{module_name}"
|
|
elif len(splits) > 2 and splits[2].startswith("trainer"):
|
|
default_test_file = f"tests/trainer/test_{module_name}"
|
|
else:
|
|
default_test_file = f"tests/utils/test_{module_name}"
|
|
|
|
if os.path.isfile(default_test_file):
|
|
return default_test_file
|
|
|
|
# Processing -> processor
|
|
if "processing" in default_test_file:
|
|
test_file = default_test_file.replace("processing", "processor")
|
|
if os.path.isfile(test_file):
|
|
return test_file
|
|
|
|
|
|
# This list contains the list of test files we expect never to be launched from a change in a module/util. Those are
|
|
# launched separately.
|
|
EXPECTED_TEST_FILES_NEVER_TOUCHED = [
|
|
"tests/utils/test_doc_samples.py", # Doc tests
|
|
"tests/pipelines/test_pipelines_common.py", # Actually checked by the pipeline based file
|
|
"tests/sagemaker/test_single_node_gpu.py", # SageMaker test
|
|
"tests/sagemaker/test_multi_node_model_parallel.py", # SageMaker test
|
|
"tests/sagemaker/test_multi_node_data_parallel.py", # SageMaker test
|
|
"tests/mixed_int8/test_mixed_int8.py", # Mixed-int8 bitsandbytes test
|
|
]
|
|
|
|
|
|
def _print_list(l):
|
|
return "\n".join([f"- {f}" for f in l])
|
|
|
|
|
|
def sanity_check():
|
|
"""
|
|
Checks that all test files can be touched by a modification in at least one module/utils. This test ensures that
|
|
newly-added test files are properly mapped to some module or utils, so they can be run by the CI.
|
|
"""
|
|
# Grab all module and utils
|
|
all_files = [
|
|
str(p.relative_to(PATH_TO_TRANFORMERS))
|
|
for p in (Path(PATH_TO_TRANFORMERS) / "src/transformers").glob("**/*.py")
|
|
]
|
|
all_files += [
|
|
str(p.relative_to(PATH_TO_TRANFORMERS)) for p in (Path(PATH_TO_TRANFORMERS) / "utils").glob("**/*.py")
|
|
]
|
|
|
|
# Compute all the test files we get from those.
|
|
test_files_found = []
|
|
for f in all_files:
|
|
test_f = module_to_test_file(f)
|
|
if test_f is not None:
|
|
if isinstance(test_f, str):
|
|
test_files_found.append(test_f)
|
|
else:
|
|
test_files_found.extend(test_f)
|
|
|
|
# Some of the test files might actually be subfolders so we grab the tests inside.
|
|
test_files = []
|
|
for test_f in test_files_found:
|
|
if os.path.isdir(os.path.join(PATH_TO_TRANFORMERS, test_f)):
|
|
test_files.extend(
|
|
[
|
|
str(p.relative_to(PATH_TO_TRANFORMERS))
|
|
for p in (Path(PATH_TO_TRANFORMERS) / test_f).glob("**/test*.py")
|
|
]
|
|
)
|
|
else:
|
|
test_files.append(test_f)
|
|
|
|
# Compare to existing test files
|
|
existing_test_files = [
|
|
str(p.relative_to(PATH_TO_TRANFORMERS)) for p in (Path(PATH_TO_TRANFORMERS) / "tests").glob("**/test*.py")
|
|
]
|
|
not_touched_test_files = [f for f in existing_test_files if f not in test_files]
|
|
|
|
should_be_tested = set(not_touched_test_files) - set(EXPECTED_TEST_FILES_NEVER_TOUCHED)
|
|
if len(should_be_tested) > 0:
|
|
raise ValueError(
|
|
"The following test files are not currently associated with any module or utils files, which means they "
|
|
f"will never get run by the CI:\n{_print_list(should_be_tested)}\n. Make sure the names of these test "
|
|
"files match the name of the module or utils they are testing, or adapt the constant "
|
|
"`SPECIAL_MODULE_TO_TEST_MAP` in `utils/tests_fetcher.py` to add them. If your test file is triggered "
|
|
"separately and is not supposed to be run by the regular CI, add it to the "
|
|
"`EXPECTED_TEST_FILES_NEVER_TOUCHED` constant instead."
|
|
)
|
|
|
|
|
|
def infer_tests_to_run(output_file, diff_with_last_commit=False, filters=None, json_output_file=None):
|
|
modified_files = get_modified_python_files(diff_with_last_commit=diff_with_last_commit)
|
|
print(f"\n### MODIFIED FILES ###\n{_print_list(modified_files)}")
|
|
|
|
# Create the map that will give us all impacted modules.
|
|
impacted_modules_map = create_reverse_dependency_map()
|
|
impacted_files = modified_files.copy()
|
|
for f in modified_files:
|
|
if f in impacted_modules_map:
|
|
impacted_files.extend(impacted_modules_map[f])
|
|
|
|
# Remove duplicates
|
|
impacted_files = sorted(list(set(impacted_files)))
|
|
print(f"\n### IMPACTED FILES ###\n{_print_list(impacted_files)}")
|
|
|
|
# Grab the corresponding test files:
|
|
if "setup.py" in impacted_files:
|
|
test_files_to_run = ["tests"]
|
|
else:
|
|
# Grab the corresponding test files:
|
|
test_files_to_run = []
|
|
for f in impacted_files:
|
|
# Modified test files are always added
|
|
if f.startswith("tests/"):
|
|
test_files_to_run.append(f)
|
|
# Example files are tested separately
|
|
elif f.startswith("examples/pytorch"):
|
|
test_files_to_run.append("examples/pytorch/test_pytorch_examples.py")
|
|
test_files_to_run.append("examples/pytorch/test_accelerate_examples.py")
|
|
elif f.startswith("examples/flax"):
|
|
test_files_to_run.append("examples/flax/test_flax_examples.py")
|
|
else:
|
|
new_tests = module_to_test_file(f)
|
|
if new_tests is not None:
|
|
if isinstance(new_tests, str):
|
|
test_files_to_run.append(new_tests)
|
|
else:
|
|
test_files_to_run.extend(new_tests)
|
|
|
|
# Remove duplicates
|
|
test_files_to_run = sorted(list(set(test_files_to_run)))
|
|
# Make sure we did not end up with a test file that was removed
|
|
test_files_to_run = [f for f in test_files_to_run if os.path.isfile(f) or os.path.isdir(f)]
|
|
if filters is not None:
|
|
filtered_files = []
|
|
for filter in filters:
|
|
filtered_files.extend([f for f in test_files_to_run if f.startswith(filter)])
|
|
test_files_to_run = filtered_files
|
|
|
|
print(f"\n### TEST TO RUN ###\n{_print_list(test_files_to_run)}")
|
|
if len(test_files_to_run) > 0:
|
|
with open(output_file, "w", encoding="utf-8") as f:
|
|
f.write(" ".join(test_files_to_run))
|
|
|
|
# Create a map that maps test categories to test files, i.e. `models/bert` -> [...test_modeling_bert.py, ...]
|
|
|
|
# Get all test directories (and some common test files) under `tests` and `tests/models` if `test_files_to_run`
|
|
# contains `tests` (i.e. when `setup.py` is changed).
|
|
if "tests" in test_files_to_run:
|
|
test_files_to_run = get_all_tests()
|
|
|
|
if json_output_file is not None:
|
|
test_map = {}
|
|
for test_file in test_files_to_run:
|
|
# `test_file` is a path to a test folder/file, starting with `tests/`. For example,
|
|
# - `tests/models/bert/test_modeling_bert.py` or `tests/models/bert`
|
|
# - `tests/trainer/test_trainer.py` or `tests/trainer`
|
|
# - `tests/test_modeling_common.py`
|
|
names = test_file.split(os.path.sep)
|
|
if names[1] == "models":
|
|
# take the part like `models/bert` for modeling tests
|
|
key = "/".join(names[1:3])
|
|
elif len(names) > 2 or not test_file.endswith(".py"):
|
|
# test folders under `tests` or python files under them
|
|
# take the part like tokenization, `pipeline`, etc. for other test categories
|
|
key = "/".join(names[1:2])
|
|
else:
|
|
# common test files directly under `tests/`
|
|
key = "common"
|
|
|
|
if key not in test_map:
|
|
test_map[key] = []
|
|
test_map[key].append(test_file)
|
|
|
|
# sort the keys & values
|
|
keys = sorted(test_map.keys())
|
|
test_map = {k: " ".join(sorted(test_map[k])) for k in keys}
|
|
with open(json_output_file, "w", encoding="UTF-8") as fp:
|
|
json.dump(test_map, fp, ensure_ascii=False)
|
|
|
|
|
|
def filter_pipeline_tests(output_file):
|
|
if not os.path.isfile(output_file):
|
|
print("No test file found.")
|
|
return
|
|
with open(output_file, "r", encoding="utf-8") as f:
|
|
test_files = f.read().split(" ")
|
|
|
|
if len(test_files) == 0:
|
|
print("No tests to filter.")
|
|
return
|
|
if test_files == ["tests"]:
|
|
test_files = [os.path.join("tests", f) for f in os.listdir("tests") if f not in ["__init__.py", "pipelines"]]
|
|
else:
|
|
test_files = [f for f in test_files if not f.startswith(os.path.join("tests", "pipelines"))]
|
|
|
|
with open(output_file, "w", encoding="utf-8") as f:
|
|
f.write(" ".join(test_files))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"--sanity_check", action="store_true", help="Only test that all tests and modules are accounted for."
|
|
)
|
|
parser.add_argument(
|
|
"--output_file", type=str, default="test_list.txt", help="Where to store the list of tests to run"
|
|
)
|
|
parser.add_argument(
|
|
"--json_output_file",
|
|
type=str,
|
|
default="test_map.json",
|
|
help="Where to store the tests to run in a dictionary format mapping test categories to test files",
|
|
)
|
|
parser.add_argument(
|
|
"--diff_with_last_commit",
|
|
action="store_true",
|
|
help="To fetch the tests between the current commit and the last commit",
|
|
)
|
|
parser.add_argument(
|
|
"--filters",
|
|
type=str,
|
|
nargs="*",
|
|
default=["tests"],
|
|
help="Only keep the test files matching one of those filters.",
|
|
)
|
|
parser.add_argument(
|
|
"--filter_pipeline_tests",
|
|
action="store_true",
|
|
help="Will filter the pipeline tests outside of the generated list of tests.",
|
|
)
|
|
parser.add_argument(
|
|
"--print_dependencies_of",
|
|
type=str,
|
|
help="Will only print the tree of modules depending on the file passed.",
|
|
default=None,
|
|
)
|
|
args = parser.parse_args()
|
|
if args.print_dependencies_of is not None:
|
|
print_tree_deps_of(args.print_dependencies_of)
|
|
elif args.sanity_check:
|
|
sanity_check()
|
|
elif args.filter_pipeline_tests:
|
|
filter_pipeline_tests(args.output_file)
|
|
else:
|
|
repo = Repo(PATH_TO_TRANFORMERS)
|
|
|
|
diff_with_last_commit = args.diff_with_last_commit
|
|
if not diff_with_last_commit and not repo.head.is_detached and repo.head.ref == repo.refs.main:
|
|
print("main branch detected, fetching tests against last commit.")
|
|
diff_with_last_commit = True
|
|
|
|
try:
|
|
infer_tests_to_run(
|
|
args.output_file,
|
|
diff_with_last_commit=diff_with_last_commit,
|
|
filters=args.filters,
|
|
json_output_file=args.json_output_file,
|
|
)
|
|
except Exception as e:
|
|
print(f"\nError when trying to grab the relevant tests: {e}\n\nRunning all tests.")
|
|
with open(args.output_file, "w", encoding="utf-8") as f:
|
|
if args.filters is None:
|
|
f.write("./tests/")
|
|
else:
|
|
f.write(" ".join(args.filters))
|