├── tests ├── __init__.py ├── data │ ├── __init__.py │ ├── fields │ │ ├── __init__.py │ │ ├── metadata_field_test.py │ │ ├── flag_field_test.py │ │ ├── field_test.py │ │ └── index_field_test.py │ ├── samplers │ │ └── __init__.py │ ├── tokenizers │ │ └── __init__.py │ ├── dataset_readers │ │ ├── __init__.py │ │ └── babi_reader_test.py │ ├── token_indexers │ │ ├── __init__.py │ │ └── spacy_indexer_test.py │ ├── dataloader_test.py │ └── instance_test.py ├── nn │ └── __init__.py ├── commands │ ├── __init__.py │ ├── test_install_test.py │ └── no_op_train_test.py ├── common │ ├── __init__.py │ ├── testing.py │ └── plugins_test.py ├── interpret │ ├── __init__.py │ ├── smooth_gradient_test.py │ ├── simple_gradient_test.py │ └── integrated_gradient_test.py ├── models │ ├── __init__.py │ ├── model_test.py │ ├── basic_classifier_test.py │ └── test_model_test_case.py ├── predictors │ ├── __init__.py │ └── sentence_tagger_test.py ├── training │ ├── __init__.py │ ├── metrics │ │ ├── __init__.py │ │ ├── mean_absolute_error_test.py │ │ └── entropy_test.py │ ├── momentum_schedulers │ │ └── __init__.py │ ├── learning_rate_schedulers │ │ └── __init__.py │ └── no_op_trainer_test.py ├── tutorials │ ├── __init__.py │ └── tagger │ │ ├── __init__.py │ │ └── basic_allennlp_test.py ├── modules │ ├── attention │ │ ├── __init__.py │ │ ├── bilinear_attention_test.py │ │ ├── cosine_attention_test.py │ │ ├── dot_product_attention_test.py │ │ └── additive_attention_test.py │ ├── matrix_attention │ │ ├── __init__.py │ │ ├── cosine_matrix_attention_test.py │ │ ├── dot_product_matrix_attention_test.py │ │ └── bilinear_matrix_attention_test.py │ ├── seq2seq_encoders │ │ ├── __init__.py │ │ ├── pass_through_encoder_test.py │ │ ├── feedforward_encoder_test.py │ │ └── gated_cnn_encoder_test.py │ ├── seq2vec_encoders │ │ ├── __init__.py │ │ ├── cls_pooler_test.py │ │ └── cnn_highway_encoder_test.py │ ├── span_extractors │ │ └── __init__.py │ ├── token_embedders │ │ ├── __init__.py │ │ └── pass_through_embedder_test.py │ ├── text_field_embedders │ │ └── __init__.py │ ├── highway_test.py │ ├── masked_layer_norm_test.py │ ├── gated_sum_test.py │ ├── stacked_alternating_lstm_test.py │ ├── seq2vec_encoder_test.py │ ├── stacked_elmo_lstm_test.py │ ├── seq2seq_encoder_test.py │ └── lstm_cell_with_projection_test.py └── version_test.py ├── benchmarks ├── __init__.py ├── data │ ├── __init__.py │ └── tokenizers │ │ ├── __init__.py │ │ └── character_tokenizer_bench.py └── pytest.ini ├── allennlp ├── tools │ ├── __init__.py │ ├── EVALB │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── tgrep_proc.prl │ │ ├── LICENSE │ │ ├── sample │ │ │ ├── sample.tst │ │ │ └── sample.gld │ │ └── bug │ │ │ ├── bug.rsl-new │ │ │ └── bug.rsl-old │ └── inspect_cache.py ├── interpret │ ├── __init__.py │ ├── attackers │ │ └── __init__.py │ └── saliency_interpreters │ │ ├── __init__.py │ │ └── saliency_interpreter.py ├── nn │ ├── __init__.py │ └── regularizers │ │ ├── regularizer.py │ │ ├── __init__.py │ │ ├── regularizers.py │ │ └── regularizer_applicator.py ├── training │ ├── momentum_schedulers │ │ ├── __init__.py │ │ ├── momentum_scheduler.py │ │ └── inverted_triangular.py │ ├── __init__.py │ ├── metrics │ │ ├── perplexity.py │ │ ├── average.py │ │ ├── __init__.py │ │ ├── entropy.py │ │ ├── mean_absolute_error.py │ │ └── metric.py │ ├── no_op_trainer.py │ └── learning_rate_schedulers │ │ └── __init__.py ├── common │ ├── __init__.py │ ├── testing │ │ └── __init__.py │ ├── tqdm.py │ └── plugins.py ├── models │ └── __init__.py ├── data │ ├── dataset_readers │ │ ├── dataset_utils │ │ │ └── __init__.py │ │ └── __init__.py │ ├── samplers │ │ └── __init__.py │ ├── tokenizers │ │ ├── __init__.py │ │ ├── letters_digits_tokenizer.py │ │ └── whitespace_tokenizer.py │ ├── __init__.py │ ├── token_indexers │ │ └── __init__.py │ └── fields │ │ ├── sequence_field.py │ │ ├── __init__.py │ │ └── flag_field.py ├── modules │ ├── text_field_embedders │ │ └── __init__.py │ ├── span_extractors │ │ └── __init__.py │ ├── attention │ │ ├── __init__.py │ │ ├── dot_product_attention.py │ │ ├── cosine_attention.py │ │ └── attention.py │ ├── matrix_attention │ │ ├── __init__.py │ │ ├── dot_product_matrix_attention.py │ │ ├── matrix_attention.py │ │ └── cosine_matrix_attention.py │ ├── token_embedders │ │ ├── pass_through_token_embedder.py │ │ ├── empty_embedder.py │ │ ├── __init__.py │ │ ├── token_embedder.py │ │ └── token_characters_encoder.py │ ├── masked_layer_norm.py │ ├── softmax_loss.py │ ├── layer_norm.py │ ├── __init__.py │ ├── seq2vec_encoders │ │ ├── seq2vec_encoder.py │ │ └── __init__.py │ ├── input_variational_dropout.py │ ├── gated_sum.py │ └── seq2seq_encoders │ │ ├── feedforward_encoder.py │ │ ├── seq2seq_encoder.py │ │ ├── pass_through_encoder.py │ │ └── __init__.py ├── predictors │ ├── __init__.py │ └── text_classifier.py ├── version.py ├── __main__.py ├── __init__.py └── commands │ ├── subcommand.py │ └── test_install.py ├── test_fixtures ├── __init__.py ├── plugins │ ├── .allennlp_plugins │ └── d │ │ ├── __init__.py │ │ └── d.py ├── basic_classifier │ ├── serialization │ │ ├── vocabulary │ │ │ ├── labels.txt │ │ │ └── non_padded_namespaces.txt │ │ ├── best.th │ │ └── model.tar.gz │ ├── from_archive_serialization │ │ └── model.tar.gz │ ├── embedding_with_trainable_is_false │ │ └── model.tar.gz │ ├── experiment_from_archive.jsonnet │ ├── parameters_inspection.json │ ├── experiment_seq2vec.jsonnet │ ├── common.jsonnet │ └── experiment_seq2seq.jsonnet ├── simple_tagger │ ├── serialization │ │ ├── vocabulary │ │ │ ├── labels.txt │ │ │ ├── non_padded_namespaces.txt │ │ │ └── tokens.txt │ │ ├── best.th │ │ └── model.tar.gz │ ├── model_test_case.jsonnet │ ├── experiment.json │ └── experiment_with_regularization.json ├── simple_tagger_with_elmo │ ├── serialization │ │ ├── vocabulary │ │ │ ├── labels.txt │ │ │ └── non_padded_namespaces.txt │ │ ├── best.th │ │ └── model.tar.gz │ └── experiment.json ├── simple_tagger_with_span_f1 │ ├── serialization │ │ ├── vocabulary │ │ │ ├── labels.txt │ │ │ ├── non_padded_namespaces.txt │ │ │ ├── tokens.txt │ │ │ └── test_tokens.txt │ │ ├── best.th │ │ └── model.tar.gz │ └── experiment.json ├── elmo │ ├── lm_weights.hdf5 │ ├── lm_embeddings_0.hdf5 │ ├── lm_embeddings_1.hdf5 │ ├── lm_embeddings_2.hdf5 │ ├── elmo_token_embeddings.hdf5 │ ├── options.json │ └── config │ │ └── characters_token_embedder.json ├── utf-8_sample │ ├── archives │ │ ├── utf-8.zip │ │ ├── utf-8.tar.gz │ │ ├── utf-8.tar.bz2 │ │ └── utf-8.tar.lzma │ ├── utf-8_sample.txt.gz │ └── utf-8_sample.txt.zip ├── embeddings │ ├── multi-file-archive.zip │ ├── fake_embeddings.5d.txt.gz │ ├── multi-file-archive.tar.gz │ ├── fake_embeddings.5d.txt.bz2 │ ├── fake_embeddings.5d.txt.lzma │ ├── fake_embeddings.5d.txt.zip │ ├── glove.6B.100d.sample.txt.gz │ ├── glove.6B.300d.sample.txt.gz │ ├── fake_embeddings.5d.txt.tar.gz │ └── fake_embeddings.5d.txt └── data │ ├── text_classification_json │ ├── integer_labels.jsonl │ ├── ag_news_corpus.jsonl │ ├── ag_news_corpus_fake_sentiment_labels.jsonl │ └── imdb_corpus.jsonl │ ├── sequence_tagging.tsv │ ├── brown_corpus.txt │ ├── shards │ ├── sequence_tagging_00.tsv │ ├── sequence_tagging_01.tsv │ └── sequence_tagging_02.tsv │ ├── conll2003.txt │ └── babi.txt ├── .coveragerc ├── .dockerignore ├── docs ├── img │ ├── favicon.ico │ └── allennlp-logo-dark.png └── css │ └── extra.css ├── scripts ├── build_docs.sh ├── 24hr_diff.sh ├── ai2_internal │ └── resumable_train.sh ├── get_version.py ├── check_large_files.sh ├── compile_coref_data.sh └── tests │ └── py2md │ └── py2md_test.py ├── MANIFEST.in ├── codecov.yml ├── pyproject.toml ├── .flake8 ├── .github └── ISSUE_TEMPLATE │ └── feature_request.md ├── .gitignore ├── mkdocs-skeleton.yml ├── Dockerfile ├── dev-requirements.txt ├── Dockerfile.test └── pytest.ini /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /benchmarks/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/data/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/nn/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /allennlp/tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /benchmarks/data/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test_fixtures/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/common/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/interpret/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/models/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/predictors/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/tutorials/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/data/fields/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/data/samplers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/data/tokenizers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /benchmarks/data/tokenizers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/data/dataset_readers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/data/token_indexers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/modules/attention/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/training/metrics/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/tutorials/tagger/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = tests/* 3 | -------------------------------------------------------------------------------- /allennlp/tools/EVALB/.gitignore: -------------------------------------------------------------------------------- 1 | evalb 2 | -------------------------------------------------------------------------------- /tests/modules/matrix_attention/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/modules/seq2seq_encoders/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/modules/seq2vec_encoders/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/modules/span_extractors/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/modules/token_embedders/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test_fixtures/plugins/.allennlp_plugins: -------------------------------------------------------------------------------- 1 | d 2 | -------------------------------------------------------------------------------- /tests/modules/text_field_embedders/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/training/momentum_schedulers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/training/learning_rate_schedulers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test_fixtures/plugins/d/__init__.py: -------------------------------------------------------------------------------- 1 | from d.d import D 2 | -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/serialization/vocabulary/labels.txt: -------------------------------------------------------------------------------- 1 | neg 2 | pos 3 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | **.pyc 3 | **/__pycache__ 4 | .gitignore 5 | .git 6 | -------------------------------------------------------------------------------- /docs/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/docs/img/favicon.ico -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/serialization/vocabulary/non_padded_namespaces.txt: -------------------------------------------------------------------------------- 1 | *labels 2 | *tags 3 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/serialization/vocabulary/labels.txt: -------------------------------------------------------------------------------- 1 | O 2 | U-ORG 3 | U-PER 4 | U-LOC 5 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/serialization/vocabulary/non_padded_namespaces.txt: -------------------------------------------------------------------------------- 1 | *labels 2 | *tags 3 | -------------------------------------------------------------------------------- /scripts/build_docs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -Eeuo pipefail 4 | 5 | make clean 6 | make build-docs 7 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_elmo/serialization/vocabulary/labels.txt: -------------------------------------------------------------------------------- 1 | O 2 | U-ORG 3 | U-PER 4 | U-LOC 5 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_elmo/serialization/vocabulary/non_padded_namespaces.txt: -------------------------------------------------------------------------------- 1 | *labels 2 | *tags 3 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_span_f1/serialization/vocabulary/labels.txt: -------------------------------------------------------------------------------- 1 | O 2 | I-ORG 3 | I-PER 4 | I-LOC 5 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_span_f1/serialization/vocabulary/non_padded_namespaces.txt: -------------------------------------------------------------------------------- 1 | *labels 2 | *tags 3 | -------------------------------------------------------------------------------- /docs/img/allennlp-logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/docs/img/allennlp-logo-dark.png -------------------------------------------------------------------------------- /test_fixtures/elmo/lm_weights.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/elmo/lm_weights.hdf5 -------------------------------------------------------------------------------- /test_fixtures/elmo/lm_embeddings_0.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/elmo/lm_embeddings_0.hdf5 -------------------------------------------------------------------------------- /test_fixtures/elmo/lm_embeddings_1.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/elmo/lm_embeddings_1.hdf5 -------------------------------------------------------------------------------- /test_fixtures/elmo/lm_embeddings_2.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/elmo/lm_embeddings_2.hdf5 -------------------------------------------------------------------------------- /allennlp/tools/EVALB/Makefile: -------------------------------------------------------------------------------- 1 | all: clean evalb 2 | 3 | clean: 4 | rm -f evalb 5 | 6 | evalb: evalb.c 7 | gcc -Wall -g -o evalb evalb.c 8 | -------------------------------------------------------------------------------- /test_fixtures/elmo/elmo_token_embeddings.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/elmo/elmo_token_embeddings.hdf5 -------------------------------------------------------------------------------- /test_fixtures/utf-8_sample/archives/utf-8.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/utf-8_sample/archives/utf-8.zip -------------------------------------------------------------------------------- /test_fixtures/embeddings/multi-file-archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/multi-file-archive.zip -------------------------------------------------------------------------------- /test_fixtures/utf-8_sample/archives/utf-8.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/utf-8_sample/archives/utf-8.tar.gz -------------------------------------------------------------------------------- /test_fixtures/utf-8_sample/utf-8_sample.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/utf-8_sample/utf-8_sample.txt.gz -------------------------------------------------------------------------------- /test_fixtures/utf-8_sample/utf-8_sample.txt.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/utf-8_sample/utf-8_sample.txt.zip -------------------------------------------------------------------------------- /test_fixtures/embeddings/fake_embeddings.5d.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/fake_embeddings.5d.txt.gz -------------------------------------------------------------------------------- /test_fixtures/embeddings/multi-file-archive.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/multi-file-archive.tar.gz -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/serialization/best.th: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/simple_tagger/serialization/best.th -------------------------------------------------------------------------------- /test_fixtures/utf-8_sample/archives/utf-8.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/utf-8_sample/archives/utf-8.tar.bz2 -------------------------------------------------------------------------------- /test_fixtures/utf-8_sample/archives/utf-8.tar.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/utf-8_sample/archives/utf-8.tar.lzma -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/serialization/best.th: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/basic_classifier/serialization/best.th -------------------------------------------------------------------------------- /test_fixtures/data/text_classification_json/integer_labels.jsonl: -------------------------------------------------------------------------------- 1 | {"label": 0, "text": "This text has label 0"} 2 | {"label": 1, "text": "This text has label 1"} -------------------------------------------------------------------------------- /test_fixtures/embeddings/fake_embeddings.5d.txt.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/fake_embeddings.5d.txt.bz2 -------------------------------------------------------------------------------- /test_fixtures/embeddings/fake_embeddings.5d.txt.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/fake_embeddings.5d.txt.lzma -------------------------------------------------------------------------------- /test_fixtures/embeddings/fake_embeddings.5d.txt.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/fake_embeddings.5d.txt.zip -------------------------------------------------------------------------------- /test_fixtures/embeddings/glove.6B.100d.sample.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/glove.6B.100d.sample.txt.gz -------------------------------------------------------------------------------- /test_fixtures/embeddings/glove.6B.300d.sample.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/glove.6B.300d.sample.txt.gz -------------------------------------------------------------------------------- /test_fixtures/embeddings/fake_embeddings.5d.txt.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/embeddings/fake_embeddings.5d.txt.tar.gz -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/serialization/model.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/simple_tagger/serialization/model.tar.gz -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/serialization/model.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/basic_classifier/serialization/model.tar.gz -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_elmo/serialization/best.th: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/simple_tagger_with_elmo/serialization/best.th -------------------------------------------------------------------------------- /allennlp/tools/EVALB/tgrep_proc.prl: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | 3 | while(<>) 4 | { 5 | if(m/TOP/) #skip lines which are blank 6 | { 7 | print; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_span_f1/serialization/best.th: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/simple_tagger_with_span_f1/serialization/best.th -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_elmo/serialization/model.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/simple_tagger_with_elmo/serialization/model.tar.gz -------------------------------------------------------------------------------- /allennlp/interpret/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.interpret.attackers.attacker import Attacker 2 | from allennlp.interpret.saliency_interpreters.saliency_interpreter import SaliencyInterpreter 3 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_span_f1/serialization/model.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/simple_tagger_with_span_f1/serialization/model.tar.gz -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/from_archive_serialization/model.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/basic_classifier/from_archive_serialization/model.tar.gz -------------------------------------------------------------------------------- /test_fixtures/data/sequence_tagging.tsv: -------------------------------------------------------------------------------- 1 | cats###N are###V animals###N .###N 2 | dogs###N are###V animals###N .###N 3 | snakes###N are###V animals###N .###N 4 | birds###N are###V animals###N .###N 5 | -------------------------------------------------------------------------------- /test_fixtures/data/brown_corpus.txt: -------------------------------------------------------------------------------- 1 | cats/N are/V animals/N ./N 2 | 3 | 4 | dogs/N are/V animals/N ./N 5 | 6 | 7 | snakes/N are/V animals/N ./N 8 | 9 | 10 | birds/N are/V animals/N ./N 11 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.md 3 | recursive-include allennlp * 4 | recursive-include scripts * 5 | global-exclude .DS_Store *.py[cod] 6 | prune **/__pycache__ 7 | prune **/.mypy_cache 8 | -------------------------------------------------------------------------------- /docs/css/extra.css: -------------------------------------------------------------------------------- 1 | h4 { 2 | font-size: 0.9rem !important; 3 | font-weight: 400 !important; 4 | margin-top: 1.2em !important; 5 | } 6 | 7 | h2, h3, h4 { 8 | color: #213744; 9 | } 10 | -------------------------------------------------------------------------------- /test_fixtures/data/shards/sequence_tagging_00.tsv: -------------------------------------------------------------------------------- 1 | cats###N are###V animals###N .###N 2 | dogs###N are###V animals###N .###N 3 | snakes###N are###V animals###N .###N 4 | birds###N are###V animals###N .###N 5 | -------------------------------------------------------------------------------- /allennlp/nn/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.nn.activations import Activation 2 | from allennlp.nn.initializers import Initializer, InitializerApplicator 3 | from allennlp.nn.regularizers import RegularizerApplicator 4 | -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/embedding_with_trainable_is_false/model.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/allennlp/master/test_fixtures/basic_classifier/embedding_with_trainable_is_false/model.tar.gz -------------------------------------------------------------------------------- /test_fixtures/data/shards/sequence_tagging_01.tsv: -------------------------------------------------------------------------------- 1 | ferns###N are###V plants###N .###N 2 | trees###N are###V plants###N .###N 3 | flowers###N are###V plants###N .###N 4 | vegetables###N are###V plants###N .###N 5 | -------------------------------------------------------------------------------- /test_fixtures/data/shards/sequence_tagging_02.tsv: -------------------------------------------------------------------------------- 1 | cars###N are###V vehicles###N .###N 2 | buses###N are###V vehicles###N .###N 3 | planes###N are###V vehicles###N .###N 4 | rockets###N are###V vehicles###N .###N 5 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/serialization/vocabulary/tokens.txt: -------------------------------------------------------------------------------- 1 | @@UNKNOWN@@ 2 | . 3 | u.n. 4 | official 5 | ekeus 6 | heads 7 | for 8 | baghdad 9 | ai2 10 | engineer 11 | joel 12 | lives 13 | in 14 | seattle 15 | -------------------------------------------------------------------------------- /allennlp/training/momentum_schedulers/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.training.momentum_schedulers.momentum_scheduler import MomentumScheduler 2 | from allennlp.training.momentum_schedulers.inverted_triangular import InvertedTriangular 3 | -------------------------------------------------------------------------------- /scripts/24hr_diff.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # A small script which checks if there have been any commits in the past 24 hours. 4 | 5 | if [[ $(git whatchanged --since 'one day ago') ]]; then 6 | exit 0 7 | fi 8 | exit 1 9 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_span_f1/serialization/vocabulary/tokens.txt: -------------------------------------------------------------------------------- 1 | @@UNKNOWN@@ 2 | . 3 | u.n. 4 | official 5 | ekeus 6 | heads 7 | for 8 | baghdad 9 | ai2 10 | engineer 11 | joel 12 | lives 13 | in 14 | seattle 15 | -------------------------------------------------------------------------------- /allennlp/interpret/attackers/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.interpret.attackers.attacker import Attacker 2 | from allennlp.interpret.attackers.input_reduction import InputReduction 3 | from allennlp.interpret.attackers.hotflip import Hotflip 4 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_span_f1/serialization/vocabulary/test_tokens.txt: -------------------------------------------------------------------------------- 1 | @@UNKNOWN@@ 2 | . 3 | u.n. 4 | official 5 | ekeus 6 | heads 7 | for 8 | baghdad 9 | ai2 10 | engineer 11 | joel 12 | lives 13 | in 14 | seattle 15 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | precision: 0 3 | round: down 4 | status: 5 | patch: 6 | default: 7 | target: 90 8 | project: 9 | default: 10 | threshold: 1% 11 | changes: false 12 | comment: false 13 | ignore: 14 | - "tests/" 15 | -------------------------------------------------------------------------------- /allennlp/common/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.common.from_params import FromParams 2 | from allennlp.common.lazy import Lazy 3 | from allennlp.common.params import Params 4 | from allennlp.common.registrable import Registrable 5 | from allennlp.common.tqdm import Tqdm 6 | from allennlp.common.util import JsonDict 7 | -------------------------------------------------------------------------------- /allennlp/training/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.training.checkpointer import Checkpointer 2 | from allennlp.training.tensorboard_writer import TensorboardWriter 3 | from allennlp.training.no_op_trainer import NoOpTrainer 4 | from allennlp.training.trainer import Trainer, GradientDescentTrainer, BatchCallback, EpochCallback 5 | -------------------------------------------------------------------------------- /allennlp/models/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | These submodules contain the classes for AllenNLP models, 3 | all of which are subclasses of `Model`. 4 | """ 5 | 6 | from allennlp.models.model import Model 7 | from allennlp.models.archival import archive_model, load_archive, Archive 8 | from allennlp.models.simple_tagger import SimpleTagger 9 | from allennlp.models.basic_classifier import BasicClassifier 10 | -------------------------------------------------------------------------------- /allennlp/data/dataset_readers/dataset_utils/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.data.dataset_readers.dataset_utils.span_utils import enumerate_spans 2 | from allennlp.data.dataset_readers.dataset_utils.span_utils import bio_tags_to_spans 3 | from allennlp.data.dataset_readers.dataset_utils.span_utils import to_bioul, iob1_to_bioul 4 | from allennlp.data.dataset_readers.dataset_utils.span_utils import bioul_tags_to_spans 5 | -------------------------------------------------------------------------------- /test_fixtures/data/conll2003.txt: -------------------------------------------------------------------------------- 1 | -DOCSTART- -X- -X- O 2 | 3 | U.N. NNP I-NP I-ORG 4 | official NN I-NP O 5 | Ekeus NNP I-NP I-PER 6 | heads VBZ I-VP O 7 | for IN I-PP O 8 | Baghdad NNP I-NP I-LOC 9 | . . O O 10 | 11 | -DOCSTART- -X- -X- O 12 | 13 | AI2 NNP I-NP I-ORG 14 | engineer NN I-NP O 15 | Joel NNP I-NP I-PER 16 | lives VBZ I-VP O 17 | in IN I-PP O 18 | Seattle NNP I-NP I-LOC 19 | . . O O 20 | -------------------------------------------------------------------------------- /allennlp/interpret/saliency_interpreters/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.interpret.saliency_interpreters.saliency_interpreter import SaliencyInterpreter 2 | from allennlp.interpret.saliency_interpreters.simple_gradient import SimpleGradient 3 | from allennlp.interpret.saliency_interpreters.integrated_gradient import IntegratedGradient 4 | from allennlp.interpret.saliency_interpreters.smooth_gradient import SmoothGradient 5 | -------------------------------------------------------------------------------- /allennlp/data/samplers/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.data.samplers.samplers import ( 2 | Sampler, 3 | BatchSampler, 4 | SequentialSampler, 5 | SubsetRandomSampler, 6 | WeightedRandomSampler, 7 | RandomSampler, 8 | BasicBatchSampler, 9 | ) 10 | from allennlp.data.samplers.bucket_batch_sampler import BucketBatchSampler 11 | from allennlp.data.samplers.max_tokens_batch_sampler import MaxTokensBatchSampler 12 | -------------------------------------------------------------------------------- /benchmarks/pytest.ini: -------------------------------------------------------------------------------- 1 | # We use pytest to run benchmarks, which is weird, but so far the best benchmarking 2 | # framework we've found is only available as a pytest plugin. 3 | # That said, we like to organize our benchmarks seperately and with different naming 4 | # conventions from our tests, which requires using a seperate pytest configuration. 5 | [pytest] 6 | python_files = *_bench.py 7 | python_functions = bench_* *_bench 8 | python_classes = 9 | -------------------------------------------------------------------------------- /allennlp/modules/text_field_embedders/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A `TextFieldEmbedder` is a `Module` that takes as input the `dict` of NumPy arrays 3 | produced by a `TextField` and returns as output an embedded representation of the tokens in that field. 4 | """ 5 | 6 | from allennlp.modules.text_field_embedders.text_field_embedder import TextFieldEmbedder 7 | from allennlp.modules.text_field_embedders.basic_text_field_embedder import BasicTextFieldEmbedder 8 | -------------------------------------------------------------------------------- /allennlp/nn/regularizers/regularizer.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common import Registrable 4 | 5 | 6 | class Regularizer(Registrable): 7 | """ 8 | An abstract class representing a regularizer. It must implement 9 | call, returning a scalar tensor. 10 | """ 11 | 12 | default_implementation = "l2" 13 | 14 | def __call__(self, parameter: torch.Tensor) -> torch.Tensor: 15 | raise NotImplementedError 16 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 100 3 | 4 | include = '\.pyi?$' 5 | 6 | exclude = ''' 7 | ( 8 | __pycache__ 9 | | \btutorials\b 10 | | \bbuild\b 11 | | \.git 12 | | \.mypy_cache 13 | | \.pytest_cache 14 | | \.vscode 15 | | \.venv 16 | | \bdist\b 17 | | \bdoc\b 18 | ) 19 | ''' 20 | 21 | [build-system] 22 | requires = ["setuptools", "wheel"] 23 | build-backend = "setuptools.build_meta" 24 | -------------------------------------------------------------------------------- /tests/tutorials/tagger/basic_allennlp_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from allennlp.common.testing import AllenNlpTestCase 4 | 5 | 6 | @pytest.mark.skip("makes test-install fail (and also takes 30 seconds)") 7 | class TestBasicAllenNlp(AllenNlpTestCase): 8 | @classmethod 9 | def test_run_as_script(cls): 10 | # Just ensure the tutorial runs without throwing an exception. 11 | 12 | import tutorials.tagger.basic_allennlp # noqa 13 | -------------------------------------------------------------------------------- /allennlp/modules/span_extractors/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.modules.span_extractors.span_extractor import SpanExtractor 2 | from allennlp.modules.span_extractors.endpoint_span_extractor import EndpointSpanExtractor 3 | from allennlp.modules.span_extractors.self_attentive_span_extractor import ( 4 | SelfAttentiveSpanExtractor, 5 | ) 6 | from allennlp.modules.span_extractors.bidirectional_endpoint_span_extractor import ( 7 | BidirectionalEndpointSpanExtractor, 8 | ) 9 | -------------------------------------------------------------------------------- /allennlp/nn/regularizers/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains classes representing regularization schemes 3 | as well as a class for applying regularization to parameters. 4 | """ 5 | 6 | from allennlp.nn.regularizers.regularizer import Regularizer 7 | from allennlp.nn.regularizers.regularizers import L1Regularizer 8 | from allennlp.nn.regularizers.regularizers import L2Regularizer 9 | from allennlp.nn.regularizers.regularizer_applicator import RegularizerApplicator 10 | -------------------------------------------------------------------------------- /allennlp/modules/attention/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.modules.attention.attention import Attention 2 | from allennlp.modules.attention.bilinear_attention import BilinearAttention 3 | from allennlp.modules.attention.additive_attention import AdditiveAttention 4 | from allennlp.modules.attention.cosine_attention import CosineAttention 5 | from allennlp.modules.attention.dot_product_attention import DotProductAttention 6 | from allennlp.modules.attention.linear_attention import LinearAttention 7 | -------------------------------------------------------------------------------- /allennlp/training/momentum_schedulers/momentum_scheduler.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common.registrable import Registrable 4 | from allennlp.training.scheduler import Scheduler 5 | 6 | 7 | class MomentumScheduler(Scheduler, Registrable): 8 | def __init__(self, optimizer: torch.optim.Optimizer, last_epoch: int = -1) -> None: 9 | super().__init__(optimizer, "momentum", last_epoch) 10 | 11 | def get_values(self) -> None: 12 | raise NotImplementedError 13 | -------------------------------------------------------------------------------- /tests/common/testing.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common.testing import AllenNlpTestCase, multi_device 4 | 5 | actual_devices = set() 6 | 7 | 8 | class TestTesting(AllenNlpTestCase): 9 | @multi_device 10 | def test_multi_device(self, device: str): 11 | actual_devices.add(device) 12 | 13 | def test_devices_accounted_for(self): 14 | expected_devices = {"cpu", "cuda"} if torch.cuda.is_available() else {"cpu"} 15 | assert expected_devices == actual_devices 16 | -------------------------------------------------------------------------------- /allennlp/modules/matrix_attention/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.modules.matrix_attention.matrix_attention import MatrixAttention 2 | from allennlp.modules.matrix_attention.bilinear_matrix_attention import BilinearMatrixAttention 3 | from allennlp.modules.matrix_attention.cosine_matrix_attention import CosineMatrixAttention 4 | from allennlp.modules.matrix_attention.dot_product_matrix_attention import DotProductMatrixAttention 5 | from allennlp.modules.matrix_attention.linear_matrix_attention import LinearMatrixAttention 6 | -------------------------------------------------------------------------------- /allennlp/predictors/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A `Predictor` is 3 | a wrapper for an AllenNLP `Model` 4 | that makes JSON predictions using JSON inputs. If you 5 | want to serve up a model through the web service 6 | (or using `allennlp.commands.predict`), you'll need 7 | a `Predictor` that wraps it. 8 | """ 9 | from allennlp.predictors.predictor import Predictor 10 | from allennlp.predictors.sentence_tagger import SentenceTaggerPredictor 11 | from allennlp.predictors.text_classifier import TextClassifierPredictor 12 | -------------------------------------------------------------------------------- /allennlp/version.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | _MAJOR = "1" 4 | _MINOR = "0" 5 | # On master and in a nightly release the patch should be one ahead of the last 6 | # released build. 7 | _PATCH = "1" 8 | # This is mainly for nightly builds which have the suffix ".dev$DATE". See 9 | # https://semver.org/#is-v123-a-semantic-version for the semantics. 10 | _SUFFIX = os.environ.get("ALLENNLP_VERSION_SUFFIX", "") 11 | 12 | VERSION_SHORT = "{0}.{1}".format(_MAJOR, _MINOR) 13 | VERSION = "{0}.{1}.{2}{3}".format(_MAJOR, _MINOR, _PATCH, _SUFFIX) 14 | -------------------------------------------------------------------------------- /test_fixtures/plugins/d/d.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | from overrides import overrides 4 | 5 | from allennlp.commands import Subcommand 6 | 7 | 8 | def do_nothing(_): 9 | pass 10 | 11 | 12 | @Subcommand.register("d") 13 | class D(Subcommand): 14 | @overrides 15 | def add_subparser(self, parser: argparse._SubParsersAction) -> argparse.ArgumentParser: 16 | subparser = parser.add_parser(self.name, description="fake", help="fake help") 17 | subparser.set_defaults(func=do_nothing) 18 | return subparser 19 | -------------------------------------------------------------------------------- /tests/modules/token_embedders/pass_through_embedder_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import torch 3 | from allennlp.modules.token_embedders import PassThroughTokenEmbedder 4 | from allennlp.common.testing import AllenNlpTestCase 5 | 6 | 7 | class TestBagOfWordCountsTokenEmbedder(AllenNlpTestCase): 8 | def test_pass_through_embedder(self): 9 | embedder = PassThroughTokenEmbedder(3) 10 | tensor = torch.randn([4, 3]) 11 | numpy.testing.assert_equal(tensor.numpy(), embedder(tensor).numpy()) 12 | assert embedder.get_output_dim() == 3 13 | -------------------------------------------------------------------------------- /test_fixtures/elmo/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "lstm": { 3 | "cell_clip": 3, 4 | "use_skip_connections": true, 5 | "n_layers": 2, 6 | "proj_clip": 3, 7 | "projection_dim": 16, 8 | "dim": 64 9 | }, 10 | "char_cnn": { 11 | "embedding": { 12 | "dim": 4 13 | }, 14 | "filters": [ 15 | [1, 4], 16 | [2, 8], 17 | [3, 16], 18 | [4, 32], 19 | [5, 64] 20 | ], 21 | "n_highway": 2, 22 | "n_characters": 262, 23 | "max_characters_per_token": 50, 24 | "activation": "relu" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /allennlp/modules/attention/dot_product_attention.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from overrides import overrides 3 | from allennlp.modules.attention.attention import Attention 4 | 5 | 6 | @Attention.register("dot_product") 7 | class DotProductAttention(Attention): 8 | """ 9 | Computes attention between a vector and a matrix using dot product. 10 | 11 | Registered as an `Attention` with name "dot_product". 12 | """ 13 | 14 | @overrides 15 | def _forward_internal(self, vector: torch.Tensor, matrix: torch.Tensor) -> torch.Tensor: 16 | return matrix.bmm(vector.unsqueeze(-1)).squeeze(-1) 17 | -------------------------------------------------------------------------------- /tests/data/dataloader_test.py: -------------------------------------------------------------------------------- 1 | from typing import Iterable 2 | 3 | import pytest 4 | 5 | from allennlp.data.instance import Instance 6 | from allennlp.data.dataloader import DataLoader 7 | from allennlp.data.dataset_readers.dataset_reader import AllennlpLazyDataset 8 | 9 | 10 | def fake_instance_generator(file_name: str) -> Iterable[Instance]: 11 | yield from [] 12 | 13 | 14 | def test_multi_processing_with_lazy_dataset_warns(): 15 | with pytest.warns(UserWarning, match=r".*deadlocks.*"): 16 | DataLoader(AllennlpLazyDataset(fake_instance_generator, "nonexistent_file"), num_workers=1) 17 | -------------------------------------------------------------------------------- /test_fixtures/embeddings/fake_embeddings.5d.txt: -------------------------------------------------------------------------------- 1 | If 0.798 0.817 0.213 0.501 0.712 2 | you 0.723 0.626 0.850 0.024 0.715 3 | think 0.143 0.189 0.555 0.361 0.472 4 | are 0.095 0.023 0.760 0.773 0.501 5 | too 0.424 0.834 0.341 0.550 0.250 6 | small 0.072 0.154 0.410 0.436 0.417 7 | to 0.510 0.358 0.086 0.459 0.024 8 | make 0.878 0.651 0.044 0.264 0.872 9 | a 0.267 0.036 0.937 0.782 0.331 10 | difference 0.053 0.162 0.671 0.110 0.259 11 | try 0.929 0.813 0.396 0.053 0.049 12 | sleeping 0.991 0.532 0.972 0.165 0.203 13 | with 0.042 0.408 0.231 0.294 0.237 14 | mosquito 0.017 0.479 0.909 0.488 0.296 15 | àèìòù 1.0 2.0 3.0 4.0 5.0 16 | -------------------------------------------------------------------------------- /allennlp/data/tokenizers/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains various classes for performing 3 | tokenization. 4 | """ 5 | 6 | from allennlp.data.tokenizers.tokenizer import Token, Tokenizer 7 | from allennlp.data.tokenizers.spacy_tokenizer import SpacyTokenizer 8 | from allennlp.data.tokenizers.letters_digits_tokenizer import LettersDigitsTokenizer 9 | from allennlp.data.tokenizers.pretrained_transformer_tokenizer import PretrainedTransformerTokenizer 10 | from allennlp.data.tokenizers.character_tokenizer import CharacterTokenizer 11 | from allennlp.data.tokenizers.sentence_splitter import SentenceSplitter 12 | from allennlp.data.tokenizers.whitespace_tokenizer import WhitespaceTokenizer 13 | -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/experiment_from_archive.jsonnet: -------------------------------------------------------------------------------- 1 | local COMMON = import 'common.jsonnet'; 2 | 3 | { 4 | "dataset_reader": COMMON['dataset_reader'], 5 | "datasets_for_vocab_creation": ["train"], 6 | "train_data_path": "test_fixtures/data/text_classification_json/ag_news_corpus_fake_sentiment_labels.jsonl", 7 | "validation_data_path": "test_fixtures/data/text_classification_json/ag_news_corpus_fake_sentiment_labels.jsonl", 8 | "model": { 9 | "type": "from_archive", 10 | "archive_file": "test_fixtures/basic_classifier/serialization/model.tar.gz", 11 | }, 12 | "data_loader": COMMON['data_loader'], 13 | "trainer": COMMON['trainer'], 14 | } 15 | -------------------------------------------------------------------------------- /allennlp/modules/matrix_attention/dot_product_matrix_attention.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from overrides import overrides 3 | 4 | from allennlp.modules.matrix_attention.matrix_attention import MatrixAttention 5 | 6 | 7 | @MatrixAttention.register("dot_product") 8 | class DotProductMatrixAttention(MatrixAttention): 9 | """ 10 | Computes attention between every entry in matrix_1 with every entry in matrix_2 using a dot 11 | product. 12 | 13 | Registered as a `MatrixAttention` with name "dot_product". 14 | """ 15 | 16 | @overrides 17 | def forward(self, matrix_1: torch.Tensor, matrix_2: torch.Tensor) -> torch.Tensor: 18 | return matrix_1.bmm(matrix_2.transpose(2, 1)) 19 | -------------------------------------------------------------------------------- /scripts/ai2_internal/resumable_train.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Dispatches to allennlp train. Recovers if the serialization directory is 4 | # found and is non-empty, trains from scratch otherwise. 5 | # 6 | # Usage: 7 | # resumable_train.sh serialization_dir [train_arg ...] 8 | 9 | serialization_dir=$1 10 | shift 11 | 12 | # If $serialization_dir exists and is non-empty we are resuming 13 | if [ -d $serialization_dir ] && [ "$(ls -A $serialization_dir)" ]; then 14 | echo "Recovering state from $serialization_dir" 15 | allennlp train -r -s $serialization_dir $@ 16 | else 17 | echo "No recovery state found. Starting from scratch." 18 | allennlp train -s $serialization_dir $@ 19 | fi 20 | 21 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 115 3 | 4 | ignore = 5 | # these rules don't play well with black 6 | E203 # whitespace before : 7 | W503 # line break before binary operator 8 | 9 | exclude = 10 | build/** 11 | doc/** 12 | tutorials/tagger/** 13 | 14 | per-file-ignores = 15 | # __init__.py files are allowed to have unused imports and lines-too-long 16 | */__init__.py:F401 17 | */**/**/__init__.py:F401,E501 18 | 19 | # tests don't have to respect 20 | # E731: do not assign a lambda expression, use a def 21 | tests/**:E731 22 | 23 | # scripts don't have to respect 24 | # E402: imports not at top of file (because we mess with sys.path) 25 | scripts/**:E402 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'Feature request' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build artifacts 2 | 3 | .eggs/ 4 | .mypy_cache 5 | allennlp.egg-info/ 6 | build/ 7 | dist/ 8 | pip-wheel-metadata/ 9 | context.tar.gz 10 | 11 | 12 | # dev tools 13 | 14 | .envrc 15 | .python-version 16 | .idea 17 | .venv/ 18 | .vscode/ 19 | /*.iml 20 | 21 | 22 | # jupyter notebooks 23 | 24 | .ipynb_checkpoints 25 | 26 | 27 | # miscellaneous 28 | 29 | .cache/ 30 | allennlp/tools/EVALB/evalb.dSYM/ 31 | doc/_build/ 32 | *.swp 33 | .DS_Store 34 | 35 | 36 | # python 37 | 38 | *.pyc 39 | *.pyo 40 | __pycache__ 41 | 42 | 43 | # testing and continuous integration 44 | 45 | .coverage 46 | .pytest_cache/ 47 | 48 | # documentation build artifacts 49 | 50 | docs/*.md 51 | docs/api 52 | site/ 53 | mkdocs.yml 54 | -------------------------------------------------------------------------------- /allennlp/data/__init__.py: -------------------------------------------------------------------------------- 1 | from allennlp.data.dataloader import DataLoader, allennlp_collate 2 | from allennlp.data.dataset_readers.dataset_reader import ( 3 | DatasetReader, 4 | AllennlpDataset, 5 | AllennlpLazyDataset, 6 | ) 7 | from allennlp.data.fields.field import DataArray, Field 8 | from allennlp.data.fields.text_field import TextFieldTensors 9 | from allennlp.data.instance import Instance 10 | from allennlp.data.samplers import BatchSampler, Sampler 11 | from allennlp.data.token_indexers.token_indexer import TokenIndexer, IndexedTokenList 12 | from allennlp.data.tokenizers.token import Token 13 | from allennlp.data.tokenizers.tokenizer import Tokenizer 14 | from allennlp.data.vocabulary import Vocabulary 15 | from allennlp.data.batch import Batch 16 | -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/parameters_inspection.json: -------------------------------------------------------------------------------- 1 | { 2 | "_classification_layer": { 3 | "bias": "tunable", 4 | "weight": "tunable" 5 | }, 6 | "_feedforward": { 7 | "_linear_layers": { 8 | "0": { 9 | "bias": "tunable", 10 | "weight": "tunable" 11 | } 12 | } 13 | }, 14 | "_seq2seq_encoder": { 15 | "_module": { 16 | "bias_hh_l0": "tunable", 17 | "bias_ih_l0": "tunable", 18 | "weight_hh_l0": "tunable", 19 | "weight_ih_l0": "tunable" 20 | } 21 | }, 22 | "_text_field_embedder": { 23 | "token_embedder_tokens": { 24 | "weight": "tunable" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /benchmarks/data/tokenizers/character_tokenizer_bench.py: -------------------------------------------------------------------------------- 1 | from allennlp.data.tokenizers import CharacterTokenizer 2 | 3 | 4 | tokenizer = CharacterTokenizer() 5 | passage = ( 6 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " 7 | "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis " 8 | "nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " 9 | "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu " 10 | "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in " 11 | "culpa qui officia deserunt mollit anim id est laborum." 12 | ) 13 | 14 | 15 | def bench_character_tokenizer(benchmark): 16 | benchmark(tokenizer.tokenize, passage) 17 | -------------------------------------------------------------------------------- /test_fixtures/data/text_classification_json/ag_news_corpus.jsonl: -------------------------------------------------------------------------------- 1 | {"label":2,"text":"Memphis Rout Still Stings for No. 14 Louisville; Coach Petrino Vows to Have Team Better Prepared. NASHVILLE, Tenn. Nov 3, 2004 - Louisville #39;s 30-point loss at home to Memphis last season is still a painful memory for the Cardinals.","headline":"Memphis Rout Still Stings for Louisville"} 2 | {"label":2,"text":"AP - Eli Manning has replaced Kurt Warner as the New York Giants' starting quarterback.","headline":"Manning Replaces Warner As Giants QB (AP)"} 3 | {"label":4,"text":"A conference dedicated to online journalism explores the effect blogs have on news reporting. Some say they draw attention to under-reported stories. Others struggle to establish the credibility enjoyed by professionals.","headline":"Do Blogs Change the News?"} 4 | -------------------------------------------------------------------------------- /allennlp/data/token_indexers/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A `TokenIndexer` determines how string tokens get represented as arrays of indices in a model. 3 | """ 4 | 5 | from allennlp.data.token_indexers.single_id_token_indexer import SingleIdTokenIndexer 6 | from allennlp.data.token_indexers.token_characters_indexer import TokenCharactersIndexer 7 | from allennlp.data.token_indexers.token_indexer import TokenIndexer 8 | from allennlp.data.token_indexers.elmo_indexer import ELMoTokenCharactersIndexer 9 | from allennlp.data.token_indexers.spacy_indexer import SpacyTokenIndexer 10 | from allennlp.data.token_indexers.pretrained_transformer_indexer import PretrainedTransformerIndexer 11 | from allennlp.data.token_indexers.pretrained_transformer_mismatched_indexer import ( 12 | PretrainedTransformerMismatchedIndexer, 13 | ) 14 | -------------------------------------------------------------------------------- /allennlp/modules/token_embedders/pass_through_token_embedder.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from allennlp.modules.token_embedders.token_embedder import TokenEmbedder 3 | 4 | 5 | @TokenEmbedder.register("pass_through") 6 | class PassThroughTokenEmbedder(TokenEmbedder): 7 | """ 8 | Assumes that the input is already vectorized in some way, 9 | and just returns it. 10 | 11 | Registered as a `TokenEmbedder` with name "pass_through". 12 | 13 | # Parameters 14 | 15 | hidden_dim : `int`, required. 16 | 17 | """ 18 | 19 | def __init__(self, hidden_dim: int) -> None: 20 | self.hidden_dim = hidden_dim 21 | super().__init__() 22 | 23 | def get_output_dim(self): 24 | return self.hidden_dim 25 | 26 | def forward(self, tokens: torch.Tensor) -> torch.Tensor: 27 | return tokens 28 | -------------------------------------------------------------------------------- /test_fixtures/data/babi.txt: -------------------------------------------------------------------------------- 1 | 1 Gertrude is a cat. 2 | 2 Cats are afraid of sheep. 3 | 3 Jessica is a sheep. 4 | 4 Mice are afraid of wolves. 5 | 5 Emily is a wolf. 6 | 6 Winona is a mouse. 7 | 7 Wolves are afraid of sheep. 8 | 8 Sheep are afraid of wolves. 9 | 9 What is Gertrude afraid of? sheep 1 2 10 | 10 What is Winona afraid of? wolf 4 6 11 | 11 What is Emily afraid of? sheep 5 7 12 | 12 What is Jessica afraid of? wolf 3 8 13 | 1 Mice are afraid of wolves. 14 | 2 Gertrude is a mouse. 15 | 3 Sheep are afraid of mice. 16 | 4 Winona is a cat. 17 | 5 Wolves are afraid of mice. 18 | 6 Emily is a sheep. 19 | 7 Jessica is a wolf. 20 | 8 Cats are afraid of mice. 21 | 9 What is Emily afraid of? mouse 3 6 22 | 10 What is Winona afraid of? mouse 4 8 23 | 11 What is Gertrude afraid of? wolf 1 2 24 | 12 What is Jessica afraid of? mouse 5 7 25 | -------------------------------------------------------------------------------- /test_fixtures/data/text_classification_json/ag_news_corpus_fake_sentiment_labels.jsonl: -------------------------------------------------------------------------------- 1 | {"label":"pos","text":"Memphis Rout Still Stings for No. 14 Louisville; Coach Petrino Vows to Have Team Better Prepared. NASHVILLE, Tenn. Nov 3, 2004 - Louisville #39;s 30-point loss at home to Memphis last season is still a painful memory for the Cardinals.","headline":"Memphis Rout Still Stings for Louisville"} 2 | {"label":"neg","text":"AP - Eli Manning has replaced Kurt Warner as the New York Giants' starting quarterback.","headline":"Manning Replaces Warner As Giants QB (AP)"} 3 | {"label":"pos","text":"A conference dedicated to online journalism explores the effect blogs have on news reporting. Some say they draw attention to under-reported stories. Others struggle to establish the credibility enjoyed by professionals.","headline":"Do Blogs Change the News?"} 4 | -------------------------------------------------------------------------------- /allennlp/data/fields/sequence_field.py: -------------------------------------------------------------------------------- 1 | from allennlp.data.fields.field import DataArray, Field 2 | 3 | 4 | class SequenceField(Field[DataArray]): 5 | """ 6 | A `SequenceField` represents a sequence of things. This class just adds a method onto 7 | `Field`: :func:`sequence_length`. It exists so that `SequenceLabelField`, `IndexField` and other 8 | similar `Fields` can have a single type to require, with a consistent API, whether they are 9 | pointing to words in a `TextField`, items in a `ListField`, or something else. 10 | """ 11 | 12 | __slots__ = [] # type: ignore 13 | 14 | def sequence_length(self) -> int: 15 | """ 16 | How many elements are there in this sequence? 17 | """ 18 | raise NotImplementedError 19 | 20 | def empty_field(self) -> "SequenceField": 21 | raise NotImplementedError 22 | -------------------------------------------------------------------------------- /allennlp/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import logging 3 | import os 4 | import sys 5 | 6 | if os.environ.get("ALLENNLP_DEBUG"): 7 | LEVEL = logging.DEBUG 8 | else: 9 | level_name = os.environ.get("ALLENNLP_LOG_LEVEL") 10 | LEVEL = logging._nameToLevel.get(level_name, logging.INFO) 11 | 12 | sys.path.insert(0, os.path.dirname(os.path.abspath(os.path.join(__file__, os.pardir)))) 13 | logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", level=LEVEL) 14 | 15 | # filelock emits too many messages, so tell it to be quiet unless it has something 16 | # important to say. 17 | _filelock_logger = logging.getLogger("filelock") 18 | _filelock_logger.setLevel(logging.WARNING) 19 | 20 | from allennlp.commands import main # noqa 21 | 22 | 23 | def run(): 24 | main(prog="allennlp") 25 | 26 | 27 | if __name__ == "__main__": 28 | run() 29 | -------------------------------------------------------------------------------- /allennlp/data/tokenizers/letters_digits_tokenizer.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import List 3 | 4 | from overrides import overrides 5 | 6 | from allennlp.data.tokenizers.token import Token 7 | from allennlp.data.tokenizers.tokenizer import Tokenizer 8 | 9 | 10 | @Tokenizer.register("letters_digits") 11 | class LettersDigitsTokenizer(Tokenizer): 12 | """ 13 | A `Tokenizer` which keeps runs of (unicode) letters and runs of digits together, while 14 | every other non-whitespace character becomes a separate word. 15 | 16 | Registered as a `Tokenizer` with name "letters_digits". 17 | """ 18 | 19 | @overrides 20 | def tokenize(self, text: str) -> List[Token]: 21 | # We use the [^\W\d_] pattern as a trick to match unicode letters 22 | tokens = [Token(m.group(), idx=m.start()) for m in re.finditer(r"[^\W\d_]+|\d+|\S", text)] 23 | return tokens 24 | -------------------------------------------------------------------------------- /tests/commands/test_install_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from allennlp.common.testing import AllenNlpTestCase 4 | from allennlp.commands.test_install import _get_module_root 5 | 6 | 7 | class TestTestInstall(AllenNlpTestCase): 8 | def test_get_module_root(self): 9 | """ 10 | When a user runs `allennlp test-install`, we have no idea where 11 | they're running it from, so we do an `os.chdir` to the _module_ 12 | root in order to get all the paths in the fixtures to resolve properly. 13 | 14 | The logic within `allennlp test-install` is pretty hard to test in 15 | its entirety, so this test is verifies that the `os.chdir` component 16 | works properly by checking that we correctly find the path to 17 | `os.chdir` to. 18 | """ 19 | project_root = _get_module_root() 20 | assert os.path.exists(os.path.join(project_root, "__main__.py")) 21 | -------------------------------------------------------------------------------- /allennlp/tools/inspect_cache.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from allennlp.common.file_utils import CACHE_DIRECTORY 4 | from allennlp.common.file_utils import filename_to_url 5 | 6 | 7 | def main(): 8 | print(f"Looking for datasets in {CACHE_DIRECTORY}...") 9 | if not os.path.exists(CACHE_DIRECTORY): 10 | print("Directory does not exist.") 11 | print("No cached datasets found.") 12 | 13 | cached_files = os.listdir(CACHE_DIRECTORY) 14 | 15 | if not cached_files: 16 | print("Directory is empty.") 17 | print("No cached datasets found.") 18 | 19 | for filename in cached_files: 20 | if not filename.endswith("json"): 21 | url, etag = filename_to_url(filename) 22 | print("Filename: %s" % filename) 23 | print("Url: %s" % url) 24 | print("ETag: %s" % etag) 25 | print() 26 | 27 | 28 | if __name__ == "__main__": 29 | main() 30 | -------------------------------------------------------------------------------- /allennlp/modules/attention/cosine_attention.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from overrides import overrides 3 | from allennlp.modules.attention.attention import Attention 4 | from allennlp.nn import util 5 | 6 | 7 | @Attention.register("cosine") 8 | class CosineAttention(Attention): 9 | """ 10 | Computes attention between a vector and a matrix using cosine similarity. 11 | 12 | Registered as an `Attention` with name "cosine". 13 | """ 14 | 15 | @overrides 16 | def _forward_internal(self, vector: torch.Tensor, matrix: torch.Tensor) -> torch.Tensor: 17 | a_norm = vector / ( 18 | vector.norm(p=2, dim=-1, keepdim=True) + util.tiny_value_of_dtype(vector.dtype) 19 | ) 20 | b_norm = matrix / ( 21 | matrix.norm(p=2, dim=-1, keepdim=True) + util.tiny_value_of_dtype(matrix.dtype) 22 | ) 23 | return torch.bmm(a_norm.unsqueeze(dim=1), b_norm.transpose(-1, -2)).squeeze(1) 24 | -------------------------------------------------------------------------------- /allennlp/modules/matrix_attention/matrix_attention.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common.registrable import Registrable 4 | 5 | 6 | class MatrixAttention(torch.nn.Module, Registrable): 7 | """ 8 | `MatrixAttention` takes two matrices as input and returns a matrix of attentions. 9 | 10 | We compute the similarity between each row in each matrix and return unnormalized similarity 11 | scores. Because these scores are unnormalized, we don't take a mask as input; it's up to the 12 | caller to deal with masking properly when this output is used. 13 | 14 | Input: 15 | - matrix_1 : `(batch_size, num_rows_1, embedding_dim_1)` 16 | - matrix_2 : `(batch_size, num_rows_2, embedding_dim_2)` 17 | 18 | Output: 19 | - `(batch_size, num_rows_1, num_rows_2)` 20 | """ 21 | 22 | def forward(self, matrix_1: torch.Tensor, matrix_2: torch.Tensor) -> torch.Tensor: 23 | raise NotImplementedError 24 | -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/experiment_seq2vec.jsonnet: -------------------------------------------------------------------------------- 1 | local COMMON = import 'common.jsonnet'; 2 | 3 | { 4 | "dataset_reader": COMMON['dataset_reader'], 5 | "datasets_for_vocab_creation": ["train"], 6 | "train_data_path": COMMON['train_data_path'], 7 | "validation_data_path": COMMON['train_data_path'], 8 | "model": { 9 | "type": "basic_classifier", 10 | "text_field_embedder": { 11 | "token_embedders": { 12 | "tokens": { 13 | "type": "embedding", 14 | "embedding_dim": 10, 15 | "trainable": true 16 | } 17 | } 18 | }, 19 | "seq2vec_encoder": { 20 | "type": "cnn", 21 | "num_filters": 8, 22 | "embedding_dim": 10, 23 | "output_dim": 16 24 | } 25 | }, 26 | "data_loader": COMMON['data_loader'], 27 | "trainer": COMMON['trainer'], 28 | } 29 | -------------------------------------------------------------------------------- /allennlp/training/metrics/perplexity.py: -------------------------------------------------------------------------------- 1 | from overrides import overrides 2 | import torch 3 | 4 | from allennlp.training.metrics.average import Average 5 | from allennlp.training.metrics.metric import Metric 6 | 7 | 8 | @Metric.register("perplexity") 9 | class Perplexity(Average): 10 | """ 11 | Perplexity is a common metric used for evaluating how well a language model 12 | predicts a sample. 13 | 14 | Notes 15 | ----- 16 | Assumes negative log likelihood loss of each batch (base e). Provides the 17 | average perplexity of the batches. 18 | """ 19 | 20 | @overrides 21 | def get_metric(self, reset: bool = False) -> float: 22 | """ 23 | # Returns 24 | 25 | The accumulated perplexity. 26 | """ 27 | average_loss = super().get_metric(reset) 28 | if average_loss == 0: 29 | return 0.0 30 | 31 | # Exponentiate the loss to compute perplexity 32 | return float(torch.exp(average_loss)) 33 | -------------------------------------------------------------------------------- /mkdocs-skeleton.yml: -------------------------------------------------------------------------------- 1 | site_name: AllenNLP 2 | site_description: AllenNLP is a .. 3 | site_url: https://allennlp.org/ 4 | 5 | extra_css: 6 | - "css/extra.css" 7 | 8 | theme: 9 | name: material 10 | palette: 11 | primary: blue 12 | accent: grey 13 | logo: img/favicon.ico 14 | favicon: img/favicon.ico 15 | highlightjs: true 16 | hljs_languages: 17 | - python 18 | - typescript 19 | - json 20 | 21 | 22 | repo_name: allenai/allennlp 23 | # TODO(markn): Consider adding GA here, if we care about it. 24 | 25 | nav: 26 | - Home: README.md 27 | - Repository: https://github.com/allenai/allennlp 28 | - Versions: 29 | - Latest: /latest/ 30 | - Stable: /stable/ 31 | - Master: /master/ 32 | - API: 'This section is autogenerated, do not edit.' 33 | - Contributing: CONTRIBUTING.md 34 | - License: LICENSE.md 35 | 36 | markdown_extensions: 37 | - toc: 38 | permalink: '#' 39 | - markdown.extensions.codehilite: 40 | guess_lang: true 41 | - admonition 42 | - codehilite 43 | - extra 44 | -------------------------------------------------------------------------------- /tests/models/model_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common.testing.test_case import AllenNlpTestCase 4 | from allennlp.models import load_archive 5 | 6 | 7 | class TestModel(AllenNlpTestCase): 8 | def test_extend_embedder_vocab(self): 9 | model_archive = str( 10 | self.FIXTURES_ROOT / "basic_classifier" / "serialization" / "model.tar.gz" 11 | ) 12 | trained_model = load_archive(model_archive).model 13 | 14 | original_weight = trained_model._text_field_embedder.token_embedder_tokens.weight 15 | assert tuple(original_weight.shape) == (213, 10) 16 | 17 | counter = {"tokens": {"unawarded": 1}} 18 | trained_model.vocab._extend(counter) 19 | trained_model.extend_embedder_vocab() 20 | 21 | extended_weight = trained_model._text_field_embedder.token_embedder_tokens.weight 22 | assert tuple(extended_weight.shape) == (214, 10) 23 | 24 | assert torch.all(original_weight == extended_weight[:213, :]) 25 | -------------------------------------------------------------------------------- /allennlp/data/tokenizers/whitespace_tokenizer.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from overrides import overrides 4 | 5 | from allennlp.data.tokenizers.token import Token 6 | from allennlp.data.tokenizers.tokenizer import Tokenizer 7 | 8 | 9 | @Tokenizer.register("whitespace") 10 | @Tokenizer.register("just_spaces") 11 | class WhitespaceTokenizer(Tokenizer): 12 | """ 13 | A `Tokenizer` that assumes you've already done your own tokenization somehow and have 14 | separated the tokens by spaces. We just split the input string on whitespace and return the 15 | resulting list. 16 | 17 | Note that we use `text.split()`, which means that the amount of whitespace between the 18 | tokens does not matter. This will never result in spaces being included as tokens. 19 | 20 | Registered as a `Tokenizer` with name "whitespace" and "just_spaces". 21 | """ 22 | 23 | @overrides 24 | def tokenize(self, text: str) -> List[Token]: 25 | return [Token(t) for t in text.split()] 26 | -------------------------------------------------------------------------------- /allennlp/modules/matrix_attention/cosine_matrix_attention.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from overrides import overrides 3 | 4 | from allennlp.modules.matrix_attention.matrix_attention import MatrixAttention 5 | from allennlp.nn import util 6 | 7 | 8 | @MatrixAttention.register("cosine") 9 | class CosineMatrixAttention(MatrixAttention): 10 | """ 11 | Computes attention between every entry in matrix_1 with every entry in matrix_2 using cosine 12 | similarity. 13 | 14 | Registered as a `MatrixAttention` with name "cosine". 15 | """ 16 | 17 | @overrides 18 | def forward(self, matrix_1: torch.Tensor, matrix_2: torch.Tensor) -> torch.Tensor: 19 | a_norm = matrix_1 / ( 20 | matrix_1.norm(p=2, dim=-1, keepdim=True) + util.tiny_value_of_dtype(matrix_1.dtype) 21 | ) 22 | b_norm = matrix_2 / ( 23 | matrix_2.norm(p=2, dim=-1, keepdim=True) + util.tiny_value_of_dtype(matrix_2.dtype) 24 | ) 25 | return torch.bmm(a_norm, b_norm.transpose(-1, -2)) 26 | -------------------------------------------------------------------------------- /tests/modules/attention/bilinear_attention_test.py: -------------------------------------------------------------------------------- 1 | from numpy.testing import assert_almost_equal 2 | import torch 3 | from torch.nn.parameter import Parameter 4 | 5 | from allennlp.common import Params 6 | from allennlp.modules.attention import BilinearAttention 7 | from allennlp.common.testing import AllenNlpTestCase 8 | 9 | 10 | class TestBilinearAttention(AllenNlpTestCase): 11 | def test_forward_does_a_bilinear_product(self): 12 | params = Params({"vector_dim": 2, "matrix_dim": 2, "normalize": False}) 13 | bilinear = BilinearAttention.from_params(params) 14 | bilinear._weight_matrix = Parameter(torch.FloatTensor([[-0.3, 0.5], [2.0, -1.0]])) 15 | bilinear._bias = Parameter(torch.FloatTensor([0.1])) 16 | a_vectors = torch.FloatTensor([[1, 1]]) 17 | b_vectors = torch.FloatTensor([[[1, 0], [0, 1]]]) 18 | result = bilinear(a_vectors, b_vectors).detach().numpy() 19 | assert result.shape == (1, 2) 20 | assert_almost_equal(result, [[1.8, -0.4]]) 21 | -------------------------------------------------------------------------------- /tests/modules/attention/cosine_attention_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from numpy.testing import assert_almost_equal 3 | import numpy 4 | 5 | from allennlp.common import Params 6 | from allennlp.common.testing.test_case import AllenNlpTestCase 7 | from allennlp.modules.attention.attention import Attention 8 | from allennlp.modules.attention.cosine_attention import CosineAttention 9 | 10 | 11 | class TestCosineAttention(AllenNlpTestCase): 12 | def test_can_init_cosine(self): 13 | legacy_attention = Attention.from_params(Params({"type": "cosine"})) 14 | isinstance(legacy_attention, CosineAttention) 15 | 16 | def test_cosine_similarity(self): 17 | linear = CosineAttention(normalize=False) 18 | output = linear( 19 | torch.FloatTensor([[0, 0, 0], [1, 1, 1]]), 20 | torch.FloatTensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]), 21 | ) 22 | 23 | assert_almost_equal(output.numpy(), numpy.array([[0.0, 0.0], [0.9948, 0.9973]]), decimal=2) 24 | -------------------------------------------------------------------------------- /tests/data/fields/metadata_field_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from allennlp.common.testing.test_case import AllenNlpTestCase 4 | from allennlp.data.fields import MetadataField 5 | 6 | 7 | class TestMetadataField(AllenNlpTestCase): 8 | def test_mapping_works_with_dict(self): 9 | field = MetadataField({"a": 1, "b": [0]}) 10 | 11 | assert "a" in field 12 | assert field["a"] == 1 13 | assert len(field) == 2 14 | 15 | keys = {k for k in field} 16 | assert keys == {"a", "b"} 17 | 18 | values = [v for v in field.values()] 19 | assert len(values) == 2 20 | assert 1 in values 21 | assert [0] in values 22 | 23 | def test_mapping_raises_with_non_dict(self): 24 | field = MetadataField(0) 25 | 26 | with pytest.raises(TypeError): 27 | _ = field[0] 28 | 29 | with pytest.raises(TypeError): 30 | _ = len(field) 31 | 32 | with pytest.raises(TypeError): 33 | _ = [x for x in field] 34 | -------------------------------------------------------------------------------- /tests/interpret/smooth_gradient_test.py: -------------------------------------------------------------------------------- 1 | from allennlp.common.testing import AllenNlpTestCase 2 | from allennlp.models.archival import load_archive 3 | from allennlp.predictors import Predictor 4 | from allennlp.interpret.saliency_interpreters import SmoothGradient 5 | 6 | 7 | class TestSmoothGradient(AllenNlpTestCase): 8 | def test_smooth_gradient(self): 9 | inputs = {"sentence": "It was the ending that I hated"} 10 | archive = load_archive( 11 | self.FIXTURES_ROOT / "basic_classifier" / "serialization" / "model.tar.gz" 12 | ) 13 | predictor = Predictor.from_archive(archive, "text_classifier") 14 | 15 | interpreter = SmoothGradient(predictor) 16 | interpretation = interpreter.saliency_interpret_from_json(inputs) 17 | assert interpretation is not None 18 | assert "instance_1" in interpretation 19 | assert "grad_input_1" in interpretation["instance_1"] 20 | assert len(interpretation["instance_1"]["grad_input_1"]) == 7 # 7 words in input 21 | -------------------------------------------------------------------------------- /allennlp/data/dataset_readers/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A :class:`~allennlp.data.dataset_readers.dataset_reader.DatasetReader` 3 | reads a file and converts it to a collection of 4 | :class:`~allennlp.data.instance.Instance` s. 5 | The various subclasses know how to read specific filetypes 6 | and produce datasets in the formats required by specific models. 7 | """ 8 | 9 | 10 | from allennlp.data.dataset_readers.conll2003 import Conll2003DatasetReader 11 | from allennlp.data.dataset_readers.dataset_reader import ( 12 | DatasetReader, 13 | AllennlpDataset, 14 | AllennlpLazyDataset, 15 | ) 16 | from allennlp.data.dataset_readers.interleaving_dataset_reader import InterleavingDatasetReader 17 | from allennlp.data.dataset_readers.sequence_tagging import SequenceTaggingDatasetReader 18 | from allennlp.data.dataset_readers.sharded_dataset_reader import ShardedDatasetReader 19 | from allennlp.data.dataset_readers.babi import BabiReader 20 | from allennlp.data.dataset_readers.text_classification_json import TextClassificationJsonReader 21 | -------------------------------------------------------------------------------- /tests/predictors/sentence_tagger_test.py: -------------------------------------------------------------------------------- 1 | from allennlp.common.testing import AllenNlpTestCase 2 | from allennlp.models.archival import load_archive 3 | from allennlp.predictors import Predictor 4 | 5 | 6 | class TestSentenceTaggerPredictor(AllenNlpTestCase): 7 | def test_predictions_to_labeled_instances(self): 8 | inputs = {"sentence": "Eric Wallace was an intern at AI2"} 9 | 10 | archive = load_archive( 11 | self.FIXTURES_ROOT / "simple_tagger" / "serialization" / "model.tar.gz" 12 | ) 13 | predictor = Predictor.from_archive(archive, "sentence_tagger") 14 | 15 | instance = predictor._json_to_instance(inputs) 16 | outputs = predictor._model.forward_on_instance(instance) 17 | new_instances = predictor.predictions_to_labeled_instances(instance, outputs) 18 | assert len(new_instances) > 1 19 | for new_instance in new_instances: 20 | assert "tags" in new_instance 21 | assert len(new_instance["tags"]) == 7 # 7 words in input 22 | -------------------------------------------------------------------------------- /tests/modules/attention/dot_product_attention_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from numpy.testing import assert_almost_equal 3 | import numpy 4 | 5 | from allennlp.common import Params 6 | from allennlp.common.testing.test_case import AllenNlpTestCase 7 | from allennlp.modules.attention.attention import Attention 8 | from allennlp.modules.attention.dot_product_attention import DotProductAttention 9 | 10 | 11 | class TestDotProductAttention(AllenNlpTestCase): 12 | def test_can_init_dot(self): 13 | legacy_attention = Attention.from_params(Params({"type": "dot_product"})) 14 | isinstance(legacy_attention, DotProductAttention) 15 | 16 | def test_dot_product_similarity(self): 17 | linear = DotProductAttention(normalize=False) 18 | output = linear( 19 | torch.FloatTensor([[0, 0, 0], [1, 1, 1]]), 20 | torch.FloatTensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]), 21 | ) 22 | 23 | assert_almost_equal(output.numpy(), numpy.array([[0.0, 0.0], [24.0, 33.0]]), decimal=2) 24 | -------------------------------------------------------------------------------- /allennlp/modules/token_embedders/empty_embedder.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from allennlp.modules.token_embedders.token_embedder import TokenEmbedder 3 | 4 | 5 | @TokenEmbedder.register("empty") 6 | class EmptyEmbedder(TokenEmbedder): 7 | """ 8 | Assumes you want to completely ignore the output of a `TokenIndexer` for some reason, and does 9 | not return anything when asked to embed it. 10 | 11 | You should almost never need to use this; normally you would just not use a particular 12 | `TokenIndexer`. It's only in very rare cases, like simplicity in data processing for language 13 | modeling (where we use just one `TextField` to handle input embedding and computing target ids), 14 | where you might want to use this. 15 | 16 | Registered as a `TokenEmbedder` with name "empty". 17 | """ 18 | 19 | def __init__(self) -> None: 20 | super().__init__() 21 | 22 | def get_output_dim(self): 23 | return 0 24 | 25 | def forward(self, *inputs, **kwargs) -> torch.Tensor: 26 | return None 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This Dockerfile creates an environment suitable for downstream usage of AllenNLP. 2 | # It's built from a wheel installation of allennlp. 3 | 4 | FROM python:3.7 5 | 6 | ENV LC_ALL=C.UTF-8 7 | ENV LANG=C.UTF-8 8 | 9 | ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64 10 | 11 | # Tell nvidia-docker the driver spec that we need as well as to 12 | # use all available devices, which are mounted at /usr/local/nvidia. 13 | # The LABEL supports an older version of nvidia-docker, the env 14 | # variables a newer one. 15 | ENV NVIDIA_VISIBLE_DEVICES all 16 | ENV NVIDIA_DRIVER_CAPABILITIES compute,utility 17 | LABEL com.nvidia.volumes.needed="nvidia_driver" 18 | 19 | WORKDIR /stage/allennlp 20 | 21 | # Install the wheel of AllenNLP. 22 | COPY dist dist/ 23 | RUN pip install $(ls dist/*.whl) 24 | 25 | # Copy wrapper script to allow beaker to run resumable training workloads. 26 | COPY scripts/ai2_internal/resumable_train.sh /stage/allennlp 27 | 28 | LABEL maintainer="allennlp-contact@allenai.org" 29 | 30 | ENTRYPOINT ["allennlp"] 31 | -------------------------------------------------------------------------------- /allennlp/data/fields/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A :class:`~allennlp.data.fields.field.Field` is some piece of data instance 3 | that ends up as an array in a model. 4 | """ 5 | 6 | from allennlp.data.fields.field import Field 7 | from allennlp.data.fields.adjacency_field import AdjacencyField 8 | from allennlp.data.fields.array_field import ArrayField 9 | from allennlp.data.fields.flag_field import FlagField 10 | from allennlp.data.fields.index_field import IndexField 11 | from allennlp.data.fields.label_field import LabelField 12 | from allennlp.data.fields.list_field import ListField 13 | from allennlp.data.fields.metadata_field import MetadataField 14 | from allennlp.data.fields.multilabel_field import MultiLabelField 15 | from allennlp.data.fields.namespace_swapping_field import NamespaceSwappingField 16 | from allennlp.data.fields.sequence_field import SequenceField 17 | from allennlp.data.fields.sequence_label_field import SequenceLabelField 18 | from allennlp.data.fields.span_field import SpanField 19 | from allennlp.data.fields.text_field import TextField 20 | -------------------------------------------------------------------------------- /allennlp/modules/token_embedders/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A `TokenEmbedder` is a `Module` that 3 | embeds one-hot-encoded tokens as vectors. 4 | """ 5 | 6 | from allennlp.modules.token_embedders.token_embedder import TokenEmbedder 7 | from allennlp.modules.token_embedders.embedding import Embedding 8 | from allennlp.modules.token_embedders.token_characters_encoder import TokenCharactersEncoder 9 | from allennlp.modules.token_embedders.elmo_token_embedder import ElmoTokenEmbedder 10 | from allennlp.modules.token_embedders.empty_embedder import EmptyEmbedder 11 | from allennlp.modules.token_embedders.bag_of_word_counts_token_embedder import ( 12 | BagOfWordCountsTokenEmbedder, 13 | ) 14 | from allennlp.modules.token_embedders.pass_through_token_embedder import PassThroughTokenEmbedder 15 | from allennlp.modules.token_embedders.pretrained_transformer_embedder import ( 16 | PretrainedTransformerEmbedder, 17 | ) 18 | from allennlp.modules.token_embedders.pretrained_transformer_mismatched_embedder import ( 19 | PretrainedTransformerMismatchedEmbedder, 20 | ) 21 | -------------------------------------------------------------------------------- /tests/modules/highway_test.py: -------------------------------------------------------------------------------- 1 | from numpy.testing import assert_almost_equal 2 | import torch 3 | 4 | from allennlp.modules import Highway 5 | from allennlp.common.testing import AllenNlpTestCase 6 | 7 | 8 | class TestHighway(AllenNlpTestCase): 9 | def test_forward_works_on_simple_input(self): 10 | highway = Highway(2, 2) 11 | 12 | highway._layers[0].weight.data.fill_(1) 13 | highway._layers[0].bias.data.fill_(0) 14 | highway._layers[1].weight.data.fill_(2) 15 | highway._layers[1].bias.data.fill_(-2) 16 | input_tensor = torch.FloatTensor([[-2, 1], [3, -2]]) 17 | result = highway(input_tensor).data.numpy() 18 | assert result.shape == (2, 2) 19 | # This was checked by hand. 20 | assert_almost_equal(result, [[-0.0394, 0.0197], [1.7527, -0.5550]], decimal=4) 21 | 22 | def test_forward_works_on_nd_input(self): 23 | highway = Highway(2, 2) 24 | input_tensor = torch.ones(2, 2, 2) 25 | output = highway(input_tensor) 26 | assert output.size() == (2, 2, 2) 27 | -------------------------------------------------------------------------------- /tests/modules/masked_layer_norm_test.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | 4 | from allennlp.common.testing import AllenNlpTestCase 5 | from allennlp.modules.masked_layer_norm import MaskedLayerNorm 6 | from allennlp.nn import util 7 | 8 | 9 | class TestMaskedLayerNorm(AllenNlpTestCase): 10 | def test_masked_layer_norm(self): 11 | x_n = np.random.rand(2, 3, 7) 12 | mask_n = np.array([[1, 1, 0], [1, 1, 1]]) 13 | 14 | x = torch.from_numpy(x_n).float() 15 | mask = torch.from_numpy(mask_n).bool() 16 | 17 | layer_norm = MaskedLayerNorm(7, gamma0=0.2) 18 | normed_x = layer_norm(x, mask) 19 | 20 | N = 7 * 5 21 | mean = (x_n * np.expand_dims(mask_n, axis=-1)).sum() / N 22 | std = np.sqrt( 23 | (((x_n - mean) * np.expand_dims(mask_n, axis=-1)) ** 2).sum() / N 24 | + util.tiny_value_of_dtype(torch.float) 25 | ) 26 | expected = 0.2 * (x_n - mean) / (std + util.tiny_value_of_dtype(torch.float)) 27 | 28 | assert np.allclose(normed_x.data.numpy(), expected) 29 | -------------------------------------------------------------------------------- /allennlp/nn/regularizers/regularizers.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.nn.regularizers.regularizer import Regularizer 4 | 5 | 6 | @Regularizer.register("l1") 7 | class L1Regularizer(Regularizer): 8 | """ 9 | Represents a penalty proportional to the sum of the absolute values of the parameters 10 | 11 | Registered as a `Regularizer` with name "l1". 12 | """ 13 | 14 | def __init__(self, alpha: float = 0.01) -> None: 15 | self.alpha = alpha 16 | 17 | def __call__(self, parameter: torch.Tensor) -> torch.Tensor: 18 | return self.alpha * torch.sum(torch.abs(parameter)) 19 | 20 | 21 | @Regularizer.register("l2") 22 | class L2Regularizer(Regularizer): 23 | """ 24 | Represents a penalty proportional to the sum of squared values of the parameters 25 | 26 | Registered as a `Regularizer` with name "l2". 27 | """ 28 | 29 | def __init__(self, alpha: float = 0.01) -> None: 30 | self.alpha = alpha 31 | 32 | def __call__(self, parameter: torch.Tensor) -> torch.Tensor: 33 | return self.alpha * torch.sum(torch.pow(parameter, 2)) 34 | -------------------------------------------------------------------------------- /tests/common/plugins_test.py: -------------------------------------------------------------------------------- 1 | from overrides import overrides 2 | 3 | from allennlp.commands import Subcommand 4 | from allennlp.common.plugins import ( 5 | discover_plugins, 6 | import_plugins, 7 | ) 8 | from allennlp.common.testing import AllenNlpTestCase 9 | from allennlp.common.util import pushd 10 | 11 | 12 | class TestPlugins(AllenNlpTestCase): 13 | @overrides 14 | def setup_method(self): 15 | super().setup_method() 16 | self.plugins_root = self.FIXTURES_ROOT / "plugins" 17 | 18 | def test_no_plugins(self): 19 | available_plugins = set(discover_plugins()) 20 | assert available_plugins == set() 21 | 22 | def test_file_plugin(self): 23 | available_plugins = set(discover_plugins()) 24 | assert available_plugins == set() 25 | 26 | with pushd(self.plugins_root): 27 | available_plugins = set(discover_plugins()) 28 | assert available_plugins == {"d"} 29 | 30 | import_plugins() 31 | subcommands_available = Subcommand.list_available() 32 | assert "d" in subcommands_available 33 | -------------------------------------------------------------------------------- /allennlp/__init__.py: -------------------------------------------------------------------------------- 1 | # Make sure that allennlp is running on Python 3.6.1 or later 2 | # (to avoid running into this bug: https://bugs.python.org/issue29246) 3 | import sys 4 | 5 | if sys.version_info < (3, 6, 1): 6 | raise RuntimeError("AllenNLP requires Python 3.6.1 or later") 7 | 8 | # We get a lot of these spurious warnings, 9 | # see https://github.com/ContinuumIO/anaconda-issues/issues/6678 10 | import warnings # noqa 11 | 12 | warnings.filterwarnings("ignore", message="numpy.dtype size changed") 13 | warnings.filterwarnings("ignore", message="numpy.ufunc size changed") 14 | 15 | try: 16 | # On some systems this prevents the dreaded 17 | # ImportError: dlopen: cannot load any more object with static TLS 18 | import spacy, torch, numpy # noqa 19 | 20 | except ModuleNotFoundError: 21 | print( 22 | "Using AllenNLP requires the python packages Spacy, " 23 | "Pytorch and Numpy to be installed. Please see " 24 | "https://github.com/allenai/allennlp for installation instructions." 25 | ) 26 | raise 27 | 28 | from allennlp.version import VERSION as __version__ # noqa 29 | -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/common.jsonnet: -------------------------------------------------------------------------------- 1 | { 2 | "dataset_reader": { 3 | "lazy": false, 4 | "type": "text_classification_json", 5 | "tokenizer": { 6 | "type": "spacy" 7 | }, 8 | "token_indexers": { 9 | "tokens": { 10 | "type": "single_id", 11 | "namespace": "tokens", 12 | "lowercase_tokens": true 13 | } 14 | }, 15 | "max_sequence_length": 400 16 | }, 17 | "train_data_path": "test_fixtures/data/text_classification_json/imdb_corpus.jsonl", 18 | "validation_data_path": "test_fixtures/data/text_classification_json/imdb_corpus.jsonl", 19 | "data_loader": { 20 | 21 | "batch_sampler": { 22 | "type": "bucket", 23 | "batch_size": 5 24 | }, 25 | }, 26 | "trainer": { 27 | "optimizer": { 28 | "type": "adam", 29 | "lr": 0.001 30 | }, 31 | "validation_metric": "+accuracy", 32 | "num_epochs": 3, 33 | "grad_norm": 10.0, 34 | "patience": 5, 35 | "cuda_device": -1 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/data/token_indexers/spacy_indexer_test.py: -------------------------------------------------------------------------------- 1 | from allennlp.common.testing import AllenNlpTestCase 2 | from allennlp.data.token_indexers.spacy_indexer import SpacyTokenIndexer 3 | from allennlp.data.fields.text_field import TextField 4 | from allennlp.common.util import get_spacy_model 5 | from allennlp.data.vocabulary import Vocabulary 6 | 7 | 8 | class TestSpacyTokenIndexer(AllenNlpTestCase): 9 | def test_as_array_produces_token_array(self): 10 | indexer = SpacyTokenIndexer() 11 | nlp = get_spacy_model("en_core_web_sm", pos_tags=True, parse=False, ner=False) 12 | tokens = [t for t in nlp("This is a sentence.")] 13 | field = TextField(tokens, token_indexers={"spacy": indexer}) 14 | 15 | vocab = Vocabulary() 16 | field.index(vocab) 17 | 18 | # Indexer functionality 19 | array_dict = indexer.tokens_to_indices(tokens, vocab) 20 | assert len(array_dict["tokens"]) == 5 21 | assert len(array_dict["tokens"][0]) == 96 22 | 23 | # Check it also works with field 24 | lengths = field.get_padding_lengths() 25 | array_dict = field.as_tensor(lengths) 26 | 27 | assert list(array_dict["spacy"]["tokens"].shape) == [5, 96] 28 | -------------------------------------------------------------------------------- /allennlp/modules/masked_layer_norm.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.nn import util 4 | 5 | 6 | class MaskedLayerNorm(torch.nn.Module): 7 | """ 8 | See LayerNorm for details. 9 | 10 | Note, however, that unlike LayerNorm this norm includes a batch component. 11 | """ 12 | 13 | def __init__(self, size: int, gamma0: float = 0.1) -> None: 14 | super().__init__() 15 | self.gamma = torch.nn.Parameter(torch.ones(1, 1, size) * gamma0) 16 | self.beta = torch.nn.Parameter(torch.zeros(1, 1, size)) 17 | self.size = size 18 | 19 | def forward(self, tensor: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: 20 | 21 | broadcast_mask = mask.unsqueeze(-1) 22 | num_elements = broadcast_mask.sum() * self.size 23 | mean = (tensor * broadcast_mask).sum() / num_elements 24 | masked_centered = (tensor - mean) * broadcast_mask 25 | std = torch.sqrt( 26 | (masked_centered * masked_centered).sum() / num_elements 27 | + util.tiny_value_of_dtype(tensor.dtype) 28 | ) 29 | return ( 30 | self.gamma * (tensor - mean) / (std + util.tiny_value_of_dtype(tensor.dtype)) 31 | + self.beta 32 | ) 33 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/model_test_case.jsonnet: -------------------------------------------------------------------------------- 1 | { 2 | "dataset_reader":{"type":"sequence_tagging"}, 3 | "train_data_path": "test_fixtures/data/sequence_tagging.tsv", 4 | "validation_data_path": "test_fixtures/data/sequence_tagging.tsv", 5 | "model": { 6 | "type": "simple_tagger", 7 | "text_field_embedder": { 8 | "token_embedders": { 9 | "tokens": { 10 | "type": "embedding", 11 | "projection_dim": 2, 12 | "pretrained_file": "test_fixtures/embeddings/glove.6B.100d.sample.txt.gz", 13 | "embedding_dim": 100, 14 | "trainable": true 15 | } 16 | } 17 | }, 18 | "encoder": { 19 | "type": "lstm", 20 | "input_size": 2, 21 | "hidden_size": 4, 22 | "num_layers": 1 23 | } 24 | }, 25 | "data_loader": { 26 | "batch_sampler": { 27 | "type": "bucket", 28 | "sorting_keys": ["tokens"], 29 | "padding_noise": 0.0, 30 | "batch_size" : 80 31 | } 32 | }, 33 | "trainer": { 34 | "num_epochs": 40, 35 | "grad_norm": 1.0, 36 | "patience": 500, 37 | "cuda_device": -1, 38 | "optimizer": { 39 | "type": "adam", 40 | "lr": 0.01 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/experiment.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataset_reader":{"type":"sequence_tagging"}, 3 | "train_data_path": "test_fixtures/data/sequence_tagging.tsv", 4 | "validation_data_path": "test_fixtures/data/sequence_tagging.tsv", 5 | "model": { 6 | "type": "simple_tagger", 7 | "text_field_embedder": { 8 | "token_embedders": { 9 | "tokens": { 10 | "type": "embedding", 11 | "projection_dim": 2, 12 | "pretrained_file": "test_fixtures/embeddings/glove.6B.100d.sample.txt.gz", 13 | "embedding_dim": 100, 14 | "trainable": true 15 | } 16 | } 17 | }, 18 | "encoder": { 19 | "type": "lstm", 20 | "input_size": 2, 21 | "hidden_size": 4, 22 | "num_layers": 1 23 | } 24 | }, 25 | "data_loader": { 26 | "batch_sampler": { 27 | "type": "bucket", 28 | "sorting_keys": ["tokens"], 29 | "padding_noise": 0.0, 30 | "batch_size" : 80 31 | } 32 | }, 33 | "trainer": { 34 | "num_epochs": 1, 35 | "grad_norm": 1.0, 36 | "patience": 500, 37 | "cuda_device": -1, 38 | "optimizer": { 39 | "type": "adadelta", 40 | "lr": 0.000001, 41 | "rho": 0.95 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_elmo/experiment.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataset_reader": { 3 | "type": "conll2003", 4 | "tag_label": "ner", 5 | "coding_scheme": "BIOUL", 6 | "token_indexers": { 7 | "elmo": { 8 | "type": "elmo_characters" 9 | } 10 | } 11 | }, 12 | "train_data_path": "test_fixtures/data/conll2003.txt", 13 | "validation_data_path": "test_fixtures/data/conll2003.txt", 14 | "model": { 15 | "type": "simple_tagger", 16 | "text_field_embedder": { 17 | "token_embedders": { 18 | "elmo": { 19 | "type": "elmo_token_embedder", 20 | "options_file": "test_fixtures/elmo/options.json", 21 | "weight_file": "test_fixtures/elmo/lm_weights.hdf5" 22 | } 23 | } 24 | }, 25 | "encoder": { 26 | "type": "gru", 27 | "input_size": 32, 28 | "hidden_size": 25, 29 | "num_layers": 2, 30 | "dropout": 0.5, 31 | "bidirectional": true 32 | }, 33 | "regularizer": { 34 | "regexes": [ 35 | ["transitions$", {"type": "l2", "alpha": 0.01}] 36 | ] 37 | } 38 | }, 39 | "data_loader": {"batch_size": 32}, 40 | "trainer": { 41 | "optimizer": "adam", 42 | "num_epochs": 5, 43 | "cuda_device": -1 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /allennlp/modules/softmax_loss.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import numpy as np 3 | 4 | 5 | class SoftmaxLoss(torch.nn.Module): 6 | """ 7 | Given some embeddings and some targets, applies a linear layer 8 | to create logits over possible words and then returns the 9 | negative log likelihood. 10 | """ 11 | 12 | def __init__(self, num_words: int, embedding_dim: int) -> None: 13 | super().__init__() 14 | 15 | # TODO(joelgrus): implement tie_embeddings (maybe) 16 | self.tie_embeddings = False 17 | 18 | self.softmax_w = torch.nn.Parameter( 19 | torch.randn(embedding_dim, num_words) / np.sqrt(embedding_dim) 20 | ) 21 | self.softmax_b = torch.nn.Parameter(torch.zeros(num_words)) 22 | 23 | def forward(self, embeddings: torch.Tensor, targets: torch.Tensor) -> torch.Tensor: 24 | 25 | # embeddings is size (n, embedding_dim) 26 | # targets is (batch_size, ) with the correct class id 27 | # Does not do any count normalization / divide by batch size 28 | probs = torch.nn.functional.log_softmax( 29 | torch.matmul(embeddings, self.softmax_w) + self.softmax_b, dim=-1 30 | ) 31 | 32 | return torch.nn.functional.nll_loss(probs, targets.long(), reduction="sum") 33 | -------------------------------------------------------------------------------- /allennlp/modules/layer_norm.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.nn import util 4 | 5 | 6 | class LayerNorm(torch.nn.Module): 7 | 8 | """ 9 | An implementation of [Layer Normalization]( 10 | https://www.semanticscholar.org/paper/Layer-Normalization-Ba-Kiros/97fb4e3d45bb098e27e0071448b6152217bd35a5). 11 | 12 | Layer Normalization stabilises the training of deep neural networks by 13 | normalising the outputs of neurons from a particular layer. It computes: 14 | 15 | output = (gamma * (tensor - mean) / (std + eps)) + beta 16 | 17 | # Parameters 18 | 19 | dimension : `int`, required. 20 | The dimension of the layer output to normalize. 21 | 22 | # Returns 23 | 24 | The normalized layer output. 25 | """ # noqa 26 | 27 | def __init__(self, dimension: int) -> None: 28 | super().__init__() 29 | self.gamma = torch.nn.Parameter(torch.ones(dimension)) 30 | self.beta = torch.nn.Parameter(torch.zeros(dimension)) 31 | 32 | def forward(self, tensor: torch.Tensor): 33 | mean = tensor.mean(-1, keepdim=True) 34 | std = tensor.std(-1, unbiased=False, keepdim=True) 35 | return ( 36 | self.gamma * (tensor - mean) / (std + util.tiny_value_of_dtype(std.dtype)) + self.beta 37 | ) 38 | -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | #### TESTING-RELATED PACKAGES #### 2 | 3 | # Checks style, syntax, and other useful errors. 4 | flake8 5 | 6 | # Static type checking 7 | mypy==0.780 8 | 9 | # Automatic code formatting 10 | black 11 | 12 | # Allows generation of coverage reports with pytest. 13 | pytest-cov 14 | 15 | # Allows codecov to generate coverage reports 16 | coverage 17 | codecov 18 | 19 | # Optional dependencies, which we install for testing purposes. 20 | matplotlib>=2.2.3 21 | 22 | # Required for automatic mixed precision (AMP) training 23 | git+https://github.com/NVIDIA/apex.git@master 24 | 25 | # For mocking HTTP requests/responses. 26 | responses>=0.7 27 | 28 | # For running tests that aren't 100% reliable. 29 | flaky 30 | 31 | # For running benchmarks. 32 | pytest-benchmark 33 | 34 | #### DOC-RELATED PACKAGES #### 35 | 36 | # YAML manipulation 37 | ruamel.yaml 38 | 39 | # Generating markdown files from Python modules. 40 | git+https://github.com/NiklasRosenstein/pydoc-markdown.git@f0bf8af1db4f11581c19d206d4ed1ab34b4854c1 41 | nr.databind.core<0.0.17 42 | nr.interface<0.0.4 43 | 44 | markdown-include==0.5.1 45 | # Package for the material theme for mkdocs 46 | mkdocs-material==5.3.0 47 | 48 | #### PACKAGE-UPLOAD PACKAGES #### 49 | 50 | # Pypi uploads 51 | twine>=1.11.0 52 | setuptools 53 | wheel 54 | -------------------------------------------------------------------------------- /tests/modules/seq2seq_encoders/pass_through_encoder_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import numpy 3 | 4 | from allennlp.common.testing import AllenNlpTestCase 5 | from allennlp.modules.seq2seq_encoders import PassThroughEncoder 6 | 7 | 8 | class TestPassThroughEncoder(AllenNlpTestCase): 9 | def test_get_dimension_is_correct(self): 10 | encoder = PassThroughEncoder(input_dim=9) 11 | assert encoder.get_input_dim() == 9 12 | assert encoder.get_output_dim() == 9 13 | 14 | def test_pass_through_encoder_passes_through(self): 15 | encoder = PassThroughEncoder(input_dim=9) 16 | tensor = torch.randn([2, 3, 9]) 17 | output = encoder(tensor) 18 | numpy.testing.assert_array_almost_equal( 19 | tensor.detach().cpu().numpy(), output.detach().cpu().numpy() 20 | ) 21 | 22 | def test_pass_through_encoder_with_mask(self): 23 | encoder = PassThroughEncoder(input_dim=9) 24 | tensor = torch.randn([2, 3, 9]) 25 | mask = torch.tensor([[True, True, True], [True, False, False]]) 26 | output = encoder(tensor, mask) 27 | 28 | target = tensor * mask.unsqueeze(dim=-1).float() 29 | numpy.testing.assert_array_almost_equal( 30 | output.detach().cpu().numpy(), target.detach().cpu().numpy() 31 | ) 32 | -------------------------------------------------------------------------------- /allennlp/tools/EVALB/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /scripts/get_version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import argparse 4 | from typing import Dict 5 | 6 | import requests 7 | 8 | 9 | def parse_args(): 10 | parser = argparse.ArgumentParser() 11 | parser.add_argument("version_type", choices=["stable", "latest", "current"]) 12 | return parser.parse_args() 13 | 14 | 15 | def get_current_version() -> str: 16 | VERSION: Dict[str, str] = {} 17 | with open("allennlp/version.py", "r") as version_file: 18 | exec(version_file.read(), VERSION) 19 | return "v" + VERSION["VERSION"] 20 | 21 | 22 | def get_latest_version() -> str: 23 | resp = requests.get("https://api.github.com/repos/allenai/allennlp/tags") 24 | return resp.json()[0]["name"] 25 | 26 | 27 | def get_stable_version() -> str: 28 | resp = requests.get("https://api.github.com/repos/allenai/allennlp/releases/latest") 29 | return resp.json()["tag_name"] 30 | 31 | 32 | def main() -> None: 33 | opts = parse_args() 34 | if opts.version_type == "stable": 35 | print(get_stable_version()) 36 | elif opts.version_type == "latest": 37 | print(get_latest_version()) 38 | elif opts.version_type == "current": 39 | print(get_current_version()) 40 | else: 41 | raise NotImplementedError 42 | 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /tests/training/no_op_trainer_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Dict 3 | 4 | import torch 5 | 6 | from allennlp.common.testing import AllenNlpTestCase 7 | from allennlp.data import Vocabulary 8 | from allennlp.data.dataset_readers import SequenceTaggingDatasetReader 9 | from allennlp.models.model import Model 10 | from allennlp.training import NoOpTrainer 11 | 12 | 13 | class ConstantModel(Model): 14 | def forward(self, *inputs) -> Dict[str, torch.Tensor]: 15 | return {"class": torch.tensor(98)} 16 | 17 | 18 | class TestNoOpTrainer(AllenNlpTestCase): 19 | def setup_method(self): 20 | super().setup_method() 21 | self.instances = SequenceTaggingDatasetReader().read( 22 | self.FIXTURES_ROOT / "data" / "sequence_tagging.tsv" 23 | ) 24 | vocab = Vocabulary.from_instances(self.instances) 25 | self.vocab = vocab 26 | self.model = ConstantModel(vocab) 27 | 28 | def test_trainer_serializes(self): 29 | serialization_dir = self.TEST_DIR / "serialization_dir" 30 | trainer = NoOpTrainer(serialization_dir=serialization_dir, model=self.model) 31 | metrics = trainer.train() 32 | assert metrics == {} 33 | assert os.path.exists(serialization_dir / "best.th") 34 | assert os.path.exists(serialization_dir / "vocabulary") 35 | -------------------------------------------------------------------------------- /tests/modules/seq2vec_encoders/cls_pooler_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import torch 3 | 4 | from allennlp.common.testing import AllenNlpTestCase 5 | from allennlp.modules.seq2vec_encoders.cls_pooler import ClsPooler 6 | 7 | 8 | class TestClsPooler(AllenNlpTestCase): 9 | def test_encoder(self): 10 | embedding = torch.rand(5, 50, 7) 11 | encoder = ClsPooler(embedding_dim=7) 12 | pooled = encoder(embedding, mask=None) 13 | 14 | assert list(pooled.size()) == [5, 7] 15 | numpy.testing.assert_array_almost_equal(embedding[:, 0], pooled) 16 | 17 | def test_cls_at_end(self): 18 | embedding = torch.arange(20).reshape(5, 4).unsqueeze(-1).expand(5, 4, 7) 19 | mask = torch.tensor( 20 | [ 21 | [True, True, True, True], 22 | [True, True, True, False], 23 | [True, True, True, True], 24 | [True, False, False, False], 25 | [True, True, False, False], 26 | ] 27 | ) 28 | expected = torch.LongTensor([3, 6, 11, 12, 17]).unsqueeze(-1).expand(5, 7) 29 | 30 | encoder = ClsPooler(embedding_dim=7, cls_is_last_token=True) 31 | pooled = encoder(embedding, mask=mask) 32 | 33 | assert list(pooled.size()) == [5, 7] 34 | numpy.testing.assert_array_almost_equal(expected, pooled) 35 | -------------------------------------------------------------------------------- /tests/modules/seq2vec_encoders/cnn_highway_encoder_test.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | 4 | from allennlp.common.testing import AllenNlpTestCase 5 | from allennlp.modules.seq2vec_encoders.cnn_highway_encoder import CnnHighwayEncoder 6 | from allennlp.modules.time_distributed import TimeDistributed 7 | 8 | 9 | class TestCnnHighwayEncoder(AllenNlpTestCase): 10 | def run_encoder_against_random_embeddings(self, do_layer_norm): 11 | encoder = CnnHighwayEncoder( 12 | activation="relu", 13 | embedding_dim=4, 14 | filters=[[1, 4], [2, 8], [3, 16], [4, 32], [5, 64]], 15 | num_highway=2, 16 | projection_dim=16, 17 | projection_location="after_cnn", 18 | do_layer_norm=do_layer_norm, 19 | ) 20 | encoder = TimeDistributed(encoder) 21 | 22 | embedding = torch.from_numpy(np.random.randn(5, 6, 50, 4)).float() 23 | mask = torch.ones(5, 6, 50).bool() 24 | token_embedding = encoder(embedding, mask) 25 | 26 | assert list(token_embedding.size()) == [5, 6, 16] 27 | 28 | def test_cnn_highway_encoder(self): 29 | self.run_encoder_against_random_embeddings(do_layer_norm=False) 30 | 31 | def test_cnn_highway_encoder_with_layer_norm(self): 32 | self.run_encoder_against_random_embeddings(do_layer_norm=True) 33 | -------------------------------------------------------------------------------- /allennlp/modules/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Custom PyTorch 3 | `Module `_ s 4 | that are used as components in AllenNLP `Model` s. 5 | """ 6 | 7 | from allennlp.modules.attention import Attention 8 | from allennlp.modules.bimpm_matching import BiMpmMatching 9 | from allennlp.modules.conditional_random_field import ConditionalRandomField 10 | from allennlp.modules.elmo import Elmo 11 | from allennlp.modules.feedforward import FeedForward 12 | from allennlp.modules.gated_sum import GatedSum 13 | from allennlp.modules.highway import Highway 14 | from allennlp.modules.input_variational_dropout import InputVariationalDropout 15 | from allennlp.modules.layer_norm import LayerNorm 16 | from allennlp.modules.matrix_attention import MatrixAttention 17 | from allennlp.modules.maxout import Maxout 18 | from allennlp.modules.residual_with_layer_dropout import ResidualWithLayerDropout 19 | from allennlp.modules.scalar_mix import ScalarMix 20 | from allennlp.modules.seq2seq_encoders import Seq2SeqEncoder 21 | from allennlp.modules.seq2vec_encoders import Seq2VecEncoder 22 | from allennlp.modules.text_field_embedders import TextFieldEmbedder 23 | from allennlp.modules.time_distributed import TimeDistributed 24 | from allennlp.modules.token_embedders import TokenEmbedder, Embedding 25 | from allennlp.modules.softmax_loss import SoftmaxLoss 26 | -------------------------------------------------------------------------------- /allennlp/modules/seq2vec_encoders/seq2vec_encoder.py: -------------------------------------------------------------------------------- 1 | from allennlp.modules.encoder_base import _EncoderBase 2 | from allennlp.common import Registrable 3 | 4 | 5 | class Seq2VecEncoder(_EncoderBase, Registrable): 6 | """ 7 | A `Seq2VecEncoder` is a `Module` that takes as input a sequence of vectors and returns a 8 | single vector. Input shape : `(batch_size, sequence_length, input_dim)`; output shape: 9 | `(batch_size, output_dim)`. 10 | 11 | We add two methods to the basic `Module` API: `get_input_dim()` and `get_output_dim()`. 12 | You might need this if you want to construct a `Linear` layer using the output of this encoder, 13 | or to raise sensible errors for mis-matching input dimensions. 14 | """ 15 | 16 | def get_input_dim(self) -> int: 17 | """ 18 | Returns the dimension of the vector input for each element in the sequence input 19 | to a `Seq2VecEncoder`. This is `not` the shape of the input tensor, but the 20 | last element of that shape. 21 | """ 22 | raise NotImplementedError 23 | 24 | def get_output_dim(self) -> int: 25 | """ 26 | Returns the dimension of the final vector output by this `Seq2VecEncoder`. This is `not` 27 | the shape of the returned tensor, but the last element of that shape. 28 | """ 29 | raise NotImplementedError 30 | -------------------------------------------------------------------------------- /tests/modules/gated_sum_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import torch 3 | 4 | import numpy 5 | 6 | from allennlp.common.testing import AllenNlpTestCase 7 | from allennlp.modules import GatedSum 8 | 9 | 10 | class TestGatedSum(AllenNlpTestCase): 11 | def test_gated_sum_can_run_forward(self): 12 | a = torch.FloatTensor([1, 2, 3, 4, 5]) 13 | b = -a + 0.1 14 | weight_value = 2 15 | gate_value = torch.sigmoid(torch.FloatTensor([1])) 16 | expected = gate_value * a + (1 - gate_value) * b 17 | 18 | with torch.no_grad(): # because we want to change the weight 19 | gated_sum = GatedSum(a.size(-1)) 20 | gated_sum._gate.weight *= 0 21 | gated_sum._gate.weight += weight_value 22 | gated_sum._gate.bias *= 0 23 | 24 | out = gated_sum(a, b) 25 | numpy.testing.assert_almost_equal(expected.data.numpy(), out.data.numpy(), decimal=5) 26 | 27 | with pytest.raises(ValueError): 28 | GatedSum(a.size(-1))(a, b.unsqueeze(0)) 29 | 30 | with pytest.raises(ValueError): 31 | GatedSum(100)(a, b) 32 | 33 | def test_input_output_dim(self): 34 | dim = 77 35 | gated_sum = GatedSum(dim) 36 | numpy.testing.assert_equal(gated_sum.get_input_dim(), dim) 37 | numpy.testing.assert_equal(gated_sum.get_output_dim(), dim) 38 | -------------------------------------------------------------------------------- /allennlp/interpret/saliency_interpreters/saliency_interpreter.py: -------------------------------------------------------------------------------- 1 | from allennlp.common import Registrable 2 | from allennlp.common.util import JsonDict 3 | from allennlp.predictors import Predictor 4 | 5 | 6 | class SaliencyInterpreter(Registrable): 7 | """ 8 | A `SaliencyInterpreter` interprets an AllenNLP Predictor's outputs by assigning a saliency 9 | score to each input token. 10 | """ 11 | 12 | def __init__(self, predictor: Predictor) -> None: 13 | self.predictor = predictor 14 | 15 | def saliency_interpret_from_json(self, inputs: JsonDict) -> JsonDict: 16 | """ 17 | This function finds saliency values for each input token. 18 | 19 | # Parameters 20 | 21 | inputs : `JsonDict` 22 | The input you want to interpret (the same as the argument to a Predictor, e.g., predict_json()). 23 | 24 | # Returns 25 | 26 | interpretation : `JsonDict` 27 | Contains the normalized saliency values for each input token. The dict has entries for 28 | each instance in the inputs JsonDict, e.g., `{instance_1: ..., instance_2:, ... }`. 29 | Each one of those entries has entries for the saliency of the inputs, e.g., 30 | `{grad_input_1: ..., grad_input_2: ... }`. 31 | """ 32 | raise NotImplementedError("Implement this for saliency interpretations") 33 | -------------------------------------------------------------------------------- /test_fixtures/basic_classifier/experiment_seq2seq.jsonnet: -------------------------------------------------------------------------------- 1 | local COMMON = import 'common.jsonnet'; 2 | 3 | { 4 | "dataset_reader": COMMON['dataset_reader'], 5 | "datasets_for_vocab_creation": ["train"], 6 | "train_data_path": COMMON['train_data_path'], 7 | "validation_data_path": COMMON['validation_data_path'], 8 | "model": { 9 | "type": "basic_classifier", 10 | "text_field_embedder": { 11 | "token_embedders": { 12 | "tokens": { 13 | "type": "embedding", 14 | "embedding_dim": 10, 15 | "trainable": true 16 | } 17 | } 18 | }, 19 | "seq2seq_encoder": { 20 | "type": "lstm", 21 | "num_layers": 1, 22 | "bidirectional": false, 23 | "input_size": 10, 24 | "hidden_size": 16 25 | }, 26 | "seq2vec_encoder": { 27 | "type": "bag_of_embeddings", 28 | "embedding_dim": 16, 29 | "averaged": true 30 | }, 31 | "feedforward": { 32 | "input_dim": 16, 33 | "num_layers": 1, 34 | "hidden_dims": 20, 35 | "activations": "relu", 36 | "dropout": 0.1 37 | } 38 | }, 39 | "data_loader": COMMON['data_loader'], 40 | "trainer": COMMON['trainer'] 41 | } 42 | -------------------------------------------------------------------------------- /tests/data/fields/flag_field_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from allennlp.common.testing.test_case import AllenNlpTestCase 4 | from allennlp.data.fields import FlagField 5 | 6 | 7 | class TestFlagField(AllenNlpTestCase): 8 | def test_get_padding_lengths_returns_nothing(self): 9 | flag_field = FlagField(True) 10 | assert flag_field.get_padding_lengths() == {} 11 | 12 | def test_as_tensor_just_returns_value(self): 13 | for value in [True, 3.234, "this is a string"]: 14 | assert FlagField(value).as_tensor({}) == value 15 | 16 | def test_printing_doesnt_crash(self): 17 | flag = FlagField(True) 18 | print(flag) 19 | 20 | def test_batch_tensors_returns_single_value(self): 21 | value = True 22 | fields = [FlagField(value) for _ in range(5)] 23 | values = [field.as_tensor({}) for field in fields] 24 | batched_value = fields[0].batch_tensors(values) 25 | assert batched_value == value 26 | 27 | def test_batch_tensors_crashes_with_non_uniform_values(self): 28 | field = FlagField(True) 29 | with pytest.raises(ValueError): 30 | field.batch_tensors([True, False, True]) 31 | 32 | with pytest.raises(ValueError): 33 | field.batch_tensors([1, 2, 3, 4]) 34 | 35 | with pytest.raises(ValueError): 36 | field.batch_tensors(["different", "string", "flags"]) 37 | -------------------------------------------------------------------------------- /allennlp/modules/input_variational_dropout.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | 4 | class InputVariationalDropout(torch.nn.Dropout): 5 | """ 6 | Apply the dropout technique in Gal and Ghahramani, [Dropout as a Bayesian Approximation: 7 | Representing Model Uncertainty in Deep Learning](https://arxiv.org/abs/1506.02142) to a 8 | 3D tensor. 9 | 10 | This module accepts a 3D tensor of shape `(batch_size, num_timesteps, embedding_dim)` 11 | and samples a single dropout mask of shape `(batch_size, embedding_dim)` and applies 12 | it to every time step. 13 | """ 14 | 15 | def forward(self, input_tensor): 16 | 17 | """ 18 | Apply dropout to input tensor. 19 | 20 | # Parameters 21 | 22 | input_tensor : `torch.FloatTensor` 23 | A tensor of shape `(batch_size, num_timesteps, embedding_dim)` 24 | 25 | # Returns 26 | 27 | output : `torch.FloatTensor` 28 | A tensor of shape `(batch_size, num_timesteps, embedding_dim)` with dropout applied. 29 | """ 30 | ones = input_tensor.data.new_ones(input_tensor.shape[0], input_tensor.shape[-1]) 31 | dropout_mask = torch.nn.functional.dropout(ones, self.p, self.training, inplace=False) 32 | if self.inplace: 33 | input_tensor *= dropout_mask.unsqueeze(1) 34 | return None 35 | else: 36 | return dropout_mask.unsqueeze(1) * input_tensor 37 | -------------------------------------------------------------------------------- /tests/data/dataset_readers/babi_reader_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from allennlp.common import Params 4 | from allennlp.common.util import ensure_list 5 | from allennlp.data.dataset_readers import BabiReader 6 | from allennlp.common.testing import AllenNlpTestCase 7 | 8 | 9 | class TestBAbIReader: 10 | @pytest.mark.parametrize( 11 | "keep_sentences, lazy", [(False, False), (False, True), (True, False), (True, True)] 12 | ) 13 | def test_read_from_file(self, keep_sentences, lazy): 14 | reader = BabiReader(keep_sentences=keep_sentences, lazy=lazy) 15 | instances = ensure_list(reader.read(AllenNlpTestCase.FIXTURES_ROOT / "data" / "babi.txt")) 16 | assert len(instances) == 8 17 | 18 | if keep_sentences: 19 | assert [t.text for t in instances[0].fields["context"][3].tokens[3:]] == [ 20 | "of", 21 | "wolves", 22 | ".", 23 | ] 24 | assert [t.sequence_index for t in instances[0].fields["supports"]] == [0, 1] 25 | else: 26 | assert [t.text for t in instances[0].fields["context"].tokens[7:9]] == ["afraid", "of"] 27 | 28 | def test_can_build_from_params(self): 29 | reader = BabiReader.from_params(Params({"keep_sentences": True})) 30 | 31 | assert reader._keep_sentences 32 | assert reader._token_indexers["tokens"].__class__.__name__ == "SingleIdTokenIndexer" 33 | -------------------------------------------------------------------------------- /allennlp/training/metrics/average.py: -------------------------------------------------------------------------------- 1 | from overrides import overrides 2 | 3 | from allennlp.training.metrics.metric import Metric 4 | 5 | 6 | @Metric.register("average") 7 | class Average(Metric): 8 | """ 9 | This [`Metric`](./metric.md) breaks with the typical `Metric` API and just stores values that were 10 | computed in some fashion outside of a `Metric`. If you have some external code that computes 11 | the metric for you, for instance, you can use this to report the average result using our 12 | `Metric` API. 13 | """ 14 | 15 | def __init__(self) -> None: 16 | self._total_value = 0.0 17 | self._count = 0 18 | 19 | @overrides 20 | def __call__(self, value): 21 | """ 22 | # Parameters 23 | 24 | value : `float` 25 | The value to average. 26 | """ 27 | self._total_value += list(self.detach_tensors(value))[0] 28 | self._count += 1 29 | 30 | @overrides 31 | def get_metric(self, reset: bool = False): 32 | """ 33 | # Returns 34 | 35 | The average of all values that were passed to `__call__`. 36 | """ 37 | average_value = self._total_value / self._count if self._count > 0 else 0 38 | if reset: 39 | self.reset() 40 | return average_value 41 | 42 | @overrides 43 | def reset(self): 44 | self._total_value = 0.0 45 | self._count = 0 46 | -------------------------------------------------------------------------------- /tests/modules/stacked_alternating_lstm_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import torch 3 | from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence 4 | 5 | from allennlp.modules.stacked_alternating_lstm import StackedAlternatingLstm 6 | from allennlp.common.testing import AllenNlpTestCase 7 | 8 | 9 | class TestStackedAlternatingLstm(AllenNlpTestCase): 10 | def test_stacked_alternating_lstm_completes_forward_pass(self): 11 | input_tensor = torch.rand(4, 5, 3) 12 | input_tensor[1, 4:, :] = 0.0 13 | input_tensor[2, 2:, :] = 0.0 14 | input_tensor[3, 1:, :] = 0.0 15 | input_tensor = pack_padded_sequence(input_tensor, [5, 4, 2, 1], batch_first=True) 16 | lstm = StackedAlternatingLstm(3, 7, 3) 17 | output, _ = lstm(input_tensor) 18 | output_sequence, _ = pad_packed_sequence(output, batch_first=True) 19 | numpy.testing.assert_array_equal(output_sequence.data[1, 4:, :].numpy(), 0.0) 20 | numpy.testing.assert_array_equal(output_sequence.data[2, 2:, :].numpy(), 0.0) 21 | numpy.testing.assert_array_equal(output_sequence.data[3, 1:, :].numpy(), 0.0) 22 | 23 | def test_lstms_are_interleaved(self): 24 | lstm = StackedAlternatingLstm(3, 7, 8) 25 | for i, layer in enumerate(lstm.lstm_layers): 26 | if i % 2 == 0: 27 | assert layer.go_forward 28 | else: 29 | assert not layer.go_forward 30 | -------------------------------------------------------------------------------- /allennlp/training/no_op_trainer.py: -------------------------------------------------------------------------------- 1 | import os 2 | from contextlib import contextmanager 3 | from typing import Any, Dict, Iterator, Tuple 4 | 5 | from allennlp.models import Model 6 | from allennlp.training.checkpointer import Checkpointer 7 | from allennlp.training.trainer import Trainer 8 | 9 | 10 | @Trainer.register("no_op") 11 | class NoOpTrainer(Trainer): 12 | """ 13 | Registered as a `Trainer` with name "no_op". 14 | """ 15 | 16 | def __init__(self, serialization_dir: str, model: Model) -> None: 17 | """ 18 | A trivial trainer to assist in making model archives for models that do not actually 19 | require training. For instance, a majority class baseline. 20 | 21 | In a typical AllenNLP configuration file, neither the `serialization_dir` nor the `model` 22 | arguments would need an entry. 23 | """ 24 | 25 | super().__init__(serialization_dir, cuda_device=-1) 26 | self.model = model 27 | 28 | def train(self) -> Dict[str, Any]: 29 | self.model.vocab.save_to_files(os.path.join(self._serialization_dir, "vocabulary")) 30 | 31 | checkpointer = Checkpointer(self._serialization_dir) 32 | checkpointer.save_checkpoint(epoch=0, trainer=self, is_best_so_far=True) 33 | return {} 34 | 35 | @contextmanager 36 | def get_checkpoint_state(self) -> Iterator[Tuple[Dict[str, Any], Dict[str, Any]]]: 37 | yield self.model.state_dict(), {} 38 | -------------------------------------------------------------------------------- /scripts/check_large_files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # if any command inside script returns error, exit and return that error 4 | set -e 5 | 6 | # magic line to ensure that we're always inside the root of our application, 7 | # no matter from which directory we'll run script 8 | # thanks to it we can just enter `./scripts/run-tests.bash` 9 | cd "${0%/*}/.." 10 | 11 | # let's fake failing test for now 12 | echo "Running tests" 13 | echo "............................" 14 | 15 | SIZE=$1 16 | 17 | # Get the current branch. 18 | # branch=$(git branch | grep \* | cut -d ' ' -f2) 19 | declare -a large_files=() 20 | # Get all changed files (compared to master branch) 21 | for path in $(git diff --name-only master | sed -e 's/A[[:space:]]//'); 22 | do 23 | # Check to see if any sizes are greater than 2MB 24 | large_files+=($(du -m $path | awk -v size="$SIZE" '{if ($1 > size) print $2}')) 25 | done 26 | 27 | # Result 28 | if [ ${#large_files[@]} -gt 0 ]; 29 | then 30 | # Display result 31 | echo "Found ${#large_files[@]} files have size bigger than "$SIZE" MB" 32 | echo "--------------------------------------------------------" 33 | for file in ${large_files[@]}; 34 | do 35 | echo $file 36 | done 37 | echo "--------------------------------------------------------" 38 | echo "Please reduce file size before commit." 39 | echo "Failed to commit!" && exit 1 40 | else 41 | echo "Passed" && exit 0 42 | fi -------------------------------------------------------------------------------- /tests/modules/seq2vec_encoder_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from allennlp.common import Params 4 | from allennlp.common.checks import ConfigurationError 5 | from allennlp.modules import Seq2VecEncoder 6 | from allennlp.common.testing import AllenNlpTestCase 7 | 8 | 9 | class TestSeq2VecEncoder(AllenNlpTestCase): 10 | def test_from_params_builders_encoder_correctly(self): 11 | # We're just making sure parameters get passed through correctly here, and that the basic 12 | # API works. 13 | params = Params( 14 | { 15 | "type": "lstm", 16 | "bidirectional": True, 17 | "num_layers": 3, 18 | "input_size": 5, 19 | "hidden_size": 7, 20 | } 21 | ) 22 | encoder = Seq2VecEncoder.from_params(params) 23 | 24 | assert encoder.__class__.__name__ == "LstmSeq2VecEncoder" 25 | assert encoder._module.__class__.__name__ == "LSTM" 26 | assert encoder._module.num_layers == 3 27 | assert encoder._module.input_size == 5 28 | assert encoder._module.hidden_size == 7 29 | assert encoder._module.bidirectional is True 30 | assert encoder._module.batch_first is True 31 | 32 | def test_from_params_requires_batch_first(self): 33 | params = Params({"type": "lstm", "batch_first": False}) 34 | with pytest.raises(ConfigurationError): 35 | Seq2VecEncoder.from_params(params) 36 | -------------------------------------------------------------------------------- /allennlp/common/testing/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Utilities and helpers for writing tests. 3 | """ 4 | import torch 5 | import pytest 6 | 7 | from allennlp.common.testing.test_case import AllenNlpTestCase 8 | from allennlp.common.testing.model_test_case import ModelTestCase 9 | 10 | 11 | _available_devices = ["cpu"] + (["cuda"] if torch.cuda.is_available() else []) 12 | 13 | 14 | def multi_device(test_method): 15 | """ 16 | Decorator that provides an argument `device` of type `str` for each available PyTorch device. 17 | """ 18 | return pytest.mark.parametrize("device", _available_devices)(pytest.mark.gpu(test_method)) 19 | 20 | 21 | def requires_gpu(test_method): 22 | """ 23 | Decorator to indicate that a test requires a GPU device. 24 | """ 25 | return pytest.mark.gpu( 26 | pytest.mark.skipif(not torch.cuda.is_available(), reason="No CUDA device registered.")( 27 | test_method 28 | ) 29 | ) 30 | 31 | 32 | def requires_multi_gpu(test_method): 33 | """ 34 | Decorator to indicate that a test requires multiple GPU devices. 35 | """ 36 | return pytest.mark.gpu( 37 | pytest.mark.skipif(torch.cuda.device_count() < 2, reason="2 or more GPUs required.")( 38 | test_method 39 | ) 40 | ) 41 | 42 | 43 | def cpu_or_gpu(test_method): 44 | """ 45 | Decorator to indicate that a test should run on both CPU and GPU 46 | """ 47 | return pytest.mark.gpu(test_method) 48 | -------------------------------------------------------------------------------- /tests/training/metrics/mean_absolute_error_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common.testing import AllenNlpTestCase, multi_device 4 | from allennlp.training.metrics import MeanAbsoluteError 5 | 6 | 7 | class MeanAbsoluteErrorTest(AllenNlpTestCase): 8 | @multi_device 9 | def test_mean_absolute_error_computation(self, device: str): 10 | mae = MeanAbsoluteError() 11 | predictions = torch.tensor( 12 | [[1.0, 1.5, 1.0], [2.0, 3.0, 3.5], [4.0, 5.0, 5.5], [6.0, 7.0, 7.5]], device=device 13 | ) 14 | targets = torch.tensor( 15 | [[0.0, 1.0, 0.0], [2.0, 2.0, 0.0], [4.0, 5.0, 0.0], [7.0, 7.0, 0.0]], device=device 16 | ) 17 | mae(predictions, targets) 18 | assert mae.get_metric() == 21.0 / 12.0 19 | 20 | mask = torch.tensor( 21 | [[True, True, False], [True, True, False], [True, True, False], [True, True, False]], 22 | device=device, 23 | ) 24 | mae(predictions, targets, mask) 25 | assert mae.get_metric() == (21.0 + 3.5) / (12.0 + 8.0) 26 | 27 | new_targets = torch.tensor( 28 | [[2.0, 2.0, 0.0], [0.0, 1.0, 0.0], [7.0, 7.0, 0.0], [4.0, 5.0, 0.0]], device=device 29 | ) 30 | mae(predictions, new_targets) 31 | assert mae.get_metric() == (21.0 + 3.5 + 32.0) / (12.0 + 8.0 + 12.0) 32 | 33 | mae.reset() 34 | mae(predictions, new_targets) 35 | assert mae.get_metric() == 32.0 / 12.0 36 | -------------------------------------------------------------------------------- /tests/interpret/simple_gradient_test.py: -------------------------------------------------------------------------------- 1 | from pytest import approx 2 | 3 | from allennlp.common.testing import AllenNlpTestCase 4 | from allennlp.interpret.saliency_interpreters import SimpleGradient 5 | from allennlp.models.archival import load_archive 6 | from allennlp.predictors import Predictor 7 | 8 | 9 | class TestSimpleGradient(AllenNlpTestCase): 10 | def test_simple_gradient_basic_text(self): 11 | inputs = {"sentence": "It was the ending that I hated"} 12 | archive = load_archive( 13 | self.FIXTURES_ROOT / "basic_classifier" / "serialization" / "model.tar.gz" 14 | ) 15 | predictor = Predictor.from_archive(archive, "text_classifier") 16 | 17 | interpreter = SimpleGradient(predictor) 18 | interpretation = interpreter.saliency_interpret_from_json(inputs) 19 | assert interpretation is not None 20 | assert "instance_1" in interpretation 21 | assert "grad_input_1" in interpretation["instance_1"] 22 | grad_input_1 = interpretation["instance_1"]["grad_input_1"] 23 | assert len(grad_input_1) == 7 # 7 words in input 24 | 25 | # two interpretations should be identical for gradient 26 | repeat_interpretation = interpreter.saliency_interpret_from_json(inputs) 27 | repeat_grad_input_1 = repeat_interpretation["instance_1"]["grad_input_1"] 28 | for grad, repeat_grad in zip(grad_input_1, repeat_grad_input_1): 29 | assert grad == approx(repeat_grad) 30 | -------------------------------------------------------------------------------- /allennlp/data/fields/flag_field.py: -------------------------------------------------------------------------------- 1 | from typing import Any, Dict, List 2 | 3 | from overrides import overrides 4 | 5 | from allennlp.data.fields.field import Field 6 | 7 | 8 | class FlagField(Field[Any]): 9 | """ 10 | A class representing a flag, which must be constant across all instances in a batch. 11 | This will be passed to a `forward` method as a single value of whatever type you pass in. 12 | """ 13 | 14 | __slots__ = ["flag_value"] 15 | 16 | def __init__(self, flag_value: Any) -> None: 17 | self.flag_value = flag_value 18 | 19 | @overrides 20 | def get_padding_lengths(self) -> Dict[str, int]: 21 | return {} 22 | 23 | @overrides 24 | def as_tensor(self, padding_lengths: Dict[str, int]) -> Any: 25 | return self.flag_value 26 | 27 | @overrides 28 | def empty_field(self): 29 | # Because this has to be constant across all instances in a batch, we need to keep the same 30 | # value. 31 | return FlagField(self.flag_value) 32 | 33 | def __str__(self) -> str: 34 | return f"FlagField({self.flag_value})" 35 | 36 | def __len__(self) -> int: 37 | return 1 38 | 39 | @overrides 40 | def batch_tensors(self, tensor_list: List[Any]) -> Any: 41 | if len(set(tensor_list)) != 1: 42 | raise ValueError( 43 | f"Got different values in a FlagField when trying to batch them: {tensor_list}" 44 | ) 45 | return tensor_list[0] 46 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger/experiment_with_regularization.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataset_reader":{"type":"sequence_tagging"}, 3 | "train_data_path": "test_fixtures/data/sequence_tagging.tsv", 4 | "validation_data_path": "test_fixtures/data/sequence_tagging.tsv", 5 | "model": { 6 | "type": "simple_tagger", 7 | "text_field_embedder": { 8 | "token_embedders": { 9 | "tokens": { 10 | "type": "embedding", 11 | "projection_dim": 2, 12 | "pretrained_file": "test_fixtures/embeddings/glove.6B.100d.sample.txt.gz", 13 | "embedding_dim": 100, 14 | "trainable": true 15 | } 16 | } 17 | }, 18 | "encoder": { 19 | "type": "lstm", 20 | "input_size": 2, 21 | "hidden_size": 4, 22 | "num_layers": 1 23 | }, 24 | "regularizer": { 25 | "regexes": [ 26 | ["weight$", {"type": "l2", "alpha": 10}], 27 | ["bias$", {"type": "l1", "alpha": 5}] 28 | ] 29 | } 30 | }, 31 | "data_loader": { 32 | "batch_sampler": { 33 | "type": "bucket", 34 | "batch_size": 80, 35 | "padding_noise": 0.0 36 | } 37 | }, 38 | "trainer": { 39 | "num_epochs": 1, 40 | "grad_norm": 1.0, 41 | "patience": 500, 42 | "cuda_device": -1, 43 | "optimizer": { 44 | "type": "adadelta", 45 | "lr": 0.000001, 46 | "rho": 0.95 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/interpret/integrated_gradient_test.py: -------------------------------------------------------------------------------- 1 | from pytest import approx 2 | from allennlp.common.testing import AllenNlpTestCase 3 | from allennlp.models.archival import load_archive 4 | from allennlp.predictors import Predictor 5 | from allennlp.interpret.saliency_interpreters import IntegratedGradient 6 | 7 | 8 | class TestIntegratedGradient(AllenNlpTestCase): 9 | def test_integrated_gradient(self): 10 | inputs = {"sentence": "It was the ending that I hated"} 11 | archive = load_archive( 12 | self.FIXTURES_ROOT / "basic_classifier" / "serialization" / "model.tar.gz" 13 | ) 14 | predictor = Predictor.from_archive(archive, "text_classifier") 15 | 16 | interpreter = IntegratedGradient(predictor) 17 | interpretation = interpreter.saliency_interpret_from_json(inputs) 18 | assert interpretation is not None 19 | assert "instance_1" in interpretation 20 | assert "grad_input_1" in interpretation["instance_1"] 21 | grad_input_1 = interpretation["instance_1"]["grad_input_1"] 22 | assert len(grad_input_1) == 7 # 7 words in input 23 | 24 | # two interpretations should be identical for integrated gradients 25 | repeat_interpretation = interpreter.saliency_interpret_from_json(inputs) 26 | repeat_grad_input_1 = repeat_interpretation["instance_1"]["grad_input_1"] 27 | for grad, repeat_grad in zip(grad_input_1, repeat_grad_input_1): 28 | assert grad == approx(repeat_grad) 29 | -------------------------------------------------------------------------------- /tests/commands/no_op_train_test.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | 3 | import torch 4 | 5 | from allennlp.commands.train import train_model 6 | from allennlp.common import Params 7 | from allennlp.common.testing import AllenNlpTestCase 8 | from allennlp.models import load_archive, Model 9 | 10 | SEQUENCE_TAGGING_DATA_PATH = str(AllenNlpTestCase.FIXTURES_ROOT / "data" / "sequence_tagging.tsv") 11 | 12 | 13 | @Model.register("constant") 14 | class ConstantModel(Model): 15 | def forward(self, *inputs) -> Dict[str, torch.Tensor]: 16 | return {"class": torch.tensor(98)} 17 | 18 | 19 | class TestTrain(AllenNlpTestCase): 20 | def test_train_model(self): 21 | params = lambda: Params( 22 | { 23 | "model": {"type": "constant"}, 24 | "dataset_reader": {"type": "sequence_tagging"}, 25 | "train_data_path": SEQUENCE_TAGGING_DATA_PATH, 26 | "validation_data_path": SEQUENCE_TAGGING_DATA_PATH, 27 | "data_loader": {"batch_size": 2}, 28 | "trainer": {"type": "no_op"}, 29 | } 30 | ) 31 | 32 | serialization_dir = self.TEST_DIR / "serialization_directory" 33 | train_model(params(), serialization_dir=serialization_dir) 34 | archive = load_archive(str(serialization_dir / "model.tar.gz")) 35 | model = archive.model 36 | assert model.forward(torch.tensor([1, 2, 3]))["class"] == torch.tensor(98) 37 | assert model.vocab.get_vocab_size() == 9 38 | -------------------------------------------------------------------------------- /tests/modules/stacked_elmo_lstm_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import torch 3 | 4 | from allennlp.modules.elmo_lstm import ElmoLstm 5 | from allennlp.common.testing import AllenNlpTestCase 6 | 7 | 8 | class TestElmoLstmCell(AllenNlpTestCase): 9 | def test_elmo_lstm(self): 10 | input_tensor = torch.rand(4, 5, 3) 11 | input_tensor[1, 4:, :] = 0.0 12 | input_tensor[2, 2:, :] = 0.0 13 | input_tensor[3, 1:, :] = 0.0 14 | mask = torch.ones([4, 5]).bool() 15 | mask[1, 4:] = False 16 | mask[2, 2:] = False 17 | mask[3, 1:] = False 18 | 19 | lstm = ElmoLstm( 20 | num_layers=2, 21 | input_size=3, 22 | hidden_size=5, 23 | cell_size=7, 24 | memory_cell_clip_value=2, 25 | state_projection_clip_value=1, 26 | ) 27 | output_sequence = lstm(input_tensor, mask) 28 | 29 | # Check all the layer outputs are masked properly. 30 | numpy.testing.assert_array_equal(output_sequence.data[:, 1, 4:, :].numpy(), 0.0) 31 | numpy.testing.assert_array_equal(output_sequence.data[:, 2, 2:, :].numpy(), 0.0) 32 | numpy.testing.assert_array_equal(output_sequence.data[:, 3, 1:, :].numpy(), 0.0) 33 | 34 | # LSTM state should be (num_layers, batch_size, hidden_size) 35 | assert list(lstm._states[0].size()) == [2, 4, 10] 36 | # LSTM memory cell should be (num_layers, batch_size, cell_size) 37 | assert list((lstm._states[1].size())) == [2, 4, 14] 38 | -------------------------------------------------------------------------------- /tests/modules/attention/additive_attention_test.py: -------------------------------------------------------------------------------- 1 | from numpy.testing import assert_almost_equal 2 | import torch 3 | from torch.nn.parameter import Parameter 4 | 5 | from allennlp.common import Params 6 | from allennlp.modules.attention import AdditiveAttention 7 | from allennlp.common.testing import AllenNlpTestCase 8 | 9 | 10 | class TestAdditiveAttention(AllenNlpTestCase): 11 | def test_forward_does_an_additive_product(self): 12 | params = Params({"vector_dim": 2, "matrix_dim": 3, "normalize": False}) 13 | additive = AdditiveAttention.from_params(params) 14 | additive._w_matrix = Parameter(torch.Tensor([[-0.2, 0.3], [-0.5, 0.5]])) 15 | additive._u_matrix = Parameter(torch.Tensor([[0.0, 1.0], [1.0, 1.0], [1.0, -1.0]])) 16 | additive._v_vector = Parameter(torch.Tensor([[1.0], [-1.0]])) 17 | vectors = torch.FloatTensor([[0.7, -0.8], [0.4, 0.9]]) 18 | matrices = torch.FloatTensor( 19 | [ 20 | [[1.0, -1.0, 3.0], [0.5, -0.3, 0.0], [0.2, -1.0, 1.0], [0.7, 0.8, -1.0]], 21 | [[-2.0, 3.0, -3.0], [0.6, 0.2, 2.0], [0.5, -0.4, -1.0], [0.2, 0.2, 0.0]], 22 | ] 23 | ) 24 | result = additive(vectors, matrices).detach().numpy() 25 | assert result.shape == (2, 4) 26 | assert_almost_equal( 27 | result, 28 | [ 29 | [1.975072, -0.04997836, 1.2176098, -0.9205586], 30 | [-1.4851665, 1.489604, -1.890285, -1.0672251], 31 | ], 32 | ) 33 | -------------------------------------------------------------------------------- /allennlp/modules/gated_sum.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.nn import Activation 4 | 5 | 6 | class GatedSum(torch.nn.Module): 7 | """ 8 | This `Module` represents a gated sum of two tensors `a` and `b`. Specifically: 9 | ``` 10 | f = activation(W [a; b]) 11 | out = f * a + (1 - f) * b 12 | ``` 13 | 14 | # Parameters 15 | 16 | input_dim : `int`, required 17 | The dimensionality of the input. We assume the input have shape `(..., input_dim)`. 18 | activation : `Activation`, optional (default = `torch.nn.Sigmoid()`) 19 | The activation function to use. 20 | """ 21 | 22 | def __init__(self, input_dim: int, activation: Activation = torch.nn.Sigmoid()) -> None: 23 | super().__init__() 24 | self.input_dim = input_dim 25 | self._gate = torch.nn.Linear(input_dim * 2, 1) 26 | self._activation = activation 27 | 28 | def get_input_dim(self): 29 | return self.input_dim 30 | 31 | def get_output_dim(self): 32 | return self.input_dim 33 | 34 | def forward(self, input_a: torch.Tensor, input_b: torch.Tensor) -> torch.Tensor: 35 | if input_a.size() != input_b.size(): 36 | raise ValueError("The input must have the same size.") 37 | if input_a.size(-1) != self.input_dim: 38 | raise ValueError("Input size must match `input_dim`.") 39 | gate_value = self._activation(self._gate(torch.cat([input_a, input_b], -1))) 40 | return gate_value * input_a + (1 - gate_value) * input_b 41 | -------------------------------------------------------------------------------- /allennlp/modules/token_embedders/token_embedder.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common import Registrable 4 | 5 | 6 | class TokenEmbedder(torch.nn.Module, Registrable): 7 | """ 8 | A `TokenEmbedder` is a `Module` that takes as input a tensor with integer ids that have 9 | been output from a [`TokenIndexer`](../../data/token_indexers/token_indexer.md) and outputs 10 | a vector per token in the input. The input typically has shape `(batch_size, num_tokens)` 11 | or `(batch_size, num_tokens, num_characters)`, and the output is of shape `(batch_size, num_tokens, 12 | output_dim)`. The simplest `TokenEmbedder` is just an embedding layer, but for 13 | character-level input, it could also be some kind of character encoder. 14 | 15 | We add a single method to the basic `Module` API: `get_output_dim()`. This lets us 16 | more easily compute output dimensions for the 17 | [`TextFieldEmbedder`](../../text_field_embedders/text_field_embedder.md), 18 | which we might need when defining model parameters such as LSTMs or linear layers, which need 19 | to know their input dimension before the layers are called. 20 | """ 21 | 22 | default_implementation = "embedding" 23 | 24 | def get_output_dim(self) -> int: 25 | """ 26 | Returns the final output dimension that this `TokenEmbedder` uses to represent each 27 | token. This is `not` the shape of the returned tensor, but the last element of that shape. 28 | """ 29 | raise NotImplementedError 30 | -------------------------------------------------------------------------------- /tests/version_test.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | import pytest 4 | 5 | from allennlp.version import VERSION 6 | 7 | 8 | # Regex to check that the current version set in `allennlp.version` adheres to 9 | # PEP 440, as well as some of our own internal conventions, such as the `.dev` 10 | # suffix being used only for nightly builds. 11 | # 0.0.0rc0.post0.dev20200424 12 | VALID_VERSION_RE = re.compile( 13 | r"^" 14 | r"(0|[1-9]\d*)" # major 15 | r"\.(0|[1-9]\d*)" # minor 16 | r"\.(0|[1-9]\d*)" # patch 17 | r"(rc(0|[1-9]\d*))?" # patch suffix 18 | r"(\.post(0|[1-9]\d*))?" # [.postN] 19 | r"(\.dev2020[0-9]{4})?" # [.devDATE] 20 | r"$" 21 | ) 22 | 23 | 24 | def is_valid(version: str) -> bool: 25 | return VALID_VERSION_RE.match(version) is not None 26 | 27 | 28 | @pytest.mark.parametrize( 29 | "version, valid", 30 | [ 31 | # Valid versions: 32 | ("1.0.0", True), 33 | ("1.0.0rc3", True), 34 | ("1.0.0.post0", True), 35 | ("1.0.0.post1", True), 36 | ("1.0.0rc3.post0", True), 37 | ("1.0.0rc3.post0.dev20200424", True), 38 | # Invalid versions: 39 | ("1.0.0.rc3", False), 40 | ("1.0.0rc01", False), 41 | ("1.0.0rc3.dev2020424", False), 42 | ], 43 | ) 44 | def test_is_valid_helper(version: str, valid: bool): 45 | assert is_valid(version) is valid 46 | 47 | 48 | def test_version(): 49 | """ 50 | Ensures current version is consistent with our conventions. 51 | """ 52 | assert is_valid(VERSION) 53 | -------------------------------------------------------------------------------- /tests/modules/seq2seq_encoder_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from allennlp.common import Params 4 | from allennlp.common.checks import ConfigurationError 5 | from allennlp.modules import Seq2SeqEncoder 6 | from allennlp.common.testing import AllenNlpTestCase 7 | 8 | 9 | class TestSeq2SeqEncoder(AllenNlpTestCase): 10 | def test_from_params_builders_encoder_correctly(self): 11 | # We're just making sure parameters get passed through correctly here, and that the basic 12 | # API works. 13 | params = Params( 14 | { 15 | "type": "lstm", 16 | "bidirectional": True, 17 | "num_layers": 3, 18 | "input_size": 5, 19 | "hidden_size": 7, 20 | "stateful": True, 21 | } 22 | ) 23 | encoder = Seq2SeqEncoder.from_params(params) 24 | 25 | assert encoder.__class__.__name__ == "LstmSeq2SeqEncoder" 26 | assert encoder._module.__class__.__name__ == "LSTM" 27 | assert encoder._module.num_layers == 3 28 | assert encoder._module.input_size == 5 29 | assert encoder._module.hidden_size == 7 30 | assert encoder._module.bidirectional is True 31 | assert encoder._module.batch_first is True 32 | assert encoder.stateful is True 33 | 34 | def test_from_params_requires_batch_first(self): 35 | params = Params({"type": "lstm", "batch_first": False}) 36 | with pytest.raises(ConfigurationError): 37 | Seq2SeqEncoder.from_params(params) 38 | -------------------------------------------------------------------------------- /allennlp/modules/seq2vec_encoders/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Modules that transform a sequence of input vectors 3 | into a single output vector. 4 | Some are just basic wrappers around existing PyTorch modules, 5 | others are AllenNLP modules. 6 | 7 | The available Seq2Vec encoders are 8 | 9 | * `"gru"` https://pytorch.org/docs/master/nn.html#torch.nn.GRU 10 | * `"lstm"` https://pytorch.org/docs/master/nn.html#torch.nn.LSTM 11 | * `"rnn"` https://pytorch.org/docs/master/nn.html#torch.nn.RNN 12 | * `"cnn"` allennlp.modules.seq2vec_encoders.cnn_encoder.CnnEncoder 13 | * `"augmented_lstm"` allennlp.modules.augmented_lstm.AugmentedLstm 14 | * `"alternating_lstm"` allennlp.modules.stacked_alternating_lstm.StackedAlternatingLstm 15 | * `"stacked_bidirectional_lstm"` allennlp.modules.stacked_bidirectional_lstm.StackedBidirectionalLstm 16 | """ 17 | 18 | from allennlp.modules.seq2vec_encoders.bert_pooler import BertPooler 19 | from allennlp.modules.seq2vec_encoders.boe_encoder import BagOfEmbeddingsEncoder 20 | from allennlp.modules.seq2vec_encoders.cls_pooler import ClsPooler 21 | from allennlp.modules.seq2vec_encoders.cnn_encoder import CnnEncoder 22 | from allennlp.modules.seq2vec_encoders.cnn_highway_encoder import CnnHighwayEncoder 23 | from allennlp.modules.seq2vec_encoders.pytorch_seq2vec_wrapper import ( 24 | AugmentedLstmSeq2VecEncoder, 25 | GruSeq2VecEncoder, 26 | LstmSeq2VecEncoder, 27 | PytorchSeq2VecWrapper, 28 | RnnSeq2VecEncoder, 29 | StackedAlternatingLstmSeq2VecEncoder, 30 | StackedBidirectionalLstmSeq2VecEncoder, 31 | ) 32 | from allennlp.modules.seq2vec_encoders.seq2vec_encoder import Seq2VecEncoder 33 | -------------------------------------------------------------------------------- /test_fixtures/elmo/config/characters_token_embedder.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataset_reader": { 3 | "type": "conll2003", 4 | "tag_label": "ner", 5 | "token_indexers": { 6 | "tokens": { 7 | "type": "single_id", 8 | "lowercase_tokens": true 9 | }, 10 | "elmo": { 11 | "type": "elmo_characters" 12 | } 13 | } 14 | }, 15 | "train_data_path": "test_fixtures/data/conll2003.txt", 16 | "validation_data_path": "test_fixtures/data/conll2003.txt", 17 | "model": { 18 | "type": "simple_tagger", 19 | "text_field_embedder": { 20 | "token_embedders": { 21 | "tokens": { 22 | "type": "embedding", 23 | "embedding_dim": 50 24 | }, 25 | "elmo": { 26 | "type": "elmo_token_embedder", 27 | "options_file": "test_fixtures/elmo/options.json", 28 | "weight_file": "test_fixtures/elmo/lm_weights.hdf5" 29 | } 30 | } 31 | }, 32 | "encoder": { 33 | "type": "gru", 34 | "input_size": 82, 35 | "hidden_size": 25, 36 | "num_layers": 2, 37 | "dropout": 0.5, 38 | "bidirectional": true 39 | }, 40 | "regularizer": { 41 | "regexes": [ 42 | ["transitions$", {"type": "l2", "alpha": 0.01}] 43 | ] 44 | } 45 | }, 46 | "data_loader": {"batch_size": 32}, 47 | "trainer": { 48 | "optimizer": "adam", 49 | "num_epochs": 5, 50 | "cuda_device": -1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/models/basic_classifier_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | 3 | from allennlp.common.testing import ModelTestCase 4 | 5 | 6 | class TestBasicClassifier(ModelTestCase): 7 | def setup_method(self): 8 | super().setup_method() 9 | self.set_up_model( 10 | self.FIXTURES_ROOT / "basic_classifier" / "experiment_seq2vec.jsonnet", 11 | self.FIXTURES_ROOT / "data" / "text_classification_json" / "imdb_corpus.jsonl", 12 | ) 13 | 14 | def test_forward_pass_runs_correctly(self): 15 | training_tensors = self.dataset.as_tensor_dict() 16 | output_dict = self.model(**training_tensors) 17 | output_dict = self.model.make_output_human_readable(output_dict) 18 | assert "label" in output_dict.keys() 19 | probs = output_dict["probs"][0].data.numpy() 20 | numpy.testing.assert_almost_equal(numpy.sum(probs, -1), numpy.array([1])) 21 | 22 | def test_seq2vec_clf_can_train_save_and_load(self): 23 | self.set_up_model( 24 | self.FIXTURES_ROOT / "basic_classifier" / "experiment_seq2vec.jsonnet", 25 | self.FIXTURES_ROOT / "data" / "text_classification_json" / "imdb_corpus.jsonl", 26 | ) 27 | self.ensure_model_can_train_save_and_load(self.param_file) 28 | 29 | def test_seq2seq_clf_can_train_save_and_load(self): 30 | self.set_up_model( 31 | self.FIXTURES_ROOT / "basic_classifier" / "experiment_seq2seq.jsonnet", 32 | self.FIXTURES_ROOT / "data" / "text_classification_json" / "imdb_corpus.jsonl", 33 | ) 34 | self.ensure_model_can_train_save_and_load(self.param_file) 35 | -------------------------------------------------------------------------------- /allennlp/tools/EVALB/sample/sample.tst: -------------------------------------------------------------------------------- 1 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 2 | (S (A (P this)) (B (Q is) (C (R a) (T test)))) 3 | (S (A (P this)) (B (Q is) (A (R a) (U test)))) 4 | (S (C (P this)) (B (Q is) (A (R a) (U test)))) 5 | (S (A (P this)) (B (Q is) (R a) (A (T test)))) 6 | (S (A (P this) (Q is)) (A (R a) (T test))) 7 | (S (P this) (Q is) (R a) (T test)) 8 | (P this) (Q is) (R a) (T test) 9 | (S (A (P this)) (B (Q is) (A (A (R a) (T test))))) 10 | (S (A (P this)) (B (Q is) (A (A (A (A (A (R a) (T test)))))))) 11 | 12 | (S (A (P this)) (B (Q was) (A (A (R a) (T test))))) 13 | (S (A (P this)) (B (Q is) (U not) (A (A (R a) (T test))))) 14 | 15 | (TOP (S (A (P this)) (B (Q is) (A (R a) (T test))))) 16 | (S (A (P this)) (NONE *) (B (Q is) (A (R a) (T test)))) 17 | (S (A (P this)) (S (NONE abc) (A (NONE *))) (B (Q is) (A (R a) (T test)))) 18 | (S (A (P this)) (B (Q is) (A (R a) (TT test)))) 19 | (S (A (P This)) (B (Q is) (A (R a) (T test)))) 20 | (S (A (P That)) (B (Q is) (A (R a) (T test)))) 21 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 22 | (S (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test)))) 23 | (S (A (P this)) (B (Q is) (A (R a) (T test))) (-NONE- *)) 24 | (S (A (P this)) (B (Q is) (A (R a) (T test))) (: *)) 25 | -------------------------------------------------------------------------------- /allennlp/training/learning_rate_schedulers/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | AllenNLP uses most 3 | `PyTorch learning rate schedulers `_, 4 | with a thin wrapper to allow registering them and instantiating them `from_params`. 5 | 6 | The available learning rate schedulers from PyTorch are 7 | 8 | * `"step" `_ 9 | * `"multi_step" `_ 10 | * `"exponential" `_ 11 | * `"reduce_on_plateau" `_ 12 | 13 | In addition, AllenNLP also provides `cosine with restarts `_, 14 | a Noam schedule, and a slanted triangular schedule, which are registered as 15 | "cosine", "noam", and "slanted_triangular", respectively. 16 | """ 17 | 18 | from allennlp.training.learning_rate_schedulers.learning_rate_scheduler import ( 19 | LearningRateScheduler, 20 | StepLearningRateScheduler, 21 | MultiStepLearningRateScheduler, 22 | ExponentialLearningRateScheduler, 23 | ReduceOnPlateauLearningRateScheduler, 24 | ) 25 | from allennlp.training.learning_rate_schedulers.cosine import CosineWithRestarts 26 | from allennlp.training.learning_rate_schedulers.noam import NoamLR 27 | from allennlp.training.learning_rate_schedulers.slanted_triangular import SlantedTriangular 28 | from allennlp.training.learning_rate_schedulers.polynomial_decay import PolynomialDecay 29 | -------------------------------------------------------------------------------- /allennlp/training/metrics/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A `~allennlp.training.metrics.metric.Metric` is some quantity or quantities 3 | that can be accumulated during training or evaluation; for example, 4 | accuracy or F1 score. 5 | """ 6 | 7 | from allennlp.training.metrics.attachment_scores import AttachmentScores 8 | from allennlp.training.metrics.average import Average 9 | from allennlp.training.metrics.boolean_accuracy import BooleanAccuracy 10 | from allennlp.training.metrics.bleu import BLEU 11 | from allennlp.training.metrics.rouge import ROUGE 12 | from allennlp.training.metrics.categorical_accuracy import CategoricalAccuracy 13 | from allennlp.training.metrics.covariance import Covariance 14 | from allennlp.training.metrics.entropy import Entropy 15 | from allennlp.training.metrics.evalb_bracketing_scorer import ( 16 | EvalbBracketingScorer, 17 | DEFAULT_EVALB_DIR, 18 | ) 19 | from allennlp.training.metrics.fbeta_measure import FBetaMeasure 20 | from allennlp.training.metrics.f1_measure import F1Measure 21 | from allennlp.training.metrics.mean_absolute_error import MeanAbsoluteError 22 | from allennlp.training.metrics.metric import Metric 23 | from allennlp.training.metrics.pearson_correlation import PearsonCorrelation 24 | from allennlp.training.metrics.spearman_correlation import SpearmanCorrelation 25 | from allennlp.training.metrics.perplexity import Perplexity 26 | from allennlp.training.metrics.sequence_accuracy import SequenceAccuracy 27 | from allennlp.training.metrics.span_based_f1_measure import SpanBasedF1Measure 28 | from allennlp.training.metrics.unigram_recall import UnigramRecall 29 | from allennlp.training.metrics.auc import Auc 30 | -------------------------------------------------------------------------------- /tests/modules/matrix_attention/cosine_matrix_attention_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from numpy.testing import assert_almost_equal 3 | import numpy 4 | 5 | from allennlp.common import Params 6 | from allennlp.common.testing.test_case import AllenNlpTestCase 7 | from allennlp.modules.matrix_attention import CosineMatrixAttention 8 | from allennlp.modules.matrix_attention.matrix_attention import MatrixAttention 9 | 10 | 11 | class TestCosineMatrixAttention(AllenNlpTestCase): 12 | def test_can_init_cosine(self): 13 | legacy_attention = MatrixAttention.from_params(Params({"type": "cosine"})) 14 | isinstance(legacy_attention, CosineMatrixAttention) 15 | 16 | def test_cosine_similarity(self): 17 | # example use case: a batch of size 2. 18 | # With a time element component (e.g. sentences of length 2) each word is a vector of length 3. 19 | # It is comparing this with another input of the same type 20 | output = CosineMatrixAttention()( 21 | torch.FloatTensor([[[0, 0, 0], [4, 5, 6]], [[-7, -8, -9], [10, 11, 12]]]), 22 | torch.FloatTensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]), 23 | ) 24 | 25 | # For the first batch there is 26 | # no correlation between the first words of the input matrix 27 | # but perfect correlation for the second word 28 | # For the second batch there is 29 | # negative correlation for the first words 30 | # correlation for the second word 31 | assert_almost_equal( 32 | output.numpy(), numpy.array([[[0, 0], [0.97, 1]], [[-1, -0.99], [0.99, 1]]]), decimal=2 33 | ) 34 | -------------------------------------------------------------------------------- /allennlp/nn/regularizers/regularizer_applicator.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import List, Tuple 3 | 4 | import torch 5 | 6 | from allennlp.common import FromParams 7 | from allennlp.nn.regularizers.regularizer import Regularizer 8 | 9 | 10 | class RegularizerApplicator(FromParams): 11 | """ 12 | Applies regularizers to the parameters of a Module based on regex matches. 13 | """ 14 | 15 | def __init__(self, regexes: List[Tuple[str, Regularizer]] = None) -> None: 16 | """ 17 | # Parameters 18 | 19 | regexes : `List[Tuple[str, Regularizer]]`, optional (default = `None`) 20 | A sequence of pairs (regex, Regularizer), where each Regularizer 21 | applies to the parameters its regex matches (and that haven't previously 22 | been matched). 23 | """ 24 | self._regularizers = regexes or [] 25 | 26 | def __call__(self, module: torch.nn.Module) -> torch.Tensor: 27 | """ 28 | # Parameters 29 | 30 | module : `torch.nn.Module`, required 31 | The module to regularize. 32 | """ 33 | accumulator = 0.0 34 | for name, parameter in module.named_parameters(): 35 | # We first check if the parameter needs gradient updates or not 36 | if parameter.requires_grad: 37 | # For each parameter find the first matching regex. 38 | for regex, regularizer in self._regularizers: 39 | if re.search(regex, name): 40 | penalty = regularizer(parameter) 41 | accumulator = accumulator + penalty 42 | break 43 | return accumulator 44 | -------------------------------------------------------------------------------- /tests/modules/matrix_attention/dot_product_matrix_attention_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from numpy.testing import assert_almost_equal 3 | import numpy 4 | 5 | from allennlp.common import Params 6 | from allennlp.common.testing.test_case import AllenNlpTestCase 7 | from allennlp.modules.matrix_attention import DotProductMatrixAttention 8 | from allennlp.modules.matrix_attention.matrix_attention import MatrixAttention 9 | 10 | 11 | class TestDotProductMatrixAttention(AllenNlpTestCase): 12 | def test_can_init_dot(self): 13 | legacy_attention = MatrixAttention.from_params(Params({"type": "dot_product"})) 14 | isinstance(legacy_attention, DotProductMatrixAttention) 15 | 16 | def test_dot_product_similarity(self): 17 | # example use case: a batch of size 2, 18 | # with a time element component (e.g. sentences of length 2) each word is a vector of length 3. 19 | # it is comparing this with another input of the same type 20 | output = DotProductMatrixAttention()( 21 | torch.FloatTensor([[[0, 0, 0], [4, 5, 6]], [[-7, -8, -9], [10, 11, 12]]]), 22 | torch.FloatTensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]), 23 | ) 24 | 25 | # for the first batch there is 26 | # no correlation between the first words of the input matrix 27 | # but perfect correlation for the second word 28 | # for the second batch there is 29 | # negative correlation for the first words 30 | # a correlation for the second word 31 | assert_almost_equal( 32 | output.numpy(), numpy.array([[[0, 0], [32, 77]], [[-194, -266], [266, 365]]]), decimal=2 33 | ) 34 | -------------------------------------------------------------------------------- /allennlp/tools/EVALB/sample/sample.gld: -------------------------------------------------------------------------------- 1 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 2 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 3 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 4 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 5 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 6 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 7 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 8 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 9 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 10 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 11 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 12 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 13 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 14 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 15 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 16 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 17 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 18 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 19 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 20 | (S (A (P this)) (B (Q is) (A (R a) (T test)))) 21 | (S (A-SBJ-1 (P this)) (B-WHATEVER (Q is) (A (R a) (T test)))) 22 | (S (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test))) (A (P this)) (B (Q is) (A (R a) (T test)))) 23 | (S (A (P this)) (B (Q is) (A (R a) (T test))) (-NONE- *)) 24 | (S (A (P this)) (B (Q is) (A (R a) (T test))) (: *)) 25 | -------------------------------------------------------------------------------- /allennlp/modules/seq2seq_encoders/feedforward_encoder.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from overrides import overrides 3 | 4 | from allennlp.modules.feedforward import FeedForward 5 | from allennlp.modules.seq2seq_encoders.seq2seq_encoder import Seq2SeqEncoder 6 | 7 | 8 | @Seq2SeqEncoder.register("feedforward") 9 | class FeedForwardEncoder(Seq2SeqEncoder): 10 | """ 11 | This class applies the `FeedForward` to each item in sequences. 12 | 13 | Registered as a `Seq2SeqEncoder` with name "feedforward". 14 | """ 15 | 16 | def __init__(self, feedforward: FeedForward) -> None: 17 | super().__init__() 18 | self._feedforward = feedforward 19 | 20 | @overrides 21 | def get_input_dim(self) -> int: 22 | return self._feedforward.get_input_dim() 23 | 24 | @overrides 25 | def get_output_dim(self) -> int: 26 | return self._feedforward.get_output_dim() 27 | 28 | @overrides 29 | def is_bidirectional(self) -> bool: 30 | return False 31 | 32 | @overrides 33 | def forward(self, inputs: torch.Tensor, mask: torch.BoolTensor = None) -> torch.Tensor: 34 | """ 35 | # Parameters 36 | 37 | inputs : `torch.Tensor`, required. 38 | A tensor of shape (batch_size, timesteps, input_dim) 39 | mask : `torch.BoolTensor`, optional (default = `None`). 40 | A tensor of shape (batch_size, timesteps). 41 | 42 | # Returns 43 | 44 | A tensor of shape (batch_size, timesteps, output_dim). 45 | """ 46 | if mask is None: 47 | return self._feedforward(inputs) 48 | else: 49 | outputs = self._feedforward(inputs) 50 | return outputs * mask.unsqueeze(dim=-1) 51 | -------------------------------------------------------------------------------- /tests/modules/seq2seq_encoders/feedforward_encoder_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import numpy 3 | 4 | from allennlp.common.testing import AllenNlpTestCase 5 | from allennlp.modules import FeedForward 6 | from allennlp.modules.seq2seq_encoders.feedforward_encoder import FeedForwardEncoder 7 | from allennlp.nn import Activation 8 | 9 | 10 | class TestFeedforwardEncoder(AllenNlpTestCase): 11 | def test_get_dimension_is_correct(self): 12 | feedforward = FeedForward( 13 | input_dim=10, num_layers=1, hidden_dims=10, activations=Activation.by_name("linear")() 14 | ) 15 | encoder = FeedForwardEncoder(feedforward) 16 | assert encoder.get_input_dim() == feedforward.get_input_dim() 17 | assert encoder.get_output_dim() == feedforward.get_output_dim() 18 | 19 | def test_feedforward_encoder_exactly_match_feedforward_each_item(self): 20 | feedforward = FeedForward( 21 | input_dim=10, num_layers=1, hidden_dims=10, activations=Activation.by_name("linear")() 22 | ) 23 | encoder = FeedForwardEncoder(feedforward) 24 | tensor = torch.randn([2, 3, 10]) 25 | output = encoder(tensor) 26 | target = feedforward(tensor) 27 | numpy.testing.assert_array_almost_equal( 28 | target.detach().cpu().numpy(), output.detach().cpu().numpy() 29 | ) 30 | 31 | # mask should work 32 | mask = torch.tensor([[True, True, True], [True, False, False]]) 33 | output = encoder(tensor, mask) 34 | target = feedforward(tensor) * mask.unsqueeze(dim=-1).float() 35 | numpy.testing.assert_array_almost_equal( 36 | target.detach().cpu().numpy(), output.detach().cpu().numpy() 37 | ) 38 | -------------------------------------------------------------------------------- /test_fixtures/simple_tagger_with_span_f1/experiment.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataset_reader": { 3 | "type": "conll2003", 4 | "tag_label": "ner", 5 | "token_indexers": { 6 | "tokens": { 7 | "type": "single_id", 8 | "lowercase_tokens": true 9 | } 10 | } 11 | }, 12 | "validation_dataset_reader": { 13 | "type": "conll2003", 14 | "tag_label": "ner", 15 | "token_indexers": { 16 | "tokens": { 17 | "type": "single_id", 18 | "namespace": "test_tokens", 19 | "lowercase_tokens": true 20 | } 21 | } 22 | }, 23 | "train_data_path": "test_fixtures/data/conll2003.txt", 24 | "validation_data_path": "test_fixtures/data/conll2003.txt", 25 | "model": { 26 | "type": "simple_tagger", 27 | "calculate_span_f1": true, 28 | "label_encoding": "IOB1", 29 | "text_field_embedder": { 30 | "token_embedders": { 31 | "tokens": { 32 | "type": "embedding", 33 | "projection_dim": 2, 34 | "pretrained_file": "test_fixtures/embeddings/glove.6B.100d.sample.txt.gz", 35 | "embedding_dim": 100, 36 | "trainable": true 37 | } 38 | } 39 | }, 40 | "encoder": { 41 | "type": "lstm", 42 | "input_size": 2, 43 | "hidden_size": 4, 44 | "num_layers": 1 45 | } 46 | }, 47 | "data_loader": { 48 | "batch_sampler":{ 49 | "type": "bucket", 50 | "padding_noise": 0.0, 51 | "batch_size" : 80 52 | } 53 | }, 54 | "trainer": { 55 | "num_epochs": 1, 56 | "grad_norm": 1.0, 57 | "patience": 500, 58 | "cuda_device": -1, 59 | "optimizer": { 60 | "type": "adadelta", 61 | "lr": 0.000001, 62 | "rho": 0.95 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /allennlp/modules/seq2seq_encoders/seq2seq_encoder.py: -------------------------------------------------------------------------------- 1 | from allennlp.modules.encoder_base import _EncoderBase 2 | from allennlp.common import Registrable 3 | 4 | 5 | class Seq2SeqEncoder(_EncoderBase, Registrable): 6 | """ 7 | A `Seq2SeqEncoder` is a `Module` that takes as input a sequence of vectors and returns a 8 | modified sequence of vectors. Input shape : `(batch_size, sequence_length, input_dim)`; output 9 | shape : `(batch_size, sequence_length, output_dim)`. 10 | 11 | We add two methods to the basic `Module` API: `get_input_dim()` and `get_output_dim()`. 12 | You might need this if you want to construct a `Linear` layer using the output of this encoder, 13 | or to raise sensible errors for mis-matching input dimensions. 14 | """ 15 | 16 | def get_input_dim(self) -> int: 17 | """ 18 | Returns the dimension of the vector input for each element in the sequence input 19 | to a `Seq2SeqEncoder`. This is `not` the shape of the input tensor, but the 20 | last element of that shape. 21 | """ 22 | raise NotImplementedError 23 | 24 | def get_output_dim(self) -> int: 25 | """ 26 | Returns the dimension of each vector in the sequence output by this `Seq2SeqEncoder`. 27 | This is `not` the shape of the returned tensor, but the last element of that shape. 28 | """ 29 | raise NotImplementedError 30 | 31 | def is_bidirectional(self) -> bool: 32 | """ 33 | Returns `True` if this encoder is bidirectional. If so, we assume the forward direction 34 | of the encoder is the first half of the final dimension, and the backward direction is the 35 | second half. 36 | """ 37 | raise NotImplementedError 38 | -------------------------------------------------------------------------------- /allennlp/commands/subcommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | Base class for subcommands under `allennlp.run`. 3 | """ 4 | 5 | import argparse 6 | from typing import Callable, Dict, Optional, Type, TypeVar 7 | 8 | from overrides import overrides 9 | 10 | from allennlp.common import Registrable 11 | 12 | 13 | T = TypeVar("T", bound="Subcommand") 14 | 15 | 16 | class Subcommand(Registrable): 17 | """ 18 | An abstract class representing subcommands for allennlp.run. 19 | If you wanted to (for example) create your own custom `special-evaluate` command to use like 20 | 21 | `allennlp special-evaluate ...` 22 | 23 | you would create a `Subcommand` subclass and then pass it as an override to 24 | [`main`](#main). 25 | """ 26 | 27 | reverse_registry: Dict[Type, str] = {} 28 | 29 | def add_subparser(self, parser: argparse._SubParsersAction) -> argparse.ArgumentParser: 30 | raise NotImplementedError 31 | 32 | @classmethod 33 | @overrides 34 | def register( 35 | cls: Type[T], name: str, constructor: Optional[str] = None, exist_ok: bool = False 36 | ) -> Callable[[Type[T]], Type[T]]: 37 | super_register_fn = super().register(name, constructor=constructor, exist_ok=exist_ok) 38 | 39 | def add_name_to_reverse_registry(subclass: Type[T]) -> Type[T]: 40 | subclass = super_register_fn(subclass) 41 | # Don't need to check `exist_ok`, as it's done by super. 42 | # Also, don't need to delete previous entries if overridden, they can just stay there. 43 | cls.reverse_registry[subclass] = name 44 | return subclass 45 | 46 | return add_name_to_reverse_registry 47 | 48 | @property 49 | def name(self) -> str: 50 | return self.reverse_registry[self.__class__] 51 | -------------------------------------------------------------------------------- /scripts/compile_coref_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script downloads and compiles the Ontonotes 2012 data in a helpful format 4 | # for co-reference resolution. It generates 3 files: {train, dev, test}.english.v4_gold_conll, 5 | # as well as a directory 'conll-2012' which contains the raw extracted data. 6 | # The script downloads and runs some python scripts which require python 2.X. 7 | 8 | ONTONOTES_PATH=$1 9 | 10 | if [ ! -n "$ONTONOTES_PATH" ] ; then 11 | echo "USAGE: ./scripts/compile_coref_data.sh /path/to/ontonotes/data" 12 | exit 1 13 | fi 14 | 15 | function download_and_extract() { 16 | wget $1/$2 17 | tar -xvzf $2 18 | rm $2 19 | } 20 | 21 | function compile_partition() { 22 | rm -f $2.$5.$3$4 23 | cat conll-2012/$3/data/$1/data/$5/annotations/*/*/*/*.$3$4 >> $2.$5.$3$4 24 | } 25 | 26 | function compile_language() { 27 | compile_partition development dev v4 _gold_conll $1 28 | compile_partition train train v4 _gold_conll $1 29 | compile_partition test test v4 _gold_conll $1 30 | } 31 | 32 | conll_url=https://conll.cemantix.org/2012/download 33 | download_and_extract $conll_url conll-2012-train.v4.tar.gz 34 | download_and_extract $conll_url conll-2012-development.v4.tar.gz 35 | download_and_extract $conll_url/test conll-2012-test-key.tar.gz 36 | download_and_extract $conll_url/test conll-2012-test-official.v9.tar.gz 37 | 38 | download_and_extract $conll_url conll-2012-scripts.v3.tar.gz 39 | 40 | download_and_extract https://conll.cemantix.org/download reference-coreference-scorers.v8.01.tar.gz 41 | mv reference-coreference-scorers conll-2012/scorer 42 | 43 | # Convert the ontonotes data into the CONLL format. 44 | bash conll-2012/v3/scripts/skeleton2conll.sh -D $ONTONOTES_PATH/data/files/data conll-2012 45 | 46 | compile_language english 47 | -------------------------------------------------------------------------------- /Dockerfile.test: -------------------------------------------------------------------------------- 1 | # Used to build an image for running tests. 2 | 3 | FROM python:3.7 4 | 5 | ENV LC_ALL=C.UTF-8 6 | ENV LANG=C.UTF-8 7 | 8 | ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64 9 | 10 | # Tell nvidia-docker the driver spec that we need as well as to 11 | # use all available devices, which are mounted at /usr/local/nvidia. 12 | # The LABEL supports an older version of nvidia-docker, the env 13 | # variables a newer one. 14 | ENV NVIDIA_VISIBLE_DEVICES all 15 | ENV NVIDIA_DRIVER_CAPABILITIES compute,utility 16 | LABEL com.nvidia.volumes.needed="nvidia_driver" 17 | 18 | WORKDIR /stage/allennlp 19 | 20 | # Installing AllenNLP's dependencies is the most time-consuming part of building 21 | # this Docker image, so we make use of layer caching here by adding the minimal files 22 | # necessary to install the dependencies. Since most of the dependencies are defined 23 | # in the setup.py file, we create a "shell" package of allennlp using the same setup file 24 | # and then pip install it, after which we uninstall it so that we'll only have the dependencies 25 | # installed. 26 | COPY allennlp/version.py allennlp/version.py 27 | RUN touch allennlp/__init__.py && touch README.md 28 | COPY setup.py setup.py 29 | COPY dev-requirements.txt dev-requirements.txt 30 | 31 | # Now install deps by installing the shell package, and then uninstall it so we can 32 | # re-install the full package below. 33 | RUN pip install --no-cache-dir -e . && \ 34 | pip install --no-cache-dir -r dev-requirements.txt && \ 35 | pip uninstall -y typing && \ 36 | pip uninstall -y allennlp && \ 37 | rm -rf allennlp/ 38 | 39 | # Now add the full package source and re-install just the package. 40 | COPY . . 41 | RUN pip install --no-cache-dir --no-deps -e . 42 | 43 | ENTRYPOINT ["make"] 44 | -------------------------------------------------------------------------------- /allennlp/tools/EVALB/bug/bug.rsl-new: -------------------------------------------------------------------------------- 1 | Sent. Matched Bracket Cross Correct Tag 2 | ID Len. Stat. Recal Prec. Bracket gold test Bracket Words Tags Accracy 3 | ============================================================================ 4 | 1 37 0 77.27 65.38 17 22 26 5 34 27 79.41 5 | 2 21 0 69.23 64.29 9 13 14 2 20 16 80.00 6 | 3 47 0 80.00 82.35 28 35 34 4 44 40 90.91 7 | 4 26 0 35.29 37.50 6 17 16 8 25 18 72.00 8 | 5 44 0 42.31 33.33 11 26 33 17 38 28 73.68 9 | ============================================================================ 10 | 62.83 57.72 71 113 123 0 161 129 80.12 11 | === Summary === 12 | 13 | -- All -- 14 | Number of sentence = 5 15 | Number of Error sentence = 0 16 | Number of Skip sentence = 0 17 | Number of Valid sentence = 5 18 | Bracketing Recall = 62.83 19 | Bracketing Precision = 57.72 20 | Bracketing FMeasure = 60.17 21 | Complete match = 0.00 22 | Average crossing = 7.20 23 | No crossing = 0.00 24 | 2 or less crossing = 20.00 25 | Tagging accuracy = 80.12 26 | 27 | -- len<=40 -- 28 | Number of sentence = 3 29 | Number of Error sentence = 0 30 | Number of Skip sentence = 0 31 | Number of Valid sentence = 3 32 | Bracketing Recall = 61.54 33 | Bracketing Precision = 57.14 34 | Bracketing FMeasure = 59.26 35 | Complete match = 0.00 36 | Average crossing = 5.00 37 | No crossing = 0.00 38 | 2 or less crossing = 33.33 39 | Tagging accuracy = 77.22 40 | -------------------------------------------------------------------------------- /tests/modules/matrix_attention/bilinear_matrix_attention_test.py: -------------------------------------------------------------------------------- 1 | from numpy.testing import assert_almost_equal 2 | import torch 3 | from torch.nn.parameter import Parameter 4 | 5 | from allennlp.common import Params 6 | from allennlp.modules.matrix_attention import BilinearMatrixAttention 7 | from allennlp.common.testing import AllenNlpTestCase 8 | 9 | 10 | class TestBilinearMatrixAttention(AllenNlpTestCase): 11 | def test_forward_does_a_bilinear_product(self): 12 | params = Params({"matrix_1_dim": 2, "matrix_2_dim": 2}) 13 | bilinear = BilinearMatrixAttention.from_params(params) 14 | bilinear._weight_matrix = Parameter(torch.FloatTensor([[-0.3, 0.5], [2.0, -1.0]])) 15 | bilinear._bias = Parameter(torch.FloatTensor([0.1])) 16 | a_vectors = torch.FloatTensor([[[1, 1], [2, 2]]]) 17 | b_vectors = torch.FloatTensor([[[1, 0], [0, 1]]]) 18 | result = bilinear(a_vectors, b_vectors).detach().numpy() 19 | assert result.shape == (1, 2, 2) 20 | assert_almost_equal(result, [[[1.8, -0.4], [3.5, -0.9]]]) 21 | 22 | def test_forward_does_a_bilinear_product_when_using_biases(self): 23 | params = Params({"matrix_1_dim": 2, "matrix_2_dim": 2, "use_input_biases": True}) 24 | bilinear = BilinearMatrixAttention.from_params(params) 25 | bilinear._weight_matrix = Parameter( 26 | torch.FloatTensor([[-0.3, 0.5, 1.0], [2.0, -1.0, -1.0], [1.0, 0.5, 1.0]]) 27 | ) 28 | bilinear._bias = Parameter(torch.FloatTensor([0.1])) 29 | a_vectors = torch.FloatTensor([[[1, 1], [2, 2]]]) 30 | b_vectors = torch.FloatTensor([[[1, 0], [0, 1]]]) 31 | result = bilinear(a_vectors, b_vectors).detach().numpy() 32 | assert result.shape == (1, 2, 2) 33 | assert_almost_equal(result, [[[3.8, 1.1], [5.5, 0.6]]]) 34 | -------------------------------------------------------------------------------- /tests/data/instance_test.py: -------------------------------------------------------------------------------- 1 | from allennlp.common.testing import AllenNlpTestCase 2 | from allennlp.data import Instance 3 | from allennlp.data.fields import TextField, LabelField 4 | from allennlp.data.token_indexers import PretrainedTransformerIndexer 5 | from allennlp.data.tokenizers import Token 6 | 7 | 8 | class TestInstance(AllenNlpTestCase): 9 | def test_instance_implements_mutable_mapping(self): 10 | words_field = TextField([Token("hello")], {}) 11 | label_field = LabelField(1, skip_indexing=True) 12 | instance = Instance({"words": words_field, "labels": label_field}) 13 | 14 | assert instance["words"] == words_field 15 | assert instance["labels"] == label_field 16 | assert len(instance) == 2 17 | 18 | keys = {k for k, v in instance.items()} 19 | assert keys == {"words", "labels"} 20 | 21 | values = [v for k, v in instance.items()] 22 | assert words_field in values 23 | assert label_field in values 24 | 25 | def test_duplicate(self): 26 | # Verify the `duplicate()` method works with a `PretrainedTransformerIndexer` in 27 | # a `TextField`. See https://github.com/allenai/allennlp/issues/4270. 28 | instance = Instance( 29 | { 30 | "words": TextField( 31 | [Token("hello")], {"tokens": PretrainedTransformerIndexer("bert-base-uncased")} 32 | ) 33 | } 34 | ) 35 | 36 | other = instance.duplicate() 37 | assert other == instance 38 | 39 | # Adding new fields to the original instance should not effect the duplicate. 40 | instance.add_field("labels", LabelField("some_label")) 41 | assert "labels" not in other.fields 42 | assert other != instance # sanity check on the '__eq__' method. 43 | -------------------------------------------------------------------------------- /allennlp/modules/token_embedders/token_characters_encoder.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.modules.token_embedders.embedding import Embedding 4 | from allennlp.modules.seq2vec_encoders.seq2vec_encoder import Seq2VecEncoder 5 | from allennlp.modules.time_distributed import TimeDistributed 6 | from allennlp.modules.token_embedders.token_embedder import TokenEmbedder 7 | 8 | 9 | @TokenEmbedder.register("character_encoding") 10 | class TokenCharactersEncoder(TokenEmbedder): 11 | """ 12 | A `TokenCharactersEncoder` takes the output of a 13 | [`TokenCharactersIndexer`](../../data/token_indexers/token_characters_indexer.md), which is a tensor of shape 14 | (batch_size, num_tokens, num_characters), embeds the characters, runs a token-level encoder, and 15 | returns the result, which is a tensor of shape (batch_size, num_tokens, encoding_dim). We also 16 | optionally apply dropout after the token-level encoder. 17 | 18 | We take the embedding and encoding modules as input, so this class is itself quite simple. 19 | 20 | Registered as a `TokenEmbedder` with name "character_encoding". 21 | """ 22 | 23 | def __init__(self, embedding: Embedding, encoder: Seq2VecEncoder, dropout: float = 0.0) -> None: 24 | super().__init__() 25 | self._embedding = TimeDistributed(embedding) 26 | self._encoder = TimeDistributed(encoder) 27 | if dropout > 0: 28 | self._dropout = torch.nn.Dropout(p=dropout) 29 | else: 30 | self._dropout = lambda x: x 31 | 32 | def get_output_dim(self) -> int: 33 | return self._encoder._module.get_output_dim() 34 | 35 | def forward(self, token_characters: torch.Tensor) -> torch.Tensor: 36 | mask = (token_characters != 0).long() 37 | return self._dropout(self._encoder(self._embedding(token_characters), mask)) 38 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | testpaths = tests/ scripts/tests/ 3 | python_classes = Test* *Test 4 | log_format = %(asctime)s - %(levelname)s - %(name)s - %(message)s 5 | log_level = DEBUG 6 | markers = 7 | java 8 | gpu: marks tests that need at least one GPU 9 | filterwarnings = 10 | # Note: When a warning matches more than one option in the list, 11 | # the action for the _last_ matching option is performed. 12 | # 13 | # individual warnings filters are specified as a sequence of fields separated by colons: 14 | # action:message:category:module:line 15 | # 16 | # 17 | # how to explicitly test warns 18 | # using `unittest`: https://docs.python.org/3/library/warnings.html#testing-warnings 19 | # using `pytest`: https://docs.pytest.org/en/4.1.0/warnings.html#assertwarnings 20 | # 21 | # Our policy here is to ignore (silence) any deprecation warnings from _outside_ allennlp, but to 22 | # treat any _internal_ deprecation warnings as errors. If we get a deprecation warning from things 23 | # we call in another library, we will just rely on seeing those outside of tests. The purpose of 24 | # having these errors here is to make sure that we do not deprecate things lightly in allennlp. 25 | ignore::DeprecationWarning 26 | ignore::PendingDeprecationWarning 27 | error::DeprecationWarning:allennlp.*: 28 | error::PendingDeprecationWarning:allennlp.*: 29 | # For these particular warnings, we don't want to cause an error for it, but we also don't want to 30 | # see it a whole bunch of times. 31 | once:This particular transformer implementation is a provisional feature.*::allennlp\.modules\.seq2seq_encoders\.bidirectional_language_model_transformer 32 | ignore:Length of IterableDataset.*:UserWarning:torch\.utils\.data\.dataloader 33 | ignore::UserWarning:allennlp.*: 34 | -------------------------------------------------------------------------------- /tests/training/metrics/entropy_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from torch.testing import assert_allclose 3 | 4 | from allennlp.common.testing import AllenNlpTestCase, multi_device 5 | from allennlp.training.metrics import Entropy 6 | 7 | 8 | class EntropyTest(AllenNlpTestCase): 9 | @multi_device 10 | def test_low_entropy_distribution(self, device: str): 11 | metric = Entropy() 12 | logits = torch.tensor( 13 | [[10000, -10000, -10000, -1000], [10000, -10000, -10000, -1000]], 14 | dtype=torch.float, 15 | device=device, 16 | ) 17 | metric(logits) 18 | assert metric.get_metric() == 0.0 19 | 20 | @multi_device 21 | def test_entropy_for_uniform_distribution(self, device: str): 22 | metric = Entropy() 23 | logits = torch.tensor([[1, 1, 1, 1], [1, 1, 1, 1]], dtype=torch.float, device=device) 24 | metric(logits) 25 | assert_allclose(metric.get_metric(), torch.tensor(1.38629436, device=device)) 26 | # actual values shouldn't effect uniform distribution: 27 | logits = torch.tensor([[2, 2, 2, 2], [2, 2, 2, 2]], dtype=torch.float, device=device) 28 | metric(logits) 29 | assert_allclose(metric.get_metric(), torch.tensor(1.38629436, device=device)) 30 | 31 | metric.reset() 32 | assert metric._entropy == 0.0 33 | assert metric._count == 0.0 34 | 35 | @multi_device 36 | def test_masked_case(self, device: str): 37 | metric = Entropy() 38 | # This would have non-zero entropy without the mask. 39 | logits = torch.tensor( 40 | [[1, 1, 1, 1], [10000, -10000, -10000, -1000]], dtype=torch.float, device=device 41 | ) 42 | mask = torch.tensor([False, True], device=device) 43 | metric(logits, mask) 44 | assert metric.get_metric() == 0.0 45 | -------------------------------------------------------------------------------- /allennlp/commands/test_install.py: -------------------------------------------------------------------------------- 1 | """ 2 | The `test-install` subcommand provides a programmatic way to verify 3 | that AllenNLP has been successfully installed. 4 | """ 5 | 6 | import argparse 7 | import logging 8 | import pathlib 9 | 10 | from overrides import overrides 11 | import torch 12 | 13 | import allennlp 14 | from allennlp.common.util import import_module_and_submodules 15 | from allennlp.commands.subcommand import Subcommand 16 | from allennlp.version import VERSION 17 | 18 | 19 | logger = logging.getLogger(__name__) 20 | 21 | 22 | @Subcommand.register("test-install") 23 | class TestInstall(Subcommand): 24 | @overrides 25 | def add_subparser(self, parser: argparse._SubParsersAction) -> argparse.ArgumentParser: 26 | description = """Test that AllenNLP is installed correctly.""" 27 | subparser = parser.add_parser( 28 | self.name, description=description, help="Test AllenNLP installation." 29 | ) 30 | subparser.set_defaults(func=_run_test) 31 | return subparser 32 | 33 | 34 | def _get_module_root(): 35 | return pathlib.Path(allennlp.__file__).parent 36 | 37 | 38 | def _run_test(args: argparse.Namespace): 39 | # Make sure we can actually import the main modules without errors. 40 | import_module_and_submodules("allennlp.common") 41 | import_module_and_submodules("allennlp.data") 42 | import_module_and_submodules("allennlp.interpret") 43 | import_module_and_submodules("allennlp.models") 44 | import_module_and_submodules("allennlp.modules") 45 | import_module_and_submodules("allennlp.nn") 46 | import_module_and_submodules("allennlp.predictors") 47 | import_module_and_submodules("allennlp.training") 48 | logger.info("AllenNLP version %s installed to %s", VERSION, _get_module_root()) 49 | logger.info("Cuda devices available: %s", torch.cuda.device_count()) 50 | -------------------------------------------------------------------------------- /allennlp/common/tqdm.py: -------------------------------------------------------------------------------- 1 | """ 2 | `allennlp.common.tqdm.Tqdm` wraps tqdm so we can add configurable 3 | global defaults for certain tqdm parameters. 4 | """ 5 | 6 | try: 7 | SHELL = str(type(get_ipython())) # type:ignore # noqa: F821 8 | except: # noqa: E722 9 | SHELL = "" 10 | 11 | if "zmqshell.ZMQInteractiveShell" in SHELL: 12 | from tqdm import tqdm_notebook as _tqdm 13 | else: 14 | from tqdm import tqdm as _tqdm 15 | 16 | # This is neccesary to stop tqdm from hanging 17 | # when exceptions are raised inside iterators. 18 | # It should have been fixed in 4.2.1, but it still 19 | # occurs. 20 | # TODO(Mark): Remove this once tqdm cleans up after itself properly. 21 | # https://github.com/tqdm/tqdm/issues/469 22 | _tqdm.monitor_interval = 0 23 | 24 | 25 | class Tqdm: 26 | # These defaults are the same as the argument defaults in tqdm. 27 | default_mininterval: float = 0.1 28 | 29 | @staticmethod 30 | def set_default_mininterval(value: float) -> None: 31 | Tqdm.default_mininterval = value 32 | 33 | @staticmethod 34 | def set_slower_interval(use_slower_interval: bool) -> None: 35 | """ 36 | If `use_slower_interval` is `True`, we will dramatically slow down `tqdm's` default 37 | output rate. `tqdm's` default output rate is great for interactively watching progress, 38 | but it is not great for log files. You might want to set this if you are primarily going 39 | to be looking at output through log files, not the terminal. 40 | """ 41 | if use_slower_interval: 42 | Tqdm.default_mininterval = 10.0 43 | else: 44 | Tqdm.default_mininterval = 0.1 45 | 46 | @staticmethod 47 | def tqdm(*args, **kwargs): 48 | new_kwargs = {"mininterval": Tqdm.default_mininterval, **kwargs} 49 | 50 | return _tqdm(*args, **new_kwargs) 51 | -------------------------------------------------------------------------------- /allennlp/modules/seq2seq_encoders/pass_through_encoder.py: -------------------------------------------------------------------------------- 1 | from overrides import overrides 2 | import torch 3 | 4 | from allennlp.modules.seq2seq_encoders.seq2seq_encoder import Seq2SeqEncoder 5 | 6 | 7 | @Seq2SeqEncoder.register("pass_through") 8 | class PassThroughEncoder(Seq2SeqEncoder): 9 | """ 10 | This class allows you to specify skipping a `Seq2SeqEncoder` just 11 | by changing a configuration file. This is useful for ablations and 12 | measuring the impact of different elements of your model. 13 | 14 | Registered as a `Seq2SeqEncoder` with name "pass_through". 15 | """ 16 | 17 | def __init__(self, input_dim: int) -> None: 18 | super().__init__() 19 | self._input_dim = input_dim 20 | 21 | @overrides 22 | def get_input_dim(self) -> int: 23 | return self._input_dim 24 | 25 | @overrides 26 | def get_output_dim(self) -> int: 27 | return self._input_dim 28 | 29 | @overrides 30 | def is_bidirectional(self): 31 | return False 32 | 33 | @overrides 34 | def forward(self, inputs: torch.Tensor, mask: torch.BoolTensor = None) -> torch.Tensor: 35 | """ 36 | # Parameters 37 | 38 | inputs : `torch.Tensor`, required. 39 | A tensor of shape (batch_size, timesteps, input_dim) 40 | mask : `torch.BoolTensor`, optional (default = `None`). 41 | A tensor of shape (batch_size, timesteps). 42 | 43 | # Returns 44 | 45 | A tensor of shape (batch_size, timesteps, output_dim), 46 | where output_dim = input_dim. 47 | """ 48 | if mask is None: 49 | return inputs 50 | else: 51 | # We should mask out the output instead of the input. 52 | # But here, output = input, so we directly mask out the input. 53 | return inputs * mask.unsqueeze(dim=-1) 54 | -------------------------------------------------------------------------------- /allennlp/training/metrics/entropy.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | from overrides import overrides 4 | import torch 5 | 6 | from allennlp.training.metrics.metric import Metric 7 | 8 | 9 | @Metric.register("entropy") 10 | class Entropy(Metric): 11 | def __init__(self) -> None: 12 | self._entropy = 0.0 13 | self._count = 0 14 | 15 | @overrides 16 | def __call__( 17 | self, # type: ignore 18 | logits: torch.Tensor, 19 | mask: Optional[torch.BoolTensor] = None, 20 | ): 21 | """ 22 | # Parameters 23 | 24 | logits : `torch.Tensor`, required. 25 | A tensor of unnormalized log probabilities of shape (batch_size, ..., num_classes). 26 | mask : `torch.BoolTensor`, optional (default = `None`). 27 | A masking tensor of shape (batch_size, ...). 28 | """ 29 | logits, mask = self.detach_tensors(logits, mask) 30 | 31 | if mask is None: 32 | mask = torch.ones(logits.size()[:-1], device=logits.device).bool() 33 | 34 | log_probs = torch.nn.functional.log_softmax(logits, dim=-1) 35 | probabilities = torch.exp(log_probs) * mask.unsqueeze(-1) 36 | weighted_negative_likelihood = -log_probs * probabilities 37 | entropy = weighted_negative_likelihood.sum(-1) 38 | 39 | self._entropy += entropy.sum() / mask.sum() 40 | self._count += 1 41 | 42 | @overrides 43 | def get_metric(self, reset: bool = False): 44 | """ 45 | # Returns 46 | 47 | The scalar average entropy. 48 | """ 49 | average_value = self._entropy / self._count if self._count > 0 else 0 50 | if reset: 51 | self.reset() 52 | return average_value 53 | 54 | @overrides 55 | def reset(self): 56 | self._entropy = 0.0 57 | self._count = 0 58 | -------------------------------------------------------------------------------- /tests/data/fields/field_test.py: -------------------------------------------------------------------------------- 1 | from allennlp.data.fields import Field 2 | 3 | 4 | def test_eq_with_inheritance(): 5 | class SubField(Field): 6 | 7 | __slots__ = ["a"] 8 | 9 | def __init__(self, a): 10 | self.a = a 11 | 12 | class SubSubField(SubField): 13 | 14 | __slots__ = ["b"] 15 | 16 | def __init__(self, a, b): 17 | super().__init__(a) 18 | self.b = b 19 | 20 | class SubSubSubField(SubSubField): 21 | 22 | __slots__ = ["c"] 23 | 24 | def __init__(self, a, b, c): 25 | super().__init__(a, b) 26 | self.c = c 27 | 28 | assert SubField(1) == SubField(1) 29 | assert SubField(1) != SubField(2) 30 | 31 | assert SubSubField(1, 2) == SubSubField(1, 2) 32 | assert SubSubField(1, 2) != SubSubField(1, 1) 33 | assert SubSubField(1, 2) != SubSubField(2, 2) 34 | 35 | assert SubSubSubField(1, 2, 3) == SubSubSubField(1, 2, 3) 36 | assert SubSubSubField(1, 2, 3) != SubSubSubField(0, 2, 3) 37 | 38 | 39 | def test_eq_with_inheritance_for_non_slots_field(): 40 | class SubField(Field): 41 | def __init__(self, a): 42 | self.a = a 43 | 44 | assert SubField(1) == SubField(1) 45 | assert SubField(1) != SubField(2) 46 | 47 | 48 | def test_eq_with_inheritance_for_mixed_field(): 49 | class SubField(Field): 50 | 51 | __slots__ = ["a"] 52 | 53 | def __init__(self, a): 54 | self.a = a 55 | 56 | class SubSubField(SubField): 57 | def __init__(self, a, b): 58 | super().__init__(a) 59 | self.b = b 60 | 61 | assert SubField(1) == SubField(1) 62 | assert SubField(1) != SubField(2) 63 | 64 | assert SubSubField(1, 2) == SubSubField(1, 2) 65 | assert SubSubField(1, 2) != SubSubField(1, 1) 66 | assert SubSubField(1, 2) != SubSubField(2, 2) 67 | -------------------------------------------------------------------------------- /allennlp/training/momentum_schedulers/inverted_triangular.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.training.momentum_schedulers.momentum_scheduler import MomentumScheduler 4 | 5 | 6 | @MomentumScheduler.register("inverted_triangular") 7 | class InvertedTriangular(MomentumScheduler): 8 | """ 9 | Adjust momentum during training according to an inverted triangle-like schedule. 10 | 11 | The momentum starts off high, then decreases linearly for `cool_down` epochs, 12 | until reaching `1 / ratio` th of the original value. Then the momentum increases 13 | linearly for `warm_up` epochs until reaching its original value again. If there 14 | are still more epochs left over to train, the momentum will stay flat at the original 15 | value. 16 | 17 | Registered as a `MomentumScheduler` with name "inverted_triangular". The "optimizer" argument 18 | does not get an entry in a configuration file for the object. 19 | """ 20 | 21 | def __init__( 22 | self, 23 | optimizer: torch.optim.Optimizer, 24 | cool_down: int, 25 | warm_up: int, 26 | ratio: int = 10, 27 | last_epoch: int = -1, 28 | ) -> None: 29 | self.cool_down = cool_down 30 | self.warm_up = warm_up 31 | self.ratio = ratio 32 | super().__init__(optimizer, last_epoch) 33 | 34 | def get_values(self): 35 | step = self.last_epoch + 1 36 | if step <= self.cool_down: 37 | values = [m - (m - m / self.ratio) * (step / self.cool_down) for m in self.base_values] 38 | elif step <= self.cool_down + self.warm_up: 39 | values = [ 40 | (m / self.ratio) + (m - m / self.ratio) * (step - self.cool_down) / self.warm_up 41 | for m in self.base_values 42 | ] 43 | else: 44 | values = self.base_values 45 | 46 | return values 47 | -------------------------------------------------------------------------------- /allennlp/tools/EVALB/bug/bug.rsl-old: -------------------------------------------------------------------------------- 1 | Sent. Matched Bracket Cross Correct Tag 2 | ID Len. Stat. Recal Prec. Bracket gold test Bracket Words Tags Accracy 3 | ============================================================================ 4 | 1 : Length unmatch (33|35) 5 | 1 37 1 0.00 0.00 0 0 0 0 0 0 0.00 6 | 2 : Length unmatch (19|21) 7 | 2 21 1 0.00 0.00 0 0 0 0 0 0 0.00 8 | 3 : Length unmatch (44|45) 9 | 3 47 1 0.00 0.00 0 0 0 0 0 0 0.00 10 | 4 : Length unmatch (24|26) 11 | 4 26 1 0.00 0.00 0 0 0 0 0 0 0.00 12 | 5 : Length unmatch (38|39) 13 | 5 44 1 0.00 0.00 0 0 0 0 0 0 0.00 14 | ============================================================================ 15 | 0 0 0.00 16 | 17 | === Summary === 18 | 19 | -- All -- 20 | Number of sentence = 5 21 | Number of Error sentence = 5 22 | Number of Skip sentence = 0 23 | Number of Valid sentence = 0 24 | Bracketing Recall = 0.00 25 | Bracketing Precision = 0.00 26 | Bracketing FMeasure = nan 27 | Complete match = 0.00 28 | Average crossing = 0.00 29 | No crossing = 0.00 30 | 2 or less crossing = 0.00 31 | Tagging accuracy = 0.00 32 | 33 | -- len<=40 -- 34 | Number of sentence = 3 35 | Number of Error sentence = 3 36 | Number of Skip sentence = 0 37 | Number of Valid sentence = 0 38 | Bracketing Recall = 0.00 39 | Bracketing Precision = 0.00 40 | Bracketing FMeasure = nan 41 | Complete match = 0.00 42 | Average crossing = 0.00 43 | No crossing = 0.00 44 | 2 or less crossing = 0.00 45 | Tagging accuracy = 0.00 46 | -------------------------------------------------------------------------------- /allennlp/predictors/text_classifier.py: -------------------------------------------------------------------------------- 1 | from typing import List, Dict 2 | 3 | from overrides import overrides 4 | import numpy 5 | 6 | from allennlp.common.util import JsonDict 7 | from allennlp.data import Instance 8 | from allennlp.predictors.predictor import Predictor 9 | from allennlp.data.fields import LabelField 10 | from allennlp.data.tokenizers.spacy_tokenizer import SpacyTokenizer 11 | 12 | 13 | @Predictor.register("text_classifier") 14 | class TextClassifierPredictor(Predictor): 15 | """ 16 | Predictor for any model that takes in a sentence and returns 17 | a single class for it. In particular, it can be used with 18 | the [`BasicClassifier`](../models/basic_classifier.md) model. 19 | 20 | Registered as a `Predictor` with name "text_classifier". 21 | """ 22 | 23 | def predict(self, sentence: str) -> JsonDict: 24 | return self.predict_json({"sentence": sentence}) 25 | 26 | @overrides 27 | def _json_to_instance(self, json_dict: JsonDict) -> Instance: 28 | """ 29 | Expects JSON that looks like `{"sentence": "..."}`. 30 | Runs the underlying model, and adds the `"label"` to the output. 31 | """ 32 | sentence = json_dict["sentence"] 33 | if not hasattr(self._dataset_reader, "tokenizer") and not hasattr( 34 | self._dataset_reader, "_tokenizer" 35 | ): 36 | tokenizer = SpacyTokenizer() 37 | sentence = [str(t) for t in tokenizer.tokenize(sentence)] 38 | return self._dataset_reader.text_to_instance(sentence) 39 | 40 | @overrides 41 | def predictions_to_labeled_instances( 42 | self, instance: Instance, outputs: Dict[str, numpy.ndarray] 43 | ) -> List[Instance]: 44 | new_instance = instance.duplicate() 45 | label = numpy.argmax(outputs["probs"]) 46 | new_instance.add_field("label", LabelField(int(label), skip_indexing=True)) 47 | return [new_instance] 48 | -------------------------------------------------------------------------------- /scripts/tests/py2md/py2md_test.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import pytest 4 | 5 | from allennlp.common.testing import AllenNlpTestCase 6 | from scripts.py2md import py2md, Param, DocstringError 7 | 8 | 9 | class TestPy2md(AllenNlpTestCase): 10 | def test_basic_example(self, capsys): 11 | py2md("scripts.tests.py2md.basic_example") 12 | captured = capsys.readouterr() 13 | 14 | with open( 15 | self.PROJECT_ROOT / "scripts" / "tests" / "py2md" / "basic_example_expected_output.md" 16 | ) as f: 17 | expected = f.read() 18 | 19 | assert captured.out.split("\n") == expected.split("\n") 20 | 21 | 22 | @pytest.mark.parametrize( 23 | "line_in, line_out", 24 | [ 25 | ( 26 | "a : `int`, optional (default = `None`)", 27 | "- __a__ : `int`, optional (default = `None`)
", 28 | ), 29 | ( 30 | "foo : `Tuple[int, ...]`, optional (default = `()`)", 31 | "- __foo__ : `Tuple[int, ...]`, optional (default = `()`)
", 32 | ), 33 | ("a : `int`, required", "- __a__ : `int`
"), 34 | ("a : `int`", "- __a__ : `int`
"), 35 | ("_a : `int`", "- __\\_a__ : `int`
"), 36 | ("a_ : `int`", "- __a\\___ : `int`
"), 37 | ], 38 | ) 39 | def test_param_from_and_to_line(line_in: str, line_out: Optional[str]): 40 | param = Param.from_line(line_in) 41 | assert param is not None 42 | assert param.to_line() == line_out 43 | 44 | 45 | @pytest.mark.parametrize( 46 | "line", 47 | [ 48 | "a : `int`, optional (default = None)", 49 | "a : `int`, optional (default = `None)", 50 | "a : `int`, optional (default = None`)", 51 | "a : int", 52 | "a : `int", 53 | "a : int`", 54 | ], 55 | ) 56 | def test_param_from_bad_line_raises(line: str): 57 | with pytest.raises(DocstringError): 58 | Param.from_line(line) 59 | -------------------------------------------------------------------------------- /tests/modules/seq2seq_encoders/gated_cnn_encoder_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from allennlp.common.testing import AllenNlpTestCase 4 | from allennlp.modules.seq2seq_encoders.gated_cnn_encoder import GatedCnnEncoder 5 | 6 | 7 | class TestGatedCnnEncoder(AllenNlpTestCase): 8 | def test_gated_cnn_encoder(self): 9 | cnn_encoder = GatedCnnEncoder( 10 | input_dim=32, 11 | layers=[[[4, 32]], [[1, 16], [5, 16], [1, 32]], [[1, 64], [5, 64], [1, 32]]], 12 | ) 13 | 14 | token_embeddings = torch.rand(5, 10, 32) 15 | mask = torch.ones(5, 10).bool() 16 | mask[0, 7:] = False 17 | mask[1, 5:] = False 18 | 19 | output = cnn_encoder(token_embeddings, mask) 20 | assert list(output.size()) == [5, 10, 64] 21 | 22 | def test_gated_cnn_encoder_dilations(self): 23 | cnn_encoder = GatedCnnEncoder( 24 | input_dim=32, layers=[[[2, 32, 1]], [[2, 32, 2]], [[2, 32, 4]], [[2, 32, 8]]] 25 | ) 26 | 27 | token_embeddings = torch.rand(5, 10, 32) 28 | mask = torch.ones(5, 10).bool() 29 | mask[0, 7:] = False 30 | mask[1, 5:] = False 31 | 32 | output = cnn_encoder(token_embeddings, mask) 33 | assert list(output.size()) == [5, 10, 64] 34 | 35 | def test_gated_cnn_encoder_layers(self): 36 | cnn_encoder = GatedCnnEncoder( 37 | input_dim=32, 38 | layers=[[[4, 32]], [[1, 16], [5, 16], [1, 32]], [[1, 64], [5, 64], [1, 32]]], 39 | return_all_layers=True, 40 | ) 41 | 42 | token_embeddings = torch.rand(5, 10, 32) 43 | mask = torch.ones(5, 10).bool() 44 | mask[0, 7:] = False 45 | mask[1, 5:] = False 46 | 47 | output = cnn_encoder(token_embeddings, mask) 48 | assert len(output) == 3 49 | concat_layers = torch.cat([layer.unsqueeze(1) for layer in output], dim=1) 50 | assert list(concat_layers.size()) == [5, 3, 10, 64] 51 | -------------------------------------------------------------------------------- /tests/models/test_model_test_case.py: -------------------------------------------------------------------------------- 1 | import json 2 | import pytest 3 | 4 | from allennlp.common.testing import ModelTestCase 5 | 6 | 7 | class ModelWithIncorrectValidationMetricTest(ModelTestCase): 8 | """ 9 | This test case checks some validating functionality that is implemented 10 | in `ensure_model_can_train_save_and_load` 11 | """ 12 | 13 | def setup_method(self): 14 | super().setup_method() 15 | self.set_up_model( 16 | self.FIXTURES_ROOT / "simple_tagger" / "model_test_case.jsonnet", 17 | self.FIXTURES_ROOT / "data" / "sequence_tagging.tsv", 18 | ) 19 | 20 | def test_01_test_validation_metric_does_not_exist(self): 21 | overrides = {"trainer.num_epochs": 2} 22 | pytest.raises( 23 | AssertionError, 24 | self.ensure_model_can_train_save_and_load, 25 | self.param_file, 26 | metric_to_check="non_existent_metric", 27 | metric_terminal_value=0.0, 28 | overrides=json.dumps(overrides), 29 | ) 30 | 31 | def test_02a_test_validation_metric_terminal_value_not_set(self): 32 | pytest.raises( 33 | AssertionError, 34 | self.ensure_model_can_train_save_and_load, 35 | self.param_file, 36 | metric_to_check="accuracy", 37 | metric_terminal_value=None, 38 | ) 39 | 40 | def test_02b_test_validation_metric_terminal_value_not_met(self): 41 | pytest.raises( 42 | AssertionError, 43 | self.ensure_model_can_train_save_and_load, 44 | self.param_file, 45 | metric_to_check="accuracy", 46 | metric_terminal_value=0.0, 47 | ) 48 | 49 | def test_03_test_validation_metric_exists_and_its_terminal_value_is_met(self): 50 | self.ensure_model_can_train_save_and_load( 51 | self.param_file, metric_to_check="accuracy", metric_terminal_value=1.0, 52 | ) 53 | -------------------------------------------------------------------------------- /tests/modules/lstm_cell_with_projection_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import torch 3 | 4 | from allennlp.modules.lstm_cell_with_projection import LstmCellWithProjection 5 | from allennlp.common.testing import AllenNlpTestCase 6 | 7 | 8 | class TestLstmCellWithProjection(AllenNlpTestCase): 9 | def test_elmo_lstm_cell_completes_forward_pass(self): 10 | input_tensor = torch.rand(4, 5, 3) 11 | input_tensor[1, 4:, :] = 0.0 12 | input_tensor[2, 2:, :] = 0.0 13 | input_tensor[3, 1:, :] = 0.0 14 | 15 | initial_hidden_state = torch.ones([1, 4, 5]) 16 | initial_memory_state = torch.ones([1, 4, 7]) 17 | 18 | lstm = LstmCellWithProjection( 19 | input_size=3, 20 | hidden_size=5, 21 | cell_size=7, 22 | memory_cell_clip_value=2, 23 | state_projection_clip_value=1, 24 | ) 25 | output_sequence, lstm_state = lstm( 26 | input_tensor, [5, 4, 2, 1], (initial_hidden_state, initial_memory_state) 27 | ) 28 | numpy.testing.assert_array_equal(output_sequence.data[1, 4:, :].numpy(), 0.0) 29 | numpy.testing.assert_array_equal(output_sequence.data[2, 2:, :].numpy(), 0.0) 30 | numpy.testing.assert_array_equal(output_sequence.data[3, 1:, :].numpy(), 0.0) 31 | 32 | # Test the state clipping. 33 | numpy.testing.assert_array_less(output_sequence.data.numpy(), 1.0) 34 | numpy.testing.assert_array_less(-output_sequence.data.numpy(), 1.0) 35 | 36 | # LSTM state should be (num_layers, batch_size, hidden_size) 37 | assert list(lstm_state[0].size()) == [1, 4, 5] 38 | # LSTM memory cell should be (num_layers, batch_size, cell_size) 39 | assert list((lstm_state[1].size())) == [1, 4, 7] 40 | 41 | # Test the cell clipping. 42 | numpy.testing.assert_array_less(lstm_state[0].data.numpy(), 2.0) 43 | numpy.testing.assert_array_less(-lstm_state[0].data.numpy(), 2.0) 44 | -------------------------------------------------------------------------------- /allennlp/modules/attention/attention.py: -------------------------------------------------------------------------------- 1 | """ 2 | An *attention* module that computes the similarity between 3 | an input vector and the rows of a matrix. 4 | """ 5 | 6 | import torch 7 | 8 | from overrides import overrides 9 | from allennlp.common.registrable import Registrable 10 | from allennlp.nn.util import masked_softmax 11 | 12 | 13 | class Attention(torch.nn.Module, Registrable): 14 | """ 15 | An `Attention` takes two inputs: a (batched) vector and a matrix, plus an optional mask on the 16 | rows of the matrix. We compute the similarity between the vector and each row in the matrix, 17 | and then (optionally) perform a softmax over rows using those computed similarities. 18 | 19 | 20 | Inputs: 21 | 22 | - vector: shape `(batch_size, embedding_dim)` 23 | - matrix: shape `(batch_size, num_rows, embedding_dim)` 24 | - matrix_mask: shape `(batch_size, num_rows)`, specifying which rows are just padding. 25 | 26 | Output: 27 | 28 | - attention: shape `(batch_size, num_rows)`. 29 | 30 | # Parameters 31 | 32 | normalize : `bool`, optional (default = `True`) 33 | If true, we normalize the computed similarities with a softmax, to return a probability 34 | distribution for your attention. If false, this is just computing a similarity score. 35 | """ 36 | 37 | def __init__(self, normalize: bool = True) -> None: 38 | super().__init__() 39 | self._normalize = normalize 40 | 41 | @overrides 42 | def forward( 43 | self, vector: torch.Tensor, matrix: torch.Tensor, matrix_mask: torch.BoolTensor = None 44 | ) -> torch.Tensor: 45 | similarities = self._forward_internal(vector, matrix) 46 | if self._normalize: 47 | return masked_softmax(similarities, matrix_mask) 48 | else: 49 | return similarities 50 | 51 | def _forward_internal(self, vector: torch.Tensor, matrix: torch.Tensor) -> torch.Tensor: 52 | raise NotImplementedError 53 | -------------------------------------------------------------------------------- /allennlp/training/metrics/mean_absolute_error.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | from overrides import overrides 4 | import torch 5 | 6 | from allennlp.training.metrics.metric import Metric 7 | 8 | 9 | @Metric.register("mean_absolute_error") 10 | class MeanAbsoluteError(Metric): 11 | """ 12 | This `Metric` calculates the mean absolute error (MAE) between two tensors. 13 | """ 14 | 15 | def __init__(self) -> None: 16 | self._absolute_error = 0.0 17 | self._total_count = 0.0 18 | 19 | def __call__( 20 | self, 21 | predictions: torch.Tensor, 22 | gold_labels: torch.Tensor, 23 | mask: Optional[torch.BoolTensor] = None, 24 | ): 25 | """ 26 | # Parameters 27 | 28 | predictions : `torch.Tensor`, required. 29 | A tensor of predictions of shape (batch_size, ...). 30 | gold_labels : `torch.Tensor`, required. 31 | A tensor of the same shape as `predictions`. 32 | mask : `torch.BoolTensor`, optional (default = `None`). 33 | A tensor of the same shape as `predictions`. 34 | """ 35 | predictions, gold_labels, mask = self.detach_tensors(predictions, gold_labels, mask) 36 | 37 | absolute_errors = torch.abs(predictions - gold_labels) 38 | if mask is not None: 39 | absolute_errors *= mask 40 | self._total_count += torch.sum(mask) 41 | else: 42 | self._total_count += gold_labels.numel() 43 | self._absolute_error += torch.sum(absolute_errors) 44 | 45 | def get_metric(self, reset: bool = False): 46 | """ 47 | # Returns 48 | 49 | The accumulated mean absolute error. 50 | """ 51 | mean_absolute_error = self._absolute_error / self._total_count 52 | if reset: 53 | self.reset() 54 | return mean_absolute_error 55 | 56 | @overrides 57 | def reset(self): 58 | self._absolute_error = 0.0 59 | self._total_count = 0.0 60 | -------------------------------------------------------------------------------- /allennlp/training/metrics/metric.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Iterable, List, Optional, Tuple, Union 2 | 3 | import torch 4 | 5 | from allennlp.common.registrable import Registrable 6 | 7 | 8 | class Metric(Registrable): 9 | """ 10 | A very general abstract class representing a metric which can be 11 | accumulated. 12 | """ 13 | 14 | def __call__( 15 | self, predictions: torch.Tensor, gold_labels: torch.Tensor, mask: Optional[torch.BoolTensor] 16 | ): 17 | """ 18 | # Parameters 19 | 20 | predictions : `torch.Tensor`, required. 21 | A tensor of predictions. 22 | gold_labels : `torch.Tensor`, required. 23 | A tensor corresponding to some gold label to evaluate against. 24 | mask : `torch.BoolTensor`, optional (default = `None`). 25 | A mask can be passed, in order to deal with metrics which are 26 | computed over potentially padded elements, such as sequence labels. 27 | """ 28 | raise NotImplementedError 29 | 30 | def get_metric( 31 | self, reset: bool 32 | ) -> Union[float, Tuple[float, ...], Dict[str, float], Dict[str, List[float]]]: 33 | """ 34 | Compute and return the metric. Optionally also call `self.reset`. 35 | """ 36 | raise NotImplementedError 37 | 38 | def reset(self) -> None: 39 | """ 40 | Reset any accumulators or internal state. 41 | """ 42 | raise NotImplementedError 43 | 44 | @staticmethod 45 | def detach_tensors(*tensors: torch.Tensor) -> Iterable[torch.Tensor]: 46 | """ 47 | If you actually passed gradient-tracking Tensors to a Metric, there will be 48 | a huge memory leak, because it will prevent garbage collection for the computation 49 | graph. This method ensures the tensors are detached. 50 | """ 51 | # Check if it's actually a tensor in case something else was passed. 52 | return (x.detach() if isinstance(x, torch.Tensor) else x for x in tensors) 53 | -------------------------------------------------------------------------------- /allennlp/common/plugins.py: -------------------------------------------------------------------------------- 1 | """ 2 | Plugin management. 3 | 4 | AllenNLP supports loading "plugins" dynamically. A plugin is just a Python package that 5 | can be found and imported by AllenNLP. This is done by creating a file named `.allennlp_plugins` 6 | in the directory where the `allennlp` command is run that lists the modules that should be loaded, 7 | one per line. 8 | """ 9 | 10 | import importlib 11 | import logging 12 | import os 13 | from typing import Iterable 14 | 15 | from allennlp.common.util import push_python_path, import_module_and_submodules 16 | 17 | logger = logging.getLogger(__name__) 18 | 19 | 20 | DEFAULT_PLUGINS = ("allennlp_models", "allennlp_server") 21 | 22 | 23 | def discover_file_plugins(plugins_filename: str = ".allennlp_plugins") -> Iterable[str]: 24 | """ 25 | Returns an iterable of the plugins found, declared within a file whose path is `plugins_filename`. 26 | """ 27 | if os.path.isfile(plugins_filename): 28 | with open(plugins_filename) as file_: 29 | for module_name in file_.readlines(): 30 | module_name = module_name.strip() 31 | if module_name: 32 | yield module_name 33 | else: 34 | return [] 35 | 36 | 37 | def discover_plugins() -> Iterable[str]: 38 | """ 39 | Returns an iterable of the plugins found. 40 | """ 41 | with push_python_path("."): 42 | yield from discover_file_plugins() 43 | 44 | 45 | def import_plugins() -> None: 46 | """ 47 | Imports the plugins found with `discover_plugins()`. 48 | """ 49 | for module in DEFAULT_PLUGINS: 50 | try: 51 | # For default plugins we recursively import everything. 52 | import_module_and_submodules(module) 53 | except ModuleNotFoundError: 54 | pass 55 | for module_name in discover_plugins(): 56 | try: 57 | importlib.import_module(module_name) 58 | except ModuleNotFoundError as e: 59 | logger.error(f"Plugin {module_name} could not be loaded: {e}") 60 | -------------------------------------------------------------------------------- /allennlp/modules/seq2seq_encoders/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Modules that transform a sequence of input vectors 3 | into a sequence of output vectors. 4 | Some are just basic wrappers around existing PyTorch modules, 5 | others are AllenNLP modules. 6 | 7 | The available Seq2Seq encoders are 8 | 9 | - `"gru"` : https://pytorch.org/docs/master/nn.html#torch.nn.GRU 10 | - `"lstm"` : https://pytorch.org/docs/master/nn.html#torch.nn.LSTM 11 | - `"rnn"` : https://pytorch.org/docs/master/nn.html#torch.nn.RNN 12 | - `"augmented_lstm"` : allennlp.modules.augmented_lstm.AugmentedLstm 13 | - `"alternating_lstm"` : allennlp.modules.stacked_alternating_lstm.StackedAlternatingLstm 14 | - `"alternating_highway_lstm"` : allennlp.modules.stacked_alternating_lstm.StackedAlternatingLstm (GPU only) 15 | - `"stacked_self_attention"` : allennlp.modules.stacked_self_attention.StackedSelfAttentionEncoder 16 | - `"multi_head_self_attention"` : allennlp.modules.multi_head_self_attention.MultiHeadSelfAttention 17 | - `"pass_through"` : allennlp.modules.pass_through_encoder.PassThroughEncoder 18 | - `"feedforward"` : allennlp.modules.feedforward_encoder.FeedforwardEncoder 19 | - `"pytorch_transformer"` : allennlp.modules.seq2seq_encoders.PytorchTransformer 20 | """ 21 | 22 | from allennlp.modules.seq2seq_encoders.compose_encoder import ComposeEncoder 23 | from allennlp.modules.seq2seq_encoders.feedforward_encoder import FeedForwardEncoder 24 | from allennlp.modules.seq2seq_encoders.gated_cnn_encoder import GatedCnnEncoder 25 | from allennlp.modules.seq2seq_encoders.pass_through_encoder import PassThroughEncoder 26 | from allennlp.modules.seq2seq_encoders.pytorch_seq2seq_wrapper import ( 27 | AugmentedLstmSeq2SeqEncoder, 28 | GruSeq2SeqEncoder, 29 | LstmSeq2SeqEncoder, 30 | PytorchSeq2SeqWrapper, 31 | RnnSeq2SeqEncoder, 32 | StackedAlternatingLstmSeq2SeqEncoder, 33 | StackedBidirectionalLstmSeq2SeqEncoder, 34 | ) 35 | from allennlp.modules.seq2seq_encoders.seq2seq_encoder import Seq2SeqEncoder 36 | from allennlp.modules.seq2seq_encoders.pytorch_transformer_wrapper import PytorchTransformer 37 | -------------------------------------------------------------------------------- /tests/data/fields/index_field_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import pytest 3 | 4 | from allennlp.common.checks import ConfigurationError 5 | from allennlp.common.testing import AllenNlpTestCase 6 | from allennlp.data import Token 7 | from allennlp.data.fields import TextField, IndexField 8 | from allennlp.data.token_indexers import SingleIdTokenIndexer 9 | 10 | 11 | class TestIndexField(AllenNlpTestCase): 12 | def setup_method(self): 13 | super().setup_method() 14 | self.text = TextField( 15 | [Token(t) for t in ["here", "is", "a", "sentence", "."]], 16 | {"words": SingleIdTokenIndexer("words")}, 17 | ) 18 | 19 | def test_as_tensor_converts_field_correctly(self): 20 | index_field = IndexField(4, self.text) 21 | tensor = index_field.as_tensor(index_field.get_padding_lengths()).detach().cpu().numpy() 22 | numpy.testing.assert_array_equal(tensor, numpy.array([4])) 23 | 24 | def test_index_field_raises_on_incorrect_label_type(self): 25 | with pytest.raises(ConfigurationError): 26 | _ = IndexField("hello", self.text) 27 | 28 | def test_index_field_empty_field_works(self): 29 | index_field = IndexField(4, self.text) 30 | empty_index = index_field.empty_field() 31 | assert empty_index.sequence_index == -1 32 | 33 | def test_printing_doesnt_crash(self): 34 | print(self.text) 35 | 36 | def test_equality(self): 37 | index_field1 = IndexField(4, self.text) 38 | index_field2 = IndexField(4, self.text) 39 | index_field3 = IndexField( 40 | 4, 41 | TextField( 42 | [Token(t) for t in ["AllenNLP", "is", "the", "bomb", "!"]], 43 | {"words": SingleIdTokenIndexer("words")}, 44 | ), 45 | ) 46 | 47 | assert index_field1 == 4 48 | assert index_field1 == index_field1 49 | assert index_field1 == index_field2 50 | 51 | assert index_field1 != index_field3 52 | assert index_field2 != index_field3 53 | assert index_field3 == index_field3 54 | -------------------------------------------------------------------------------- /test_fixtures/data/text_classification_json/imdb_corpus.jsonl: -------------------------------------------------------------------------------- 1 | {"id": "train_5011", "orig": "aclImdb/train/neg/5011_1.txt", "rating": 1, "label": "neg", "text": "...And I never thought a movie deserved to be awarded a 1! But this one is honestly the worst movie I've ever watched. My wife picked it up because of the cast, but the storyline right since the DVD box seemed quite predictable. It is not a mystery, nor a juvenile-catching film. It does not include any sensuality, if that's what the title could remotely have suggest any of you. This is just a total no-no. Don't waste your time or money unless you feel like watching a bunch of youngsters in a as-grown-up kind of Gothic setting, where a killer is going after them. Nothing new, nothing interesting, nothing worth watching. Max Makowski makes the worst of Nick Stahl."} 2 | {"id": "train_10433", "orig": "aclImdb/train/neg/10433_4.txt", "rating": 4, "label": "pos", "text": "The fight scenes were great. Loved the old and newer cylons and how they painted the ones on their side. It was the ending that I hated. I was disappointed that it was earth but 150k years back. But to travel all that way just to start over? Are you kidding me? 38k people that fought for their very existence and once they get to paradise, they abandon technology? No way. Sure they were eating paper and rationing food, but that is over. They can live like humans again. They only have one good doctor. What are they going to do when someone has a tooth ache never mind giving birth... yea right. No one would have made that choice."} 3 | {"id": "train_11872", "orig": "aclImdb/train/neg/11872_1.txt", "rating": 1, "label": "neg", "text": "The only way this is a family drama is if parents explain everything wrong with its message.

SPOILER: they feed a deer for a year and then kill it for eating their food after killing its mother and at first pontificating about taking responsibility for their actions. They blame bears and deer for \"misbehaving\" by eating while they take no responsibility to use adequate locks and fences or even learn to shoot instead of twice maiming animals and letting them linger."} --------------------------------------------------------------------------------