From 599bf07d614b5d2b593c1f94c2068ae5e0739d36 Mon Sep 17 00:00:00 2001 From: Guanheng Zhang Date: Wed, 25 Mar 2020 08:01:07 -0700 Subject: [PATCH 01/68] include pytorch 1.5.0-rc1 for CI test --- build_tools/travis/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_tools/travis/install.sh b/build_tools/travis/install.sh index e94013eca9..57370136dc 100644 --- a/build_tools/travis/install.sh +++ b/build_tools/travis/install.sh @@ -61,7 +61,7 @@ if [[ "$SKIP_TESTS" != "true" ]]; then # python -m nltk.downloader perluniprops nonbreaking_prefixes # # PyTorch - conda install --yes pytorch -c pytorch-nightly + conda install --yes pytorch -c pytorch-test # Installation python setup.py install From 442fcf0b90fe96e356259f3e30a8b4002e9f58f9 Mon Sep 17 00:00:00 2001 From: Guanheng Zhang Date: Wed, 25 Mar 2020 10:26:06 -0700 Subject: [PATCH 02/68] bump up the version --- torchtext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchtext/__init__.py b/torchtext/__init__.py index 1f31d001c5..db4484fdf1 100644 --- a/torchtext/__init__.py +++ b/torchtext/__init__.py @@ -4,7 +4,7 @@ from . import vocab from . import experimental -__version__ = '0.5.1' +__version__ = '0.6.0' __all__ = ['data', 'datasets', From db4d4fde12018fd6880e4f7e04d5e3aca981759d Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Wed, 29 Apr 2020 20:56:45 -0700 Subject: [PATCH 03/68] Set up ShipIt fbshipit-source-id: bb7d2eb52240c7223b57c3c9624e61d116e77e39 From db354a3e3d83a64dd83d602388153d5bd823f3dd Mon Sep 17 00:00:00 2001 From: cpuhrsch Date: Thu, 30 Apr 2020 21:49:58 -0400 Subject: [PATCH 04/68] Re-sync with internal repository (#749) --- .github/ISSUE_TEMPLATE/bug-report.md | 48 ------- .github/ISSUE_TEMPLATE/documentation.md | 10 -- .github/ISSUE_TEMPLATE/feature-request.md | 24 ---- .../ISSUE_TEMPLATE/questions-help-support.md | 10 -- .gitignore | 122 ------------------ .travis.yml | 28 ---- build_tools/conda/torchtext/meta.yaml | 35 ----- build_tools/travis/after_success.sh | 13 -- build_tools/travis/install.sh | 68 ---------- build_tools/travis/test_script.sh | 26 ---- test/.gitignore | 0 .flake8 => tox.ini | 2 +- 12 files changed, 1 insertion(+), 385 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug-report.md delete mode 100644 .github/ISSUE_TEMPLATE/documentation.md delete mode 100644 .github/ISSUE_TEMPLATE/feature-request.md delete mode 100644 .github/ISSUE_TEMPLATE/questions-help-support.md delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 build_tools/conda/torchtext/meta.yaml delete mode 100644 build_tools/travis/after_success.sh delete mode 100644 build_tools/travis/install.sh delete mode 100644 build_tools/travis/test_script.sh delete mode 100644 test/.gitignore rename .flake8 => tox.ini (51%) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md deleted file mode 100644 index 15104939bf..0000000000 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: "\U0001F41B Bug Report" -about: Submit a bug report to help us improve TorchText - ---- - -## 🐛 Bug -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Environment** - -Please copy and paste the output from our -[environment collection script](https://raw.githubusercontent.com/pytorch/text/master/torchtext/utils/collect_env.py) -(or fill out the checklist below manually). - -You can get the script and run it with: -``` -wget https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect_env.py -# For security purposes, please check the contents of collect_env.py before running it. -python collect_env.py -python -c "import torchtext; print(\"torchtext version is \", torchtext.__version__)" -``` - - - PyTorch Version (e.g., 1.0): - - OS (e.g., Linux): - - How you installed PyTorch (`conda`, `pip`, source): - - Build command you used (if compiling from source): - - Python version: - - CUDA/cuDNN version: - - GPU models and configuration: - - Any other relevant information: - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md deleted file mode 100644 index b9e37a2774..0000000000 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: "\U0001F4DA Documentation" -about: Report an issue related to TorchText - ---- - -## 📚 Documentation - -**Description** - diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md deleted file mode 100644 index 4872607a45..0000000000 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: "\U0001F680Feature Request" -about: Submit a proposal/request for a new TorchText feature - ---- - -## 🚀 Feature - - -**Motivation** - - - -**Pitch** - - - -**Alternatives** - - - -**Additional context** - - diff --git a/.github/ISSUE_TEMPLATE/questions-help-support.md b/.github/ISSUE_TEMPLATE/questions-help-support.md deleted file mode 100644 index d1e8eab0dc..0000000000 --- a/.github/ISSUE_TEMPLATE/questions-help-support.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: "❓Questions/Help/Support" -about: Do you need support? We have resources. - ---- - -## ❓ Questions and Help - -**Description** - diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8e2279529b..0000000000 --- a/.gitignore +++ /dev/null @@ -1,122 +0,0 @@ -*.txt -*.zip -*~ -.vector_cache -.idea/ - -# Documentation -docs/build - -# Download folder -.data - -# Created by https://www.gitignore.io/api/python - -### Python ### -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule.* - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ - -# End of https://www.gitignore.io/api/python - -# vim -*.swp -*.swo diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1c8f2707aa..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -dist: trusty - -language: python - -cache: - directories: - - /home/travis/download - - /home/travis/.cache/pip - -# This matrix tests that the code works on Python 2.7, -# 3.5, 3.6 (same versions as PyTorch CI), and passes lint. -matrix: - fast_finish: true - include: - - env: PYTHON_VERSION="3.5" COVERAGE="true" - - env: PYTHON_VERSION="3.6" COVERAGE="true" - - env: PYTHON_VERSION="3.6" RUN_FLAKE8="true" SKIP_TESTS="true" - - env: PYTHON_VERSION="3.6" RUN_SLOW="true" COVERAGE="true" - sudo: required - allow_failures: - - env: PYTHON_VERSION="3.6" RUN_SLOW="true" COVERAGE="true" - -notifications: - email: false - -install: source build_tools/travis/install.sh -script: bash build_tools/travis/test_script.sh -after_success: source build_tools/travis/after_success.sh diff --git a/build_tools/conda/torchtext/meta.yaml b/build_tools/conda/torchtext/meta.yaml deleted file mode 100644 index 8d4c8b6898..0000000000 --- a/build_tools/conda/torchtext/meta.yaml +++ /dev/null @@ -1,35 +0,0 @@ -package: - name: torchtext - version: 0.4.0 - -source: - url: https://github.com/pytorch/text/archive/0.4.0.zip - -requirements: - build: - - python - - setuptools - - run: - - python - - tqdm - - numpy >=1.11 - - pytorch >=1.2 - - requests - - six - -build: - number: 1 - noarch: python - script: python setup.py install --single-version-externally-managed --record=record.txt - -test: - imports: - - torchtext - - torchtext.data - -about: - home: https://github.com/pytorch/text - license: BSD - license_file: LICENSE - summary: 'PyTorch Data loaders and abstractions for text and NLP' diff --git a/build_tools/travis/after_success.sh b/build_tools/travis/after_success.sh deleted file mode 100644 index 5f672c0dbb..0000000000 --- a/build_tools/travis/after_success.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# This script is meant to be called by the "after_success" step defined in -# .travis.yml. See http://docs.travis-ci.com/ for more details. - -set -e - -if [[ "$COVERAGE" == "true" ]]; then - # Ignore codecov failures as the codecov server is not - # very reliable but we don't want travis to report a failure - # in the github UI just because the coverage report failed to - # be published. - codecov || echo "codecov upload failed" -fi diff --git a/build_tools/travis/install.sh b/build_tools/travis/install.sh deleted file mode 100644 index 57370136dc..0000000000 --- a/build_tools/travis/install.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# This script is meant to be called by the "install" step defined in -# .travis.yml. See http://docs.travis-ci.com/ for more details. -# The behavior of the script is controlled by environment variabled defined -# in the .travis.yml in the top level folder of the project. - -set -e - -echo 'List files from cached directories' -if [ -d $HOME/download ]; then - echo 'download:' - ls $HOME/download -fi -if [ -d $HOME/.cache/pip ]; then - echo 'pip:' - ls $HOME/.cache/pip -fi - -# Deactivate the travis-provided virtual environment and setup a -# conda-based environment instead -deactivate - -# Add the miniconda bin directory to $PATH -export PATH=/home/travis/miniconda3/bin:$PATH -echo $PATH - -# Use the miniconda installer for setup of conda itself -pushd . -cd -mkdir -p download -cd download -if [[ ! -f /home/travis/miniconda3/bin/activate ]] -then - if [[ ! -f miniconda.sh ]] - then - wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh \ - -O miniconda.sh - fi - chmod +x miniconda.sh && ./miniconda.sh -b -f - conda update --yes conda - echo "Creating environment to run tests in." - conda create -n testenv --yes python="$PYTHON_VERSION" -fi -cd .. -popd - -# Activate the python environment we created. -source activate testenv - -# Install requirements via pip in our conda environment -pip install -r requirements.txt - -# Install the following only if running tests -if [[ "$SKIP_TESTS" != "true" ]]; then - # SpaCy English models - python -m spacy download en - -# TODO: Add nltk data back once moses tokenizer is back online. -# https://github.com/alvations/sacremoses/issues/61 -# # NLTK data needed for Moses tokenizer -# python -m nltk.downloader perluniprops nonbreaking_prefixes -# - # PyTorch - conda install --yes pytorch -c pytorch-test - - # Installation - python setup.py install -fi diff --git a/build_tools/travis/test_script.sh b/build_tools/travis/test_script.sh deleted file mode 100644 index 200d8eb8bd..0000000000 --- a/build_tools/travis/test_script.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# This script is meant to be called by the "script" step defined in -# .travis.yml. See http://docs.travis-ci.com/ for more details. -# The behavior of the script is controlled by environment variabled defined -# in the .travis.yml in the top level folder of the project. - -set -e - -python --version - -run_tests() { - if [[ "$RUN_SLOW" == "true" ]]; then - TEST_CMD="py.test --runslow -s -v --cov=torchtext --durations=20" - else - TEST_CMD="py.test -v --cov=torchtext --durations=20" - fi - $TEST_CMD -} - -if [[ "$RUN_FLAKE8" == "true" ]]; then - flake8 -fi - -if [[ "$SKIP_TESTS" != "true" ]]; then - run_tests -fi diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.flake8 b/tox.ini similarity index 51% rename from .flake8 rename to tox.ini index 022e85ee84..031c25c69a 100644 --- a/.flake8 +++ b/tox.ini @@ -1,4 +1,4 @@ [flake8] -ignore = E402,E722,W503,W504 +ignore = E402,E722,W503,W504,F821,B006,B007,B008 max-line-length = 120 exclude = docs/source From ab3c93b3f17e3dcf33c071c3f644fea24bb0cb56 Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Thu, 30 Apr 2020 17:20:26 -0700 Subject: [PATCH 05/68] 20200429 pytorch/text import Summary: [20:45:34: cpuhrsch@devvm3140 pytorch]$ ./fb_build/import_text.sh Reviewed By: pbelevich Differential Revision: D21320577 fbshipit-source-id: ac2148b9f0d58e5538443c879845bfb4f6ca7202 --- .python3 | 0 README.rst | 4 +- docs/source/experimental_datasets.rst | 77 ++- examples/vocab/vocab.py | 0 requirements.txt | 3 - setup.py | 11 +- test/data/test_batch.py | 1 - test/data/test_builtin_datasets.py | 15 +- test/data/test_dataset.py | 4 +- test/data/test_field.py | 1 - test/data/test_functional.py | 16 +- test/data/test_pipeline.py | 10 +- test/data/test_subword.py | 4 - test/data/test_utils.py | 5 +- test/test_vocab.py | 7 +- torchtext/data/example.py | 3 +- torchtext/data/field.py | 13 +- torchtext/data/iterator.py | 2 - torchtext/data/pipeline.py | 3 +- torchtext/data/utils.py | 3 +- torchtext/datasets/text_classification.py | 172 +++--- torchtext/experimental/datasets/__init__.py | 14 +- .../experimental/datasets/raw/__init__.py | 13 + .../datasets/raw/text_classification.py | 261 ++++++++ .../datasets/text_classification.py | 570 +++++++++++++++--- torchtext/utils.py | 12 +- torchtext/vocab.py | 16 +- tox.ini | 4 - 28 files changed, 1004 insertions(+), 240 deletions(-) create mode 100644 .python3 mode change 100644 => 100755 examples/vocab/vocab.py create mode 100644 torchtext/experimental/datasets/raw/__init__.py create mode 100644 torchtext/experimental/datasets/raw/text_classification.py delete mode 100644 tox.ini diff --git a/.python3 b/.python3 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/README.rst b/README.rst index 9c2a066823..a79db166c0 100644 --- a/README.rst +++ b/README.rst @@ -15,14 +15,14 @@ This repository consists of: * `torchtext.data <#data>`_: Generic data loaders, abstractions, and iterators for text (including vocabulary and word vectors) * `torchtext.datasets <#datasets>`_: Pre-built loaders for common NLP datasets -Note: we are currently re-designing the torchtext library to make it more compatible with pytorch (e.g. ``torch.utils.data``). Several datasets have been written with the new abstractions in `torchtext.experimental `_ folder. We also created an issue to discuss the new abstraction, and users are welcome to leave feedback `here `_. +Note: we are currently re-designing the torchtext library to make it more compatible with pytorch (e.g. ``torch.utils.data``). Several datasets have been written with the new abstractions in `torchtext.experimental `_ folder. We also created an issue to discuss the new abstraction, and users are welcome to leave feedback `link `_. Installation ============ -Make sure you have Python 2.7 or 3.5+ and PyTorch 0.4.0 or newer. You can then install torchtext using pip:: +Make sure you have Python 3.5+ and PyTorch 0.4.0 or newer. You can then install torchtext using pip:: pip install torchtext diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index f37bdae0d8..d9d59539d0 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -35,7 +35,82 @@ IMDb .. autoclass:: IMDB :members: __init__ - + + +Text Classification +^^^^^^^^^^^^^^^^^^^ + +TextClassificationDataset +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: TextClassificationDataset + :members: __init__ + +AG_NEWS +~~~~~~ + +AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: AG_NEWS + :members: __init__ + +SogouNews +~~~~~~~~ + +SogouNews dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: SogouNews + :members: __init__ + +DBpedia +~~~~~~ + +DBpedia dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: DBpedia + :members: __init__ + +YelpReviewPolarity +~~~~~~~~~~~~~~~~~ + +YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: YelpReviewPolarity + :members: __init__ + +YelpReviewFull +~~~~~~~~~~~~~ + +YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: YelpReviewFull + :members: __init__ + +YahooAnswers +~~~~~~~~~~~ + +YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: YahooAnswers + :members: __init__ + +AmazonReviewPolarity +~~~~~~~~~~~~~~~~~~~ + +AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: AmazonReviewPolarity + :members: __init__ + +AmazonReviewFull +~~~~~~~~~~~~~~~ + +AmazonReviewFull dataset is subclass of ``TextClassificationDataset`` class. + +.. autoclass:: AmazonReviewFull + :members: __init__ + + Language Modeling ^^^^^^^^^^^^^^^^^ diff --git a/examples/vocab/vocab.py b/examples/vocab/vocab.py old mode 100644 new mode 100755 diff --git a/requirements.txt b/requirements.txt index 286e4c7cbf..cc0a18140f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,9 +4,6 @@ tqdm # Downloading data and other files requests -# Legacy -six - # Optional NLP tools nltk spacy diff --git a/setup.py b/setup.py index bd56651e0f..0c0cff5b03 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,16 @@ def find_version(*file_paths): license='BSD', install_requires=[ - 'tqdm', 'requests', 'torch', 'numpy', 'six', 'sentencepiece' + 'tqdm', 'requests', 'torch', 'numpy', 'sentencepiece' + ], + python_requires='>=3.5', + classifiers=[ + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3 :: Only', ], # Package info diff --git a/test/data/test_batch.py b/test/data/test_batch.py index 57f3bad85a..76017784e9 100644 --- a/test/data/test_batch.py +++ b/test/data/test_batch.py @@ -1,4 +1,3 @@ -from __future__ import unicode_literals import torch import torchtext.data as data diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 6507c9eb03..b2723949b2 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -2,7 +2,8 @@ import shutil import torchtext.data as data from torchtext.datasets import AG_NEWS - +import torch +from torch.testing import assert_allclose from ..common.test_markers import slow from ..common.torchtext_test_case import TorchtextTestCase @@ -98,6 +99,10 @@ def test_text_classification(self): ag_news_train, ag_news_test = AG_NEWS(root=datadir, ngrams=3) self.assertEqual(len(ag_news_train), 120000) self.assertEqual(len(ag_news_test), 7600) + assert_allclose(ag_news_train[-1][1][:10], + torch.tensor([3525, 319, 4053, 34, 5407, 3607, 70, 6798, 10599, 4053]).long()) + assert_allclose(ag_news_test[-1][1][:10], + torch.tensor([2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]).long()) # Delete the dataset after we're done to save disk space on CI datafile = os.path.join(self.project_root, ".data", "ag_news_csv") @@ -113,6 +118,14 @@ def test_imdb(self): train_dataset, test_dataset = IMDB() self.assertEqual(len(train_dataset), 25000) self.assertEqual(len(test_dataset), 25000) + assert_allclose(train_dataset[0][1][:10], + torch.tensor([13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]).long()) + assert_allclose(train_dataset[-1][1][:10], + torch.tensor([2, 71, 4555, 194, 3328, 15144, 42, 227, 148, 8]).long()) + assert_allclose(test_dataset[0][1][:10], + torch.tensor([13, 125, 1051, 5, 246, 1652, 8, 277, 66, 20]).long()) + assert_allclose(test_dataset[-1][1][:10], + torch.tensor([13, 1035, 14, 21, 28, 2, 1051, 1275, 1008, 3]).long()) # Test API with a vocab input object old_vocab = train_dataset.get_vocab() diff --git a/test/data/test_dataset.py b/test/data/test_dataset.py index e26c7ee664..6b3e974f75 100644 --- a/test/data/test_dataset.py +++ b/test/data/test_dataset.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals import torchtext.data as data import tempfile -import six import pytest @@ -246,7 +244,7 @@ def test_csv_dataset_quotechar(self): with tempfile.NamedTemporaryFile(dir=self.test_dir) as f: for example in example_data: - f.write(six.b("{}\n".format(",".join(example)))) + f.write("{}\n".format(",".join(example)).encode("latin-1")) TEXT = data.Field(lower=True, tokenize=lambda x: x.split()) fields = { diff --git a/test/data/test_field.py b/test/data/test_field.py index 1b734b6d9b..14fe043776 100644 --- a/test/data/test_field.py +++ b/test/data/test_field.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals from collections import Counter import os diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 98d7557017..6c5b86d71b 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -4,7 +4,6 @@ sentencepiece_numericalizer, sentencepiece_tokenizer, \ custom_replace, simple_space_split import os -import sys class TestFunctional(TorchtextTestCase): @@ -47,17 +46,10 @@ def test_sentencepiece_tokenizer(self): self.assertEqual(len(sp_model), 20000) spm_generator = sentencepiece_tokenizer(sp_model) - # Handle byte string in Python2 and Unicode string in Python3, respectively - if sys.version_info < (3, 0): - ref_results = ['\xe2\x96\x81Sent', 'ence', 'P', 'ie', 'ce', '\xe2\x96\x81is', - '\xe2\x96\x81an', '\xe2\x96\x81un', 'super', 'vis', 'ed', - '\xe2\x96\x81text', '\xe2\x96\x81to', 'ken', 'izer', - '\xe2\x96\x81and', '\xe2\x96\x81de', 'to', 'ken', 'izer'] - else: - ref_results = ['\u2581Sent', 'ence', 'P', 'ie', 'ce', '\u2581is', - '\u2581an', '\u2581un', 'super', 'vis', 'ed', '\u2581text', - '\u2581to', 'ken', 'izer', '\u2581and', - '\u2581de', 'to', 'ken', 'izer'] + ref_results = ['\u2581Sent', 'ence', 'P', 'ie', 'ce', '\u2581is', + '\u2581an', '\u2581un', 'super', 'vis', 'ed', '\u2581text', + '\u2581to', 'ken', 'izer', '\u2581and', + '\u2581de', 'to', 'ken', 'izer'] self.assertEqual(list(spm_generator([test_sample]))[0], ref_results) diff --git a/test/data/test_pipeline.py b/test/data/test_pipeline.py index 086c04b3b4..c1eda9a757 100644 --- a/test/data/test_pipeline.py +++ b/test/data/test_pipeline.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals -import six import torchtext.data as data from ..common.torchtext_test_case import TorchtextTestCase @@ -20,7 +18,7 @@ def test_pipeline(self): assert id_pipeline("ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T") == "ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T" assert id_pipeline(["1241", "Some String"]) == ["1241", "Some String"] - pipeline = data.Pipeline(six.text_type.lower) + pipeline = data.Pipeline(str.lower) assert pipeline("Test STring") == "test string" assert pipeline("ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T") == "ᑌᑎiᑕoᗪᕮ_tᕮ᙭t" assert pipeline(["1241", "Some String"]) == ["1241", "some string"] @@ -34,10 +32,10 @@ def test_composition(self): pipeline = data.Pipeline(TestPipeline.repeat_n) pipeline.add_before(id_pipeline) pipeline.add_after(id_pipeline) - pipeline.add_before(six.text_type.lower) - pipeline.add_after(six.text_type.capitalize) + pipeline.add_before(str.lower) + pipeline.add_after(str.capitalize) - other_pipeline = data.Pipeline(six.text_type.swapcase) + other_pipeline = data.Pipeline(str.swapcase) other_pipeline.add_before(pipeline) # Assert pipeline gives proper results after composition diff --git a/test/data/test_subword.py b/test/data/test_subword.py index fdbf0034d2..88e57c5044 100644 --- a/test/data/test_subword.py +++ b/test/data/test_subword.py @@ -1,14 +1,10 @@ import unittest -import pytest -import sys from torchtext import data from torchtext.datasets import TREC class TestSubword(unittest.TestCase): - @pytest.mark.skipif(sys.version_info < (3, 0), - reason="revtok currently breaks for python 2.7") def test_subword_trec(self): TEXT = data.SubwordField() LABEL = data.Field(sequential=False) diff --git a/test/data/test_utils.py b/test/data/test_utils.py index d84e6d5ad6..29716cbaaf 100644 --- a/test/data/test_utils.py +++ b/test/data/test_utils.py @@ -1,4 +1,3 @@ -import six import torchtext.data as data import pytest from ..common.torchtext_test_case import TorchtextTestCase @@ -16,7 +15,7 @@ def test_get_tokenizer_split(self): def test_get_tokenizer_spacy(self): # Test SpaCy option, and verify it properly handles punctuation. - assert data.get_tokenizer("spacy")(six.text_type(self.TEST_STR)) == [ + assert data.get_tokenizer("spacy")(str(self.TEST_STR)) == [ "A", "string", ",", "particularly", "one", "with", "slightly", "complex", "punctuation", "."] @@ -33,7 +32,7 @@ def test_get_tokenizer_moses(self): "complex", "punctuation", "."] # Nonbreaking prefixes should tokenize the final period. - assert moses_tokenizer(six.text_type("abc def.")) == ["abc", "def", "."] + assert moses_tokenizer("abc def.") == ["abc", "def", "."] def test_get_tokenizer_toktokt(self): # Test Toktok option. Test strings taken from NLTK doctests. diff --git a/test/test_vocab.py b/test/test_vocab.py index 051b547277..446954cdf6 100644 --- a/test/test_vocab.py +++ b/test/test_vocab.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals from collections import Counter import os import pickle @@ -101,7 +100,7 @@ def test_vocab_download_fasttext_vectors(self): # to test string aliases. for i in range(3): if i == 2: - vectors = str("fasttext.simple.300d") # must handle str on Py2 + vectors = "fasttext.simple.300d" else: vectors = FastText(language='simple') @@ -136,7 +135,7 @@ def test_vocab_download_fasttext_vectors(self): def test_vocab_extend(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) # Build a vocab and get vectors twice to test caching. - for i in range(2): + for _ in range(2): f = FastText(language='simple') v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], vectors=f) @@ -168,7 +167,7 @@ def test_vocab_extend(self): def test_vocab_download_custom_vectors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) # Build a vocab and get vectors twice to test caching. - for i in range(2): + for _ in range(2): v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], vectors=Vectors('wiki.simple.vec', url=FastText.url_base.format('simple'))) diff --git a/torchtext/data/example.py b/torchtext/data/example.py index 68aaf9e2be..d9f96aeda3 100644 --- a/torchtext/data/example.py +++ b/torchtext/data/example.py @@ -1,4 +1,3 @@ -import six import json from functools import reduce @@ -75,7 +74,7 @@ def fromlist(cls, data, fields): ex = cls() for (name, field), val in zip(fields, data): if field is not None: - if isinstance(val, six.string_types): + if isinstance(val, str): val = val.rstrip('\n') # Handle field tuples if isinstance(name, tuple): diff --git a/torchtext/data/field.py b/torchtext/data/field.py index 090821b315..189331c1be 100644 --- a/torchtext/data/field.py +++ b/torchtext/data/field.py @@ -1,7 +1,6 @@ # coding: utf8 from collections import Counter, OrderedDict from itertools import chain -import six import torch from tqdm import tqdm @@ -204,17 +203,13 @@ def __eq__(self, other): def preprocess(self, x): """Load a single example using this field, tokenizing if necessary. - If the input is a Python 2 `str`, it will be converted to Unicode - first. If `sequential=True`, it will be tokenized. Then the input + If `sequential=True`, the input will be tokenized. Then the input will be optionally lowercased and passed to the user-provided `preprocessing` Pipeline.""" - if (six.PY2 and isinstance(x, six.string_types) - and not isinstance(x, six.text_type)): - x = Pipeline(lambda s: six.text_type(s, encoding='utf-8'))(x) - if self.sequential and isinstance(x, six.text_type): + if self.sequential and isinstance(x, str): x = self.tokenize(x.rstrip('\n')) if self.lower: - x = Pipeline(six.text_type.lower)(x) + x = Pipeline(str.lower)(x) if self.sequential and self.use_vocab and self.stop_words is not None: x = [w for w in x if w not in self.stop_words] if self.preprocessing is not None: @@ -351,7 +346,7 @@ def numericalize(self, arr, device=None): # the data is sequential, since it's unclear how to coerce padding tokens # to a numeric type. if not self.sequential: - arr = [numericalization_func(x) if isinstance(x, six.string_types) + arr = [numericalization_func(x) if isinstance(x, str) else x for x in arr] if self.postprocessing is not None: arr = self.postprocessing(arr, None) diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py index adae0c3171..9546cb9dac 100644 --- a/torchtext/data/iterator.py +++ b/torchtext/data/iterator.py @@ -1,5 +1,3 @@ -from __future__ import division - import math import random diff --git a/torchtext/data/pipeline.py b/torchtext/data/pipeline.py index 632736429d..f576fdc720 100644 --- a/torchtext/data/pipeline.py +++ b/torchtext/data/pipeline.py @@ -1,8 +1,7 @@ class Pipeline(object): """Defines a pipeline for transforming sequence data. - The input is assumed to be utf-8 encoded `str` (Python 3) or - `unicode` (Python 2). + The input is assumed to be utf-8 encoded `str`. Attributes: convert_token: The function to apply to input sequence data. diff --git a/torchtext/data/utils.py b/torchtext/data/utils.py index 2e310c9785..eb056679e9 100644 --- a/torchtext/data/utils.py +++ b/torchtext/data/utils.py @@ -6,7 +6,8 @@ from functools import partial -def _split_tokenizer(x): +def _split_tokenizer(x): # noqa: F821 + # type: (str) -> List[str] return x.split() diff --git a/torchtext/datasets/text_classification.py b/torchtext/datasets/text_classification.py index 1b813de238..be7400f91b 100644 --- a/torchtext/datasets/text_classification.py +++ b/torchtext/datasets/text_classification.py @@ -145,10 +145,10 @@ def _setup_datasets(dataset_name, root='.data', ngrams=1, vocab=None, include_un def AG_NEWS(*args, **kwargs): """ Defines AG_NEWS datasets. The labels includes: - - 1 : World - - 2 : Sports - - 3 : Business - - 4 : Sci/Tech + - 0 : World + - 1 : Sports + - 2 : Business + - 3 : Sci/Tech Create supervised learning dataset: AG_NEWS @@ -173,11 +173,11 @@ def AG_NEWS(*args, **kwargs): def SogouNews(*args, **kwargs): """ Defines SogouNews datasets. The labels includes: - - 1 : Sports - - 2 : Finance - - 3 : Entertainment - - 4 : Automobile - - 5 : Technology + - 0 : Sports + - 1 : Finance + - 2 : Entertainment + - 3 : Automobile + - 4 : Technology Create supervised learning dataset: SogouNews @@ -202,20 +202,20 @@ def SogouNews(*args, **kwargs): def DBpedia(*args, **kwargs): """ Defines DBpedia datasets. The labels includes: - - 1 : Company - - 2 : EducationalInstitution - - 3 : Artist - - 4 : Athlete - - 5 : OfficeHolder - - 6 : MeanOfTransportation - - 7 : Building - - 8 : NaturalPlace - - 9 : Village - - 10 : Animal - - 11 : Plant - - 12 : Album - - 13 : Film - - 14 : WrittenWork + - 0 : Company + - 1 : EducationalInstitution + - 2 : Artist + - 3 : Athlete + - 4 : OfficeHolder + - 5 : MeanOfTransportation + - 6 : Building + - 7 : NaturalPlace + - 8 : Village + - 9 : Animal + - 10 : Plant + - 11 : Album + - 12 : Film + - 13 : WrittenWork Create supervised learning dataset: DBpedia @@ -240,8 +240,8 @@ def DBpedia(*args, **kwargs): def YelpReviewPolarity(*args, **kwargs): """ Defines YelpReviewPolarity datasets. The labels includes: - - 1 : Negative polarity. - - 2 : Positive polarity. + - 0 : Negative polarity. + - 1 : Positive polarity. Create supervised learning dataset: YelpReviewPolarity @@ -266,7 +266,7 @@ def YelpReviewPolarity(*args, **kwargs): def YelpReviewFull(*args, **kwargs): """ Defines YelpReviewFull datasets. The labels includes: - 1 - 5 : rating classes (5 is highly recommended). + 0 - 4 : rating classes (4 is highly recommended). Create supervised learning dataset: YelpReviewFull @@ -291,16 +291,16 @@ def YelpReviewFull(*args, **kwargs): def YahooAnswers(*args, **kwargs): """ Defines YahooAnswers datasets. The labels includes: - - 1 : Society & Culture - - 2 : Science & Mathematics - - 3 : Health - - 4 : Education & Reference - - 5 : Computers & Internet - - 6 : Sports - - 7 : Business & Finance - - 8 : Entertainment & Music - - 9 : Family & Relationships - - 10 : Politics & Government + - 0 : Society & Culture + - 1 : Science & Mathematics + - 2 : Health + - 3 : Education & Reference + - 4 : Computers & Internet + - 5 : Sports + - 6 : Business & Finance + - 7 : Entertainment & Music + - 8 : Family & Relationships + - 9 : Politics & Government Create supervised learning dataset: YahooAnswers @@ -325,8 +325,8 @@ def YahooAnswers(*args, **kwargs): def AmazonReviewPolarity(*args, **kwargs): """ Defines AmazonReviewPolarity datasets. The labels includes: - - 1 : Negative polarity - - 2 : Positive polarity + - 0 : Negative polarity + - 1 : Positive polarity Create supervised learning dataset: AmazonReviewPolarity @@ -351,7 +351,7 @@ def AmazonReviewPolarity(*args, **kwargs): def AmazonReviewFull(*args, **kwargs): """ Defines AmazonReviewFull datasets. The labels includes: - 1 - 5 : rating classes (5 is highly recommended) + 0 - 4 : rating classes (4 is highly recommended) Create supervised learning dataset: AmazonReviewFull @@ -386,51 +386,51 @@ def AmazonReviewFull(*args, **kwargs): LABELS = { - 'AG_NEWS': {1: 'World', - 2: 'Sports', - 3: 'Business', - 4: 'Sci/Tech'}, - 'SogouNews': {1: 'Sports', - 2: 'Finance', - 3: 'Entertainment', - 4: 'Automobile', - 5: 'Technology'}, - 'DBpedia': {1: 'Company', - 2: 'EducationalInstitution', - 3: 'Artist', - 4: 'Athlete', - 5: 'OfficeHolder', - 6: 'MeanOfTransportation', - 7: 'Building', - 8: 'NaturalPlace', - 9: 'Village', - 10: 'Animal', - 11: 'Plant', - 12: 'Album', - 13: 'Film', - 14: 'WrittenWork'}, - 'YelpReviewPolarity': {1: 'Negative polarity', - 2: 'Positive polarity'}, - 'YelpReviewFull': {1: 'score 1', - 2: 'score 2', - 3: 'score 3', - 4: 'score 4', - 5: 'score 5'}, - 'YahooAnswers': {1: 'Society & Culture', - 2: 'Science & Mathematics', - 3: 'Health', - 4: 'Education & Reference', - 5: 'Computers & Internet', - 6: 'Sports', - 7: 'Business & Finance', - 8: 'Entertainment & Music', - 9: 'Family & Relationships', - 10: 'Politics & Government'}, - 'AmazonReviewPolarity': {1: 'Negative polarity', - 2: 'Positive polarity'}, - 'AmazonReviewFull': {1: 'score 1', - 2: 'score 2', - 3: 'score 3', - 4: 'score 4', - 5: 'score 5'} + 'AG_NEWS': {0: 'World', + 1: 'Sports', + 2: 'Business', + 3: 'Sci/Tech'}, + 'SogouNews': {0: 'Sports', + 1: 'Finance', + 2: 'Entertainment', + 3: 'Automobile', + 4: 'Technology'}, + 'DBpedia': {0: 'Company', + 1: 'EducationalInstitution', + 2: 'Artist', + 3: 'Athlete', + 4: 'OfficeHolder', + 5: 'MeanOfTransportation', + 6: 'Building', + 7: 'NaturalPlace', + 8: 'Village', + 9: 'Animal', + 10: 'Plant', + 11: 'Album', + 12: 'Film', + 13: 'WrittenWork'}, + 'YelpReviewPolarity': {0: 'Negative polarity', + 1: 'Positive polarity'}, + 'YelpReviewFull': {0: 'score 1', + 1: 'score 2', + 2: 'score 3', + 3: 'score 4', + 4: 'score 5'}, + 'YahooAnswers': {0: 'Society & Culture', + 1: 'Science & Mathematics', + 2: 'Health', + 3: 'Education & Reference', + 4: 'Computers & Internet', + 5: 'Sports', + 6: 'Business & Finance', + 7: 'Entertainment & Music', + 8: 'Family & Relationships', + 9: 'Politics & Government'}, + 'AmazonReviewPolarity': {0: 'Negative polarity', + 1: 'Positive polarity'}, + 'AmazonReviewFull': {0: 'score 1', + 1: 'score 2', + 2: 'score 3', + 3: 'score 4', + 4: 'score 5'} } diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index e53f668a98..ac2faa423b 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -1,8 +1,18 @@ from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank # NOQA -from .text_classification import IMDB +from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ + YelpReviewFull, YahooAnswers, \ + AmazonReviewPolarity, AmazonReviewFull, IMDB __all__ = ['LanguageModelingDataset', 'WikiText2', 'WikiText103', 'PennTreebank', - 'IMDB'] + 'IMDB', + 'AG_NEWS', + 'SogouNews', + 'DBpedia', + 'YelpReviewPolarity', + 'YelpReviewFull', + 'YahooAnswers', + 'AmazonReviewPolarity', + 'AmazonReviewFull'] diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py new file mode 100644 index 0000000000..61accbe2a1 --- /dev/null +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -0,0 +1,13 @@ +from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ + YelpReviewFull, YahooAnswers, \ + AmazonReviewPolarity, AmazonReviewFull, IMDB + +__all__ = ['IMDB', + 'AG_NEWS', + 'SogouNews', + 'DBpedia', + 'YelpReviewPolarity', + 'YelpReviewFull', + 'YahooAnswers', + 'AmazonReviewPolarity', + 'AmazonReviewFull'] diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py new file mode 100644 index 0000000000..402c853a68 --- /dev/null +++ b/torchtext/experimental/datasets/raw/text_classification.py @@ -0,0 +1,261 @@ +import torch +import io +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +import sys + +URLS = { + 'AG_NEWS': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUDNpeUdjb0wxRms', + 'SogouNews': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE', + 'DBpedia': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k', + 'YelpReviewPolarity': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg', + 'YelpReviewFull': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0', + 'YahooAnswers': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU', + 'AmazonReviewPolarity': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM', + 'AmazonReviewFull': + 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA', + 'IMDB': + 'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz' +} + + +def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + + +class RawTextIterableDataset(torch.utils.data.IterableDataset): + """Defines an abstraction for raw text iterable datasets. + """ + + def __init__(self, iterator): + """Initiate text-classification dataset. + """ + super(RawTextIterableDataset, self).__init__() + self._iterator = iterator + self.has_setup = False + self.start = 0 + self.num_lines = None + + def setup_iter(self, start=0, num_lines=None): + self.start = start + self.num_lines = num_lines + self.has_setup = True + + def __iter__(self): + if not self.has_setup: + self.setup_iter() + + for i, item in enumerate(self._iterator): + if i >= self.start: + yield item + if self.num_lines is not None and i == (self.start + self.num_lines): + break + + def get_iterator(self): + return self._iterator + + +def _setup_datasets(dataset_name, root='.data'): + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files = extract_archive(dataset_tar) + + for fname in extracted_files: + if fname.endswith('train.csv'): + train_csv_path = fname + if fname.endswith('test.csv'): + test_csv_path = fname + + train_iter = _create_data_from_csv(train_csv_path) + test_iter = _create_data_from_csv(test_csv_path) + return (RawTextIterableDataset(train_iter), + RawTextIterableDataset(test_iter)) + + +def AG_NEWS(*args, **kwargs): + """ Defines AG_NEWS datasets. + + Create supervised learning dataset: AG_NEWS + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.AG_NEWS() + """ + + return _setup_datasets(*(("AG_NEWS",) + args), **kwargs) + + +def SogouNews(*args, **kwargs): + """ Defines SogouNews datasets. + + Create supervised learning dataset: SogouNews + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.SogouNews() + """ + + return _setup_datasets(*(("SogouNews",) + args), **kwargs) + + +def DBpedia(*args, **kwargs): + """ Defines DBpedia datasets. + + Create supervised learning dataset: DBpedia + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.DBpedia() + """ + + return _setup_datasets(*(("DBpedia",) + args), **kwargs) + + +def YelpReviewPolarity(*args, **kwargs): + """ Defines YelpReviewPolarity datasets. + + Create supervised learning dataset: YelpReviewPolarity + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.YelpReviewPolarity() + """ + + return _setup_datasets(*(("YelpReviewPolarity",) + args), **kwargs) + + +def YelpReviewFull(*args, **kwargs): + """ Defines YelpReviewFull datasets. + + Create supervised learning dataset: YelpReviewFull + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.YelpReviewFull() + """ + + return _setup_datasets(*(("YelpReviewFull",) + args), **kwargs) + + +def YahooAnswers(*args, **kwargs): + """ Defines YahooAnswers datasets. + + Create supervised learning dataset: YahooAnswers + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.YahooAnswers() + """ + + return _setup_datasets(*(("YahooAnswers",) + args), **kwargs) + + +def AmazonReviewPolarity(*args, **kwargs): + """ Defines AmazonReviewPolarity datasets. + + Create supervised learning dataset: AmazonReviewPolarity + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewPolarity() + """ + + return _setup_datasets(*(("AmazonReviewPolarity",) + args), **kwargs) + + +def AmazonReviewFull(*args, **kwargs): + """ Defines AmazonReviewFull datasets. + + Create supervised learning dataset: AmazonReviewFull + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewFull() + """ + + return _setup_datasets(*(("AmazonReviewFull",) + args), **kwargs) + + +def generate_imdb_data(key, extracted_files): + for fname in extracted_files: + if 'urls' in fname: + continue + elif key in fname and ('pos' in fname or 'neg' in fname): + with io.open(fname, encoding="utf8") as f: + label = 1 if 'pos' in fname else 0 + yield label, f.read() + + +def IMDB(root='.data'): + """ Defines IMDB datasets. + + Create supervised learning dataset: IMDB + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> train, test = torchtext.experimental.datasets.raw.IMDB() + """ + + dataset_tar = download_from_url(URLS['IMDB'], root=root) + extracted_files = extract_archive(dataset_tar) + train_iter = generate_imdb_data('train', extracted_files) + test_iter = generate_imdb_data('test', extracted_files) + return (RawTextIterableDataset(train_iter), + RawTextIterableDataset(test_iter)) + + +DATASETS = { + 'AG_NEWS': AG_NEWS, + 'SogouNews': SogouNews, + 'DBpedia': DBpedia, + 'YelpReviewPolarity': YelpReviewPolarity, + 'YelpReviewFull': YelpReviewFull, + 'YahooAnswers': YahooAnswers, + 'AmazonReviewPolarity': AmazonReviewPolarity, + 'AmazonReviewFull': AmazonReviewFull, + 'IMDB': IMDB +} diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index eac97e3d6e..df879ea557 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -1,93 +1,469 @@ -import logging import torch -import io -from torchtext.utils import download_from_url, extract_archive -from torchtext.data.utils import ngrams_iterator from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.vocab import Vocab -from torchtext.datasets import TextClassificationDataset +from torchtext.experimental.datasets import raw -URLS = { - 'IMDB': - 'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz' -} +def vocab_func(vocab): + def _forward(tok_iter): + return [vocab[tok] for tok in tok_iter] + return _forward -def _create_data_from_iterator(vocab, iterator, removed_tokens): - for cls, tokens in iterator: - yield cls, iter(map(lambda x: vocab[x], - filter(lambda x: x not in removed_tokens, tokens))) +def totensor(dtype): + def _forward(ids_list): + return torch.tensor(ids_list).to(dtype) + return _forward -def _imdb_iterator(key, extracted_files, tokenizer, ngrams, yield_cls=False): - for fname in extracted_files: - if 'urls' in fname: - continue - elif key in fname and ('pos' in fname or 'neg' in fname): - with io.open(fname, encoding="utf8") as f: - label = 1 if 'pos' in fname else 0 - if yield_cls: - yield label, ngrams_iterator(tokenizer(f.read()), ngrams) - else: - yield ngrams_iterator(tokenizer(f.read()), ngrams) +def ngrams_func(ngrams): + def _forward(token_list): + _token_list = [] + for _i in range(ngrams + 1): + _token_list += zip(*[token_list[i:] for i in range(_i)]) + return [' '.join(x) for x in _token_list] + return _forward -def _generate_data_iterators(dataset_name, root, ngrams, tokenizer, data_select): - if not tokenizer: - tokenizer = get_tokenizer("basic_english") - if not set(data_select).issubset(set(('train', 'test'))): - raise TypeError('Given data selection {} is not supported!'.format(data_select)) +def build_vocab(data, transforms): + tok_list = [] + for _, txt in data: + tok_list.append(transforms(txt)) + return build_vocab_from_iterator(tok_list) + + +def squential_transforms(*transforms): + def _forward(txt_input): + for transform in transforms: + txt_input = transform(txt_input) + return txt_input + return _forward + + +class TextClassificationDataset(torch.utils.data.Dataset): + """Defines an abstract text classification datasets. + Currently, we only support the following datasets: + - AG_NEWS + - SogouNews + - DBpedia + - YelpReviewPolarity + - YelpReviewFull + - YahooAnswers + - AmazonReviewPolarity + - AmazonReviewFull + """ + + def __init__(self, data, vocab, transforms): + """Initiate text-classification dataset. - dataset_tar = download_from_url(URLS[dataset_name], root=root) - extracted_files = extract_archive(dataset_tar) + Arguments: + data: a list of label and text tring tuple. label is an integer. + [(label1, text1), (label2, text2), (label2, text3)] + vocab: Vocabulary object used for dataset. + transforms: a tuple of label and text string transforms. + """ - iters_group = {} - if 'train' in data_select: - iters_group['vocab'] = _imdb_iterator('train', extracted_files, - tokenizer, ngrams) - for item in data_select: - iters_group[item] = _imdb_iterator(item, extracted_files, - tokenizer, ngrams, yield_cls=True) - return iters_group + super(TextClassificationDataset, self).__init__() + self.data = data + self.vocab = vocab + self.transforms = transforms # (label_transforms, tokens_transforms) + + def __getitem__(self, i): + label = self.data[i][0] + txt = self.data[i][1] + return (self.transforms[0](label), self.transforms[1](txt)) + + def __len__(self): + return len(self.data) + + def get_labels(self): + labels = [] + for item in self.data: + label = item[0] + labels.apppend(self.transforms[0](label)) + return set(labels) + + def get_vocab(self): + return self.vocab def _setup_datasets(dataset_name, root='.data', ngrams=1, vocab=None, - removed_tokens=[], tokenizer=None, - data_select=('train', 'test')): + tokenizer=None, data_select=('train', 'test')): + text_transform = [] + if tokenizer is None: + tokenizer = get_tokenizer('basic_english') + text_transform = squential_transforms(tokenizer, ngrams_func(ngrams)) if isinstance(data_select, str): data_select = [data_select] - - iters_group = _generate_data_iterators(dataset_name, root, ngrams, - tokenizer, data_select) + if not set(data_select).issubset(set(('train', 'test'))): + raise TypeError('Given data selection {} is not supported!'.format(data_select)) + train, test = DATASETS[dataset_name](root=root) + # Cache raw text iterable dataset + raw_data = {'train': [(label, txt) for (label, txt) in train], + 'test': [(label, txt) for (label, txt) in test]} if vocab is None: - if 'vocab' not in iters_group.keys(): + if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - logging.info('Building Vocab based on train data') - vocab = build_vocab_from_iterator(iters_group['vocab']) - else: - if not isinstance(vocab, Vocab): - raise TypeError("Passed vocabulary is not of type Vocab") - logging.info('Vocab has {} entries'.format(len(vocab))) - - data = {} - for item in data_select: - data[item] = {} - data[item]['data'] = [] - data[item]['labels'] = [] - logging.info('Creating {} data'.format(item)) - data_iter = _create_data_from_iterator(vocab, iters_group[item], removed_tokens) - for cls, tokens in data_iter: - data[item]['data'].append((torch.tensor(cls), - torch.tensor([token_id for token_id in tokens]))) - data[item]['labels'].append(cls) - data[item]['labels'] = set(data[item]['labels']) - - return tuple(TextClassificationDataset(vocab, data[item]['data'], - data[item]['labels']) for item in data_select) + vocab = build_vocab(raw_data['train'], text_transform) + text_transform = squential_transforms(text_transform, vocab_func(vocab), + totensor(dtype=torch.long)) + label_transform = squential_transforms(totensor(dtype=torch.long)) + return tuple(TextClassificationDataset(raw_data[item], vocab, + (label_transform, text_transform)) + for item in data_select) + + +def AG_NEWS(*args, **kwargs): + """ Defines AG_NEWS datasets. + The labels includes: + - 1 : World + - 2 : Sports + - 3 : Business + - 4 : Sci/Tech + + Create text classification dataset: AG_NEWS + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import AG_NEWS + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = AG_NEWS(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = AG_NEWS(tokenizer=tokenizer) + >>> train, = AG_NEWS(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(('AG_NEWS',) + args), **kwargs) + + +def SogouNews(*args, **kwargs): + """ Defines SogouNews datasets. + The labels includes: + - 1 : Sports + - 2 : Finance + - 3 : Entertainment + - 4 : Automobile + - 5 : Technology + + Create text classification dataset: SogouNews + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import SogouNews + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = SogouNews(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = SogouNews(tokenizer=tokenizer) + >>> train, = SogouNews(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("SogouNews",) + args), **kwargs) + + +def DBpedia(*args, **kwargs): + """ Defines DBpedia datasets. + The labels includes: + - 1 : Company + - 2 : EducationalInstitution + - 3 : Artist + - 4 : Athlete + - 5 : OfficeHolder + - 6 : MeanOfTransportation + - 7 : Building + - 8 : NaturalPlace + - 9 : Village + - 10 : Animal + - 11 : Plant + - 12 : Album + - 13 : Film + - 14 : WrittenWork + + Create text classification dataset: DBpedia + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import DBpedia + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = DBpedia(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = DBpedia(tokenizer=tokenizer) + >>> train, = DBpedia(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("DBpedia",) + args), **kwargs) + + +def YelpReviewPolarity(*args, **kwargs): + """ Defines YelpReviewPolarity datasets. + The labels includes: + - 1 : Negative polarity. + - 2 : Positive polarity. + + Create text classification dataset: YelpReviewPolarity + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import YelpReviewPolarity + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = YelpReviewPolarity(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = YelpReviewPolarity(tokenizer=tokenizer) + >>> train, = YelpReviewPolarity(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("YelpReviewPolarity",) + args), **kwargs) + + +def YelpReviewFull(*args, **kwargs): + """ Defines YelpReviewFull datasets. + The labels includes: + 1 - 5 : rating classes (5 is highly recommended). + + Create text classification dataset: YelpReviewFull + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import YelpReviewFull + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = YelpReviewFull(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = YelpReviewFull(tokenizer=tokenizer) + >>> train, = YelpReviewFull(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("YelpReviewFull",) + args), **kwargs) + + +def YahooAnswers(*args, **kwargs): + """ Defines YahooAnswers datasets. + The labels includes: + - 1 : Society & Culture + - 2 : Science & Mathematics + - 3 : Health + - 4 : Education & Reference + - 5 : Computers & Internet + - 6 : Sports + - 7 : Business & Finance + - 8 : Entertainment & Music + - 9 : Family & Relationships + - 10 : Politics & Government + + Create text classification dataset: YahooAnswers + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import YahooAnswers + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = YahooAnswers(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = YahooAnswers(tokenizer=tokenizer) + >>> train, = YahooAnswers(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("YahooAnswers",) + args), **kwargs) + + +def AmazonReviewPolarity(*args, **kwargs): + """ Defines AmazonReviewPolarity datasets. + The labels includes: + - 1 : Negative polarity + - 2 : Positive polarity + + Create text classification dataset: AmazonReviewPolarity + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import AmazonReviewPolarity + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = AmazonReviewPolarity(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = AmazonReviewPolarity(tokenizer=tokenizer) + >>> train, = AmazonReviewPolarity(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("AmazonReviewPolarity",) + args), **kwargs) + + +def AmazonReviewFull(*args, **kwargs): + """ Defines AmazonReviewFull datasets. + The labels includes: + 1 - 5 : rating classes (5 is highly recommended) + + Create text classification dataset: AmazonReviewFull + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + ngrams: a contiguous sequence of n items from s string text. + Default: 1 + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import AmazonReviewFull + >>> from torchtext.data.utils import get_tokenizer + >>> train, test = AmazonReviewFull(ngrams=3) + >>> tokenizer = get_tokenizer("spacy") + >>> train, test = AmazonReviewFull(tokenizer=tokenizer) + >>> train, = AmazonReviewFull(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("AmazonReviewFull",) + args), **kwargs) def IMDB(*args, **kwargs): @@ -126,17 +502,73 @@ def IMDB(*args, **kwargs): >>> tokenizer = get_tokenizer("spacy") >>> train, test = IMDB(tokenizer=tokenizer) >>> train, = IMDB(tokenizer=tokenizer, data_select='train') + """ return _setup_datasets(*(("IMDB",) + args), **kwargs) DATASETS = { - 'IMDB': IMDB + 'AG_NEWS': raw.AG_NEWS, + 'SogouNews': raw.SogouNews, + 'DBpedia': raw.DBpedia, + 'YelpReviewPolarity': raw.YelpReviewPolarity, + 'YelpReviewFull': raw.YelpReviewFull, + 'YahooAnswers': raw.YahooAnswers, + 'AmazonReviewPolarity': raw.AmazonReviewPolarity, + 'AmazonReviewFull': raw.AmazonReviewFull, + 'IMDB': raw.IMDB } LABELS = { + 'AG_NEWS': {1: 'World', + 2: 'Sports', + 3: 'Business', + 4: 'Sci/Tech'}, + 'SogouNews': {1: 'Sports', + 2: 'Finance', + 3: 'Entertainment', + 4: 'Automobile', + 5: 'Technology'}, + 'DBpedia': {1: 'Company', + 2: 'EducationalInstitution', + 3: 'Artist', + 4: 'Athlete', + 5: 'OfficeHolder', + 6: 'MeanOfTransportation', + 7: 'Building', + 8: 'NaturalPlace', + 9: 'Village', + 10: 'Animal', + 11: 'Plant', + 12: 'Album', + 13: 'Film', + 14: 'WrittenWork'}, + 'YelpReviewPolarity': {1: 'Negative polarity', + 2: 'Positive polarity'}, + 'YelpReviewFull': {1: 'score 1', + 2: 'score 2', + 3: 'score 3', + 4: 'score 4', + 5: 'score 5'}, + 'YahooAnswers': {1: 'Society & Culture', + 2: 'Science & Mathematics', + 3: 'Health', + 4: 'Education & Reference', + 5: 'Computers & Internet', + 6: 'Sports', + 7: 'Business & Finance', + 8: 'Entertainment & Music', + 9: 'Family & Relationships', + 10: 'Politics & Government'}, + 'AmazonReviewPolarity': {1: 'Negative polarity', + 2: 'Positive polarity'}, + 'AmazonReviewFull': {1: 'score 1', + 2: 'score 2', + 3: 'score 3', + 4: 'score 4', + 5: 'score 5'}, 'IMDB': {0: 'Negative', 1: 'Positive'} } diff --git a/torchtext/utils.py b/torchtext/utils.py index b69756c3aa..45f242f84b 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -1,4 +1,3 @@ -import six import requests import csv from tqdm import tqdm @@ -133,15 +132,8 @@ def unicode_csv_reader(unicode_csv_data, **kwargs): maxInt = int(maxInt / 10) csv.field_size_limit(maxInt) - if six.PY2: - # csv.py doesn't do Unicode; encode temporarily as UTF-8: - csv_reader = csv.reader(utf_8_encoder(unicode_csv_data), **kwargs) - for row in csv_reader: - # decode UTF-8 back to Unicode, cell by cell: - yield [cell.decode('utf-8') for cell in row] - else: - for line in csv.reader(unicode_csv_data, **kwargs): - yield line + for line in csv.reader(unicode_csv_data, **kwargs): + yield line def utf_8_encoder(unicode_csv_data): diff --git a/torchtext/vocab.py b/torchtext/vocab.py index f5e5c6b9f2..61848d05ca 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -1,4 +1,3 @@ -from __future__ import unicode_literals from collections import defaultdict from functools import partial import logging @@ -6,8 +5,7 @@ import zipfile import gzip -import six -from six.moves.urllib.request import urlretrieve +from urllib.request import urlretrieve import torch from tqdm import tqdm import tarfile @@ -33,7 +31,7 @@ class Vocab(object): # TODO (@mttk): Populate classs with default values of special symbols UNK = '' - def __init__(self, counter, max_size=None, min_freq=1, specials=['', ''], + def __init__(self, counter, max_size=None, min_freq=1, specials=('', ''), vectors=None, unk_init=None, vectors_cache=None, specials_first=True): """Create a Vocab object from a collections.Counter. @@ -169,9 +167,7 @@ def load_vectors(self, vectors, **kwargs): if not isinstance(vectors, list): vectors = [vectors] for idx, vector in enumerate(vectors): - if six.PY2 and isinstance(vector, str): - vector = six.text_type(vector) - if isinstance(vector, six.string_types): + if isinstance(vector, str): # Convert the string pretrained vector identifier # to a Vectors object if vector not in pretrained_aliases: @@ -222,7 +218,7 @@ def set_vectors(self, stoi, vectors, dim, unk_init=torch.Tensor.zero_): class SubwordVocab(Vocab): - def __init__(self, counter, max_size=None, specials=[''], + def __init__(self, counter, max_size=None, specials=(''), vectors=None, unk_init=torch.Tensor.zero_): """Create a revtok subword vocabulary from a collections.Counter. @@ -406,7 +402,7 @@ def cache(self, name, cache, url=None, max_vectors=None): dim)) try: - if isinstance(word, six.binary_type): + if isinstance(word, bytes): word = word.decode('utf-8') except UnicodeDecodeError: logger.info("Skipping non-UTF8 token {}".format(repr(word))) @@ -507,8 +503,6 @@ def __getitem__(self, token): vector = torch.Tensor(1, self.dim).zero_() if token == "": return self.unk_init(vector) - # These literals need to be coerced to unicode for Python 2 compatibility - # when we try to join them with read ngrams from the files. chars = ['#BEGIN#'] + list(token) + ['#END#'] num_vectors = 0 for n in [2, 3, 4]: diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 031c25c69a..0000000000 --- a/tox.ini +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -ignore = E402,E722,W503,W504,F821,B006,B007,B008 -max-line-length = 120 -exclude = docs/source From efdf20db13b24b85fc1a9179ff3587f59e69b2f9 Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Thu, 30 Apr 2020 20:52:46 -0700 Subject: [PATCH 06/68] 20200430 torchtext import script to include additional meta files Summary: ./fb_build/import_text.sh Reviewed By: zhangguanheng66 Differential Revision: D21343124 fbshipit-source-id: c08ecad2cc6f439fa40130aeaf91383be9403fe8 --- .gitignore | 122 ++++++++++++++++++++++++++ build_tools/conda/torchtext/meta.yaml | 34 +++++++ build_tools/travis/after_success.sh | 13 +++ build_tools/travis/install.sh | 68 ++++++++++++++ build_tools/travis/test_script.sh | 26 ++++++ test/.gitignore | 0 6 files changed, 263 insertions(+) create mode 100644 .gitignore create mode 100644 build_tools/conda/torchtext/meta.yaml create mode 100644 build_tools/travis/after_success.sh create mode 100644 build_tools/travis/install.sh create mode 100644 build_tools/travis/test_script.sh create mode 100644 test/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..8e2279529b --- /dev/null +++ b/.gitignore @@ -0,0 +1,122 @@ +*.txt +*.zip +*~ +.vector_cache +.idea/ + +# Documentation +docs/build + +# Download folder +.data + +# Created by https://www.gitignore.io/api/python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule.* + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# End of https://www.gitignore.io/api/python + +# vim +*.swp +*.swo diff --git a/build_tools/conda/torchtext/meta.yaml b/build_tools/conda/torchtext/meta.yaml new file mode 100644 index 0000000000..6972e81095 --- /dev/null +++ b/build_tools/conda/torchtext/meta.yaml @@ -0,0 +1,34 @@ +package: + name: torchtext + version: 0.4.0 + +source: + url: https://github.com/pytorch/text/archive/0.4.0.zip + +requirements: + build: + - python + - setuptools + + run: + - python + - tqdm + - numpy >=1.11 + - pytorch >=1.2 + - requests + +build: + number: 1 + noarch: python + script: python setup.py install --single-version-externally-managed --record=record.txt + +test: + imports: + - torchtext + - torchtext.data + +about: + home: https://github.com/pytorch/text + license: BSD + license_file: LICENSE + summary: 'PyTorch Data loaders and abstractions for text and NLP' diff --git a/build_tools/travis/after_success.sh b/build_tools/travis/after_success.sh new file mode 100644 index 0000000000..5f672c0dbb --- /dev/null +++ b/build_tools/travis/after_success.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# This script is meant to be called by the "after_success" step defined in +# .travis.yml. See http://docs.travis-ci.com/ for more details. + +set -e + +if [[ "$COVERAGE" == "true" ]]; then + # Ignore codecov failures as the codecov server is not + # very reliable but we don't want travis to report a failure + # in the github UI just because the coverage report failed to + # be published. + codecov || echo "codecov upload failed" +fi diff --git a/build_tools/travis/install.sh b/build_tools/travis/install.sh new file mode 100644 index 0000000000..57370136dc --- /dev/null +++ b/build_tools/travis/install.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# This script is meant to be called by the "install" step defined in +# .travis.yml. See http://docs.travis-ci.com/ for more details. +# The behavior of the script is controlled by environment variabled defined +# in the .travis.yml in the top level folder of the project. + +set -e + +echo 'List files from cached directories' +if [ -d $HOME/download ]; then + echo 'download:' + ls $HOME/download +fi +if [ -d $HOME/.cache/pip ]; then + echo 'pip:' + ls $HOME/.cache/pip +fi + +# Deactivate the travis-provided virtual environment and setup a +# conda-based environment instead +deactivate + +# Add the miniconda bin directory to $PATH +export PATH=/home/travis/miniconda3/bin:$PATH +echo $PATH + +# Use the miniconda installer for setup of conda itself +pushd . +cd +mkdir -p download +cd download +if [[ ! -f /home/travis/miniconda3/bin/activate ]] +then + if [[ ! -f miniconda.sh ]] + then + wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh \ + -O miniconda.sh + fi + chmod +x miniconda.sh && ./miniconda.sh -b -f + conda update --yes conda + echo "Creating environment to run tests in." + conda create -n testenv --yes python="$PYTHON_VERSION" +fi +cd .. +popd + +# Activate the python environment we created. +source activate testenv + +# Install requirements via pip in our conda environment +pip install -r requirements.txt + +# Install the following only if running tests +if [[ "$SKIP_TESTS" != "true" ]]; then + # SpaCy English models + python -m spacy download en + +# TODO: Add nltk data back once moses tokenizer is back online. +# https://github.com/alvations/sacremoses/issues/61 +# # NLTK data needed for Moses tokenizer +# python -m nltk.downloader perluniprops nonbreaking_prefixes +# + # PyTorch + conda install --yes pytorch -c pytorch-test + + # Installation + python setup.py install +fi diff --git a/build_tools/travis/test_script.sh b/build_tools/travis/test_script.sh new file mode 100644 index 0000000000..200d8eb8bd --- /dev/null +++ b/build_tools/travis/test_script.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# This script is meant to be called by the "script" step defined in +# .travis.yml. See http://docs.travis-ci.com/ for more details. +# The behavior of the script is controlled by environment variabled defined +# in the .travis.yml in the top level folder of the project. + +set -e + +python --version + +run_tests() { + if [[ "$RUN_SLOW" == "true" ]]; then + TEST_CMD="py.test --runslow -s -v --cov=torchtext --durations=20" + else + TEST_CMD="py.test -v --cov=torchtext --durations=20" + fi + $TEST_CMD +} + +if [[ "$RUN_FLAKE8" == "true" ]]; then + flake8 +fi + +if [[ "$SKIP_TESTS" != "true" ]]; then + run_tests +fi diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000000..e69de29bb2 From bfbdaec37fbcda801b966fdc9787f76181ada75a Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Thu, 30 Apr 2020 21:28:19 -0700 Subject: [PATCH 07/68] torchtext flake8, github, travis metafiles Summary: See title Reviewed By: pbelevich Differential Revision: D21344211 fbshipit-source-id: a8bcf7f3ab9bb2c2853e27f612e82caa341d3651 --- .flake8 | 4 ++ .github/ISSUE_TEMPLATE/bug-report.md | 48 +++++++++++++++++++ .github/ISSUE_TEMPLATE/documentation.md | 10 ++++ .github/ISSUE_TEMPLATE/feature-request.md | 24 ++++++++++ .../ISSUE_TEMPLATE/questions-help-support.md | 10 ++++ .travis.yml | 23 +++++++++ 6 files changed, 119 insertions(+) create mode 100644 .flake8 create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/documentation.md create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md create mode 100644 .github/ISSUE_TEMPLATE/questions-help-support.md create mode 100644 .travis.yml diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000000..50ecc8aa11 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +ignore = E402,E722,W503,W504,F821 +max-line-length = 120 +exclude = docs/source diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000000..15104939bf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,48 @@ +--- +name: "\U0001F41B Bug Report" +about: Submit a bug report to help us improve TorchText + +--- + +## 🐛 Bug +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Environment** + +Please copy and paste the output from our +[environment collection script](https://raw.githubusercontent.com/pytorch/text/master/torchtext/utils/collect_env.py) +(or fill out the checklist below manually). + +You can get the script and run it with: +``` +wget https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect_env.py +# For security purposes, please check the contents of collect_env.py before running it. +python collect_env.py +python -c "import torchtext; print(\"torchtext version is \", torchtext.__version__)" +``` + + - PyTorch Version (e.g., 1.0): + - OS (e.g., Linux): + - How you installed PyTorch (`conda`, `pip`, source): + - Build command you used (if compiling from source): + - Python version: + - CUDA/cuDNN version: + - GPU models and configuration: + - Any other relevant information: + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 0000000000..b9e37a2774 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,10 @@ +--- +name: "\U0001F4DA Documentation" +about: Report an issue related to TorchText + +--- + +## 📚 Documentation + +**Description** + diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 0000000000..4872607a45 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,24 @@ +--- +name: "\U0001F680Feature Request" +about: Submit a proposal/request for a new TorchText feature + +--- + +## 🚀 Feature + + +**Motivation** + + + +**Pitch** + + + +**Alternatives** + + + +**Additional context** + + diff --git a/.github/ISSUE_TEMPLATE/questions-help-support.md b/.github/ISSUE_TEMPLATE/questions-help-support.md new file mode 100644 index 0000000000..d1e8eab0dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/questions-help-support.md @@ -0,0 +1,10 @@ +--- +name: "❓Questions/Help/Support" +about: Do you need support? We have resources. + +--- + +## ❓ Questions and Help + +**Description** + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..83f69ea383 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,23 @@ +dist: trusty + +language: python + +cache: + directories: + - /home/travis/download + - /home/travis/.cache/pip + +# This matrix tests that the code works on Python 3.5, +# 3.6 (same versions as PyTorch CI), and passes lint. +matrix: + fast_finish: true + include: + - env: PYTHON_VERSION="3.6" RUN_FLAKE8="true" SKIP_TESTS="true" + sudo: required + +notifications: + email: false + +install: source build_tools/travis/install.sh +script: bash build_tools/travis/test_script.sh +after_success: source build_tools/travis/after_success.sh From 5aeca8d55879aa5338af18ac5d138dc1448b964c Mon Sep 17 00:00:00 2001 From: Moto Hira Date: Wed, 27 May 2020 11:08:39 -0700 Subject: [PATCH 08/68] Import torchtext 20200520 and update build Summary: Import torchtext up to #786 Reviewed By: cpuhrsch Differential Revision: D21483116 fbshipit-source-id: bc8ab38db9dc9ce4a8734ca8ea991c20e4ef0882 --- README.rst | 44 ++- build_tools/__init__.py | 0 build_tools/setup_helpers/__init__.py | 1 + build_tools/setup_helpers/extension.py | 135 ++++++++ build_tools/travis/after_success.sh | 13 - build_tools/travis/install.sh | 68 ---- build_tools/travis/test_script.sh | 26 -- packaging/build_conda.sh | 13 + packaging/build_wheel.bat | 20 ++ packaging/build_wheel.sh | 19 + packaging/pkg_helpers.bash | 233 +++++++++++++ packaging/torchtext/bld.bat | 7 + packaging/torchtext/build.sh | 5 + packaging/torchtext/meta.yaml | 46 +++ packaging/vs2019/activate.bat | 44 +++ packaging/vs2019/conda_build_config.yaml | 24 ++ packaging/vs2019/install_activate.bat | 30 ++ packaging/vs2019/install_runtime.bat | 49 +++ packaging/vs2019/meta.yaml | 24 ++ requirements.txt | 2 +- setup.py | 91 +++-- test/common/assets.py | 32 ++ test/common/test_markers.py | 7 - test/common/torchtext_test_case.py | 2 +- test/conftest.py | 3 - test/data/test_builtin_datasets.py | 59 ++-- test/data/test_dataset.py | 76 +--- test/data/test_field.py | 19 - test/data/test_functional.py | 96 ++++- test/data/test_subword.py | 2 + test/data/test_utils.py | 33 +- test/test_build.py | 327 ++++++++++++++++++ test/test_utils.py | 2 + test/test_vocab.py | 243 ------------- torchtext/__init__.py | 32 +- torchtext/csrc/sentencepiece.cpp | 104 ++++++ torchtext/data/functional.py | 25 +- torchtext/data/iterator.py | 7 + torchtext/data/utils.py | 2 +- .../datasets/raw/text_classification.py | 1 - .../datasets/text_classification.py | 207 ++++++----- torchtext/experimental/functional.py | 34 ++ 42 files changed, 1522 insertions(+), 685 deletions(-) create mode 100644 build_tools/__init__.py create mode 100644 build_tools/setup_helpers/__init__.py create mode 100644 build_tools/setup_helpers/extension.py delete mode 100644 build_tools/travis/after_success.sh delete mode 100644 build_tools/travis/install.sh delete mode 100644 build_tools/travis/test_script.sh create mode 100755 packaging/build_conda.sh create mode 100644 packaging/build_wheel.bat create mode 100755 packaging/build_wheel.sh create mode 100644 packaging/pkg_helpers.bash create mode 100644 packaging/torchtext/bld.bat create mode 100644 packaging/torchtext/build.sh create mode 100644 packaging/torchtext/meta.yaml create mode 100644 packaging/vs2019/activate.bat create mode 100644 packaging/vs2019/conda_build_config.yaml create mode 100644 packaging/vs2019/install_activate.bat create mode 100644 packaging/vs2019/install_runtime.bat create mode 100644 packaging/vs2019/meta.yaml create mode 100644 test/common/assets.py delete mode 100644 test/common/test_markers.py delete mode 100644 test/conftest.py create mode 100644 test/test_build.py create mode 100644 torchtext/csrc/sentencepiece.cpp create mode 100644 torchtext/experimental/functional.py diff --git a/README.rst b/README.rst index a79db166c0..979d87407c 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -.. image:: https://travis-ci.org/pytorch/text.svg?branch=master - :target: https://travis-ci.org/pytorch/text +.. image:: https://circleci.com/gh/pytorch/text.svg?style=svg + :target: https://circleci.com/gh/pytorch/text .. image:: https://codecov.io/gh/pytorch/text/branch/master/graph/badge.svg :target: https://codecov.io/gh/pytorch/text @@ -21,16 +21,24 @@ Note: we are currently re-designing the torchtext library to make it more compat Installation ============ +We recommend Anaconda as Python package management system. Please refer to `pytorch.org `_ for the detail of PyTorch installation. The following is the corresponding ``torchtext`` versions and supported Python versions. -Make sure you have Python 3.5+ and PyTorch 0.4.0 or newer. You can then install torchtext using pip:: +.. csv-table:: Version Compatibility + :header: "PyTorch version", "torchtext version", "Supported Python version" + :widths: 10, 10, 10 - pip install torchtext - -For PyTorch versions before 0.4.0, please use `pip install torchtext==0.2.3`. + nightly build, master, 3.6+ + 1.5, 0.5, 3.5+ + 1.4, 0.4, "2.7, 3.5+" + 0.4 and below, 0.2.3, "2.7, 3.5+" + +Using conda;:: + + conda install -c pytorch torchtext -Or you can install torchtext using conda:: +Using pip;:: - conda install -c pytorch -c powerai torchtext sentencepiece + pip install torchtext Optional requirements --------------------- @@ -44,6 +52,26 @@ Alternatively, you might want to use the `Moses `_ pip install sacremoses +For torchtext 0.5 and below, ``sentencepiece``:: + + conda install -c powerai sentencepiece + +Building from source +-------------------- + +To build torchtext from source, you need ``git``, ``CMake`` and C++11 compiler such as ``g++``.:: + + git clone https://github.com/pytorch/text torchtext + cd torchtext + git submodule update --init --recursive + python setup.py clean install + # or ``python setup.py develop`` if you are making modifications. + +**Note** + +When building from souce, make sure that you have the same C++ compiler as the one used to build PyTorch. A simple way is to build PyTorch from source and use the same environment to build torchtext. +If you are using nightly build of PyTorch, checkout the environment it was built `here (conda) `_ and `here (pip) `_. + Documentation ============= diff --git a/build_tools/__init__.py b/build_tools/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build_tools/setup_helpers/__init__.py b/build_tools/setup_helpers/__init__.py new file mode 100644 index 0000000000..7afa3f31cd --- /dev/null +++ b/build_tools/setup_helpers/__init__.py @@ -0,0 +1 @@ +from .extension import * # noqa diff --git a/build_tools/setup_helpers/extension.py b/build_tools/setup_helpers/extension.py new file mode 100644 index 0000000000..80d515d998 --- /dev/null +++ b/build_tools/setup_helpers/extension.py @@ -0,0 +1,135 @@ +import os +import platform +import subprocess +from pathlib import Path + +from torch.utils.cpp_extension import ( + CppExtension, + BuildExtension as TorchBuildExtension +) + +__all__ = [ + 'get_ext_modules', + 'BuildExtension', +] + +_ROOT_DIR = Path(__file__).parent.parent.parent.resolve() +_CSRC_DIR = _ROOT_DIR / 'torchtext' / 'csrc' +_TP_BASE_DIR = _ROOT_DIR / 'third_party' +_TP_INSTALL_DIR = _TP_BASE_DIR / 'build' + + +def _get_eca(debug): + eca = [] + if platform.system() == "Windows": + eca += ['/MT'] + if debug: + eca += ["-O0", "-g"] + else: + if platform.system() == "Windows": + eca += ['-O2'] + else: + eca += ["-O3"] + return eca + + +def _get_ela(debug): + ela = [] + if debug: + if platform.system() == "Windows": + ela += ["/DEBUG:FULL"] + else: + ela += ["-O0", "-g"] + else: + if platform.system() != "Windows": + ela += ["-O3"] + return ela + + +def _get_srcs(): + return [str(p) for p in _CSRC_DIR.glob('**/*.cpp')] + + +def _get_include_dirs(): + return [ + str(_CSRC_DIR), + str(_TP_INSTALL_DIR / 'include'), + ] + + +def _get_library_dirs(): + return [ + str(_TP_INSTALL_DIR / 'lib'), + ] + + +def _get_libraries(): + # NOTE: The order of the library listed bellow matters. + # + # For example, the symbol `sentencepiece::unigram::Model` is + # defined in sentencepiece but UNDEFINED in sentencepiece_train. + # GCC only remembers the last encountered symbol. + # Therefore placing 'sentencepiece_train' after 'sentencepiece' cause runtime error. + # + # $ nm third_party/build/lib/libsentencepiece_train.a | grep _ZTIN13sentencepiece7unigram5ModelE + # U _ZTIN13sentencepiece7unigram5ModelE + # $ nm third_party/build/lib/libsentencepiece.a | grep _ZTIN13sentencepiece7unigram5ModelE + # 0000000000000000 V _ZTIN13sentencepiece7unigram5ModelE + return [ + 'sentencepiece_train', + 'sentencepiece', + ] + + +def _build_sentence_piece(debug): + build_dir = _TP_BASE_DIR / 'sentencepiece' / 'build' + build_dir.mkdir(exist_ok=True) + build_env = os.environ.copy() + config = 'Debug' if debug else 'Release' + if platform.system() == 'Windows': + extra_args = ['-GNinja'] + build_env.setdefault('CC', 'cl') + build_env.setdefault('CXX', 'cl') + else: + extra_args = [] + subprocess.run( + args=['cmake', f'-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}', + f'-DCMAKE_BUILD_TYPE={config}'] + extra_args + ['..'], + cwd=str(build_dir), + check=True, + env=build_env, + ) + subprocess.run( + args=['cmake', '--build', '.', '--target', 'install', '--config', config], + cwd=str(build_dir), + check=True, + env=build_env, + ) + + +def _configure_third_party(debug): + _build_sentence_piece(debug) + + +_EXT_NAME = 'torchtext._torchtext' + + +def get_ext_modules(debug=False): + return [ + CppExtension( + _EXT_NAME, + _get_srcs(), + libraries=_get_libraries(), + include_dirs=_get_include_dirs(), + library_dirs=_get_library_dirs(), + extra_compile_args=_get_eca(debug), + extra_link_args=_get_ela(debug), + ), + ] + + +class BuildExtension(TorchBuildExtension): + def build_extension(self, ext): + if ext.name == _EXT_NAME: + _configure_third_party(self.debug) + super().build_extension(ext) diff --git a/build_tools/travis/after_success.sh b/build_tools/travis/after_success.sh deleted file mode 100644 index 5f672c0dbb..0000000000 --- a/build_tools/travis/after_success.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# This script is meant to be called by the "after_success" step defined in -# .travis.yml. See http://docs.travis-ci.com/ for more details. - -set -e - -if [[ "$COVERAGE" == "true" ]]; then - # Ignore codecov failures as the codecov server is not - # very reliable but we don't want travis to report a failure - # in the github UI just because the coverage report failed to - # be published. - codecov || echo "codecov upload failed" -fi diff --git a/build_tools/travis/install.sh b/build_tools/travis/install.sh deleted file mode 100644 index 57370136dc..0000000000 --- a/build_tools/travis/install.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# This script is meant to be called by the "install" step defined in -# .travis.yml. See http://docs.travis-ci.com/ for more details. -# The behavior of the script is controlled by environment variabled defined -# in the .travis.yml in the top level folder of the project. - -set -e - -echo 'List files from cached directories' -if [ -d $HOME/download ]; then - echo 'download:' - ls $HOME/download -fi -if [ -d $HOME/.cache/pip ]; then - echo 'pip:' - ls $HOME/.cache/pip -fi - -# Deactivate the travis-provided virtual environment and setup a -# conda-based environment instead -deactivate - -# Add the miniconda bin directory to $PATH -export PATH=/home/travis/miniconda3/bin:$PATH -echo $PATH - -# Use the miniconda installer for setup of conda itself -pushd . -cd -mkdir -p download -cd download -if [[ ! -f /home/travis/miniconda3/bin/activate ]] -then - if [[ ! -f miniconda.sh ]] - then - wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh \ - -O miniconda.sh - fi - chmod +x miniconda.sh && ./miniconda.sh -b -f - conda update --yes conda - echo "Creating environment to run tests in." - conda create -n testenv --yes python="$PYTHON_VERSION" -fi -cd .. -popd - -# Activate the python environment we created. -source activate testenv - -# Install requirements via pip in our conda environment -pip install -r requirements.txt - -# Install the following only if running tests -if [[ "$SKIP_TESTS" != "true" ]]; then - # SpaCy English models - python -m spacy download en - -# TODO: Add nltk data back once moses tokenizer is back online. -# https://github.com/alvations/sacremoses/issues/61 -# # NLTK data needed for Moses tokenizer -# python -m nltk.downloader perluniprops nonbreaking_prefixes -# - # PyTorch - conda install --yes pytorch -c pytorch-test - - # Installation - python setup.py install -fi diff --git a/build_tools/travis/test_script.sh b/build_tools/travis/test_script.sh deleted file mode 100644 index 200d8eb8bd..0000000000 --- a/build_tools/travis/test_script.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# This script is meant to be called by the "script" step defined in -# .travis.yml. See http://docs.travis-ci.com/ for more details. -# The behavior of the script is controlled by environment variabled defined -# in the .travis.yml in the top level folder of the project. - -set -e - -python --version - -run_tests() { - if [[ "$RUN_SLOW" == "true" ]]; then - TEST_CMD="py.test --runslow -s -v --cov=torchtext --durations=20" - else - TEST_CMD="py.test -v --cov=torchtext --durations=20" - fi - $TEST_CMD -} - -if [[ "$RUN_FLAKE8" == "true" ]]; then - flake8 -fi - -if [[ "$SKIP_TESTS" != "true" ]]; then - run_tests -fi diff --git a/packaging/build_conda.sh b/packaging/build_conda.sh new file mode 100755 index 0000000000..50c94d6204 --- /dev/null +++ b/packaging/build_conda.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -ex + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +. "$script_dir/pkg_helpers.bash" + +export BUILD_TYPE="conda" +export NO_CUDA_PACKAGE=1 +setup_env 0.6.0 +export SOURCE_ROOT_DIR="$PWD" +setup_conda_pytorch_constraint +setup_visual_studio_constraint +conda build $CONDA_CHANNEL_FLAGS --no-anaconda-upload --python "$PYTHON_VERSION" packaging/torchtext diff --git a/packaging/build_wheel.bat b/packaging/build_wheel.bat new file mode 100644 index 0000000000..90bd865361 --- /dev/null +++ b/packaging/build_wheel.bat @@ -0,0 +1,20 @@ +@echo on + +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -legacy -products * -version [15^,17^) -property installationPath`) do ( + if exist "%%i" if exist "%%i\VC\Auxiliary\Build\vcvarsall.bat" ( + set "VS15INSTALLDIR=%%i" + set "VS15VCVARSALL=%%i\VC\Auxiliary\Build\vcvarsall.bat" + goto vswhere + ) +) + +:vswhere +if "%VSDEVCMD_ARGS%" == "" ( + call "%VS15VCVARSALL%" x64 || exit /b 1 +) else ( + call "%VS15VCVARSALL%" x64 %VSDEVCMD_ARGS% || exit /b 1 +) + +@echo on + +python setup.py bdist_wheel || exit /b 1 diff --git a/packaging/build_wheel.sh b/packaging/build_wheel.sh new file mode 100755 index 0000000000..1bfa107ff2 --- /dev/null +++ b/packaging/build_wheel.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -ex + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +. "$script_dir/pkg_helpers.bash" + +export BUILD_TYPE="wheel" +export NO_CUDA_PACKAGE=1 +setup_env 0.6.0 +setup_wheel_python +pip_install numpy future +setup_pip_pytorch_version +git submodule update --init --recursive +python setup.py clean +if [[ "$OSTYPE" == "msys" ]]; then + "$script_dir/build_wheel.bat" +else + python setup.py bdist_wheel +fi diff --git a/packaging/pkg_helpers.bash b/packaging/pkg_helpers.bash new file mode 100644 index 0000000000..6f43f8e025 --- /dev/null +++ b/packaging/pkg_helpers.bash @@ -0,0 +1,233 @@ +#!/usr/bin/env bash + +# A set of useful bash functions for common functionality we need to do in +# many build scripts + + +# Setup CUDA environment variables, based on CU_VERSION +# +# Inputs: +# CU_VERSION (cpu, cu92, cu100) +# NO_CUDA_PACKAGE (bool) +# BUILD_TYPE (conda, wheel) +# +# Outputs: +# VERSION_SUFFIX (e.g., "") +# PYTORCH_VERSION_SUFFIX (e.g., +cpu) +# WHEEL_DIR (e.g., cu100/) +# CUDA_HOME (e.g., /usr/local/cuda-9.2, respected by torch.utils.cpp_extension) +# FORCE_CUDA (respected by torchvision setup.py) +# NVCC_FLAGS (respected by torchvision setup.py) +# +# Precondition: CUDA versions are installed in their conventional locations in +# /usr/local/cuda-* +# +# NOTE: Why VERSION_SUFFIX versus PYTORCH_VERSION_SUFFIX? If you're building +# a package with CUDA on a platform we support CUDA on, VERSION_SUFFIX == +# PYTORCH_VERSION_SUFFIX and everyone is happy. However, if you are building a +# package with only CPU bits (e.g., torchaudio), then VERSION_SUFFIX is always +# empty, but PYTORCH_VERSION_SUFFIX is +cpu (because that's how you get a CPU +# version of a Python package. But that doesn't apply if you're on OS X, +# since the default CU_VERSION on OS X is cpu. +setup_cuda() { + + # First, compute version suffixes. By default, assume no version suffixes + export VERSION_SUFFIX="" + export PYTORCH_VERSION_SUFFIX="" + export WHEEL_DIR="" + # Wheel builds need suffixes (but not if they're on OS X, which never has suffix) + if [[ "$BUILD_TYPE" == "wheel" ]] && [[ "$(uname)" != Darwin ]]; then + # The default CUDA has no suffix + if [[ "$CU_VERSION" != "cu100" ]]; then + export PYTORCH_VERSION_SUFFIX="+$CU_VERSION" + fi + # Match the suffix scheme of pytorch, unless this package does not have + # CUDA builds (in which case, use default) + if [[ -z "$NO_CUDA_PACKAGE" ]]; then + export VERSION_SUFFIX="$PYTORCH_VERSION_SUFFIX" + # If the suffix is non-empty, we will use a wheel subdirectory + if [[ -n "$PYTORCH_VERSION_SUFFIX" ]]; then + export WHEEL_DIR="$PYTORCH_VERSION_SUFFIX/" + fi + fi + fi + + # Now work out the CUDA settings + case "$CU_VERSION" in + cu100) + export CUDA_HOME=/usr/local/cuda-10.0/ + export FORCE_CUDA=1 + # Hard-coding gencode flags is temporary situation until + # https://github.com/pytorch/pytorch/pull/23408 lands + export NVCC_FLAGS="-gencode=arch=compute_35,code=sm_35 -gencode=arch=compute_50,code=sm_50 -gencode=arch=compute_60,code=sm_60 -gencode=arch=compute_70,code=sm_70 -gencode=arch=compute_75,code=sm_75 -gencode=arch=compute_50,code=compute_50" + ;; + cu92) + export CUDA_HOME=/usr/local/cuda-9.2/ + export FORCE_CUDA=1 + export NVCC_FLAGS="-gencode=arch=compute_35,code=sm_35 -gencode=arch=compute_50,code=sm_50 -gencode=arch=compute_60,code=sm_60 -gencode=arch=compute_70,code=sm_70 -gencode=arch=compute_50,code=compute_50" + ;; + cpu) + ;; + *) + echo "Unrecognized CU_VERSION=$CU_VERSION" + exit 1 + ;; + esac +} + +# Populate build version if necessary, and add version suffix +# +# Inputs: +# BUILD_VERSION (e.g., 0.2.0 or empty) +# VERSION_SUFFIX (e.g., +cpu) +# +# Outputs: +# BUILD_VERSION (e.g., 0.2.0.dev20190807+cpu) +# +# Fill BUILD_VERSION if it doesn't exist already with a nightly string +# Usage: setup_build_version 0.2.0 +setup_build_version() { + if [[ -z "$BUILD_VERSION" ]]; then + export BUILD_VERSION="$1.dev$(date "+%Y%m%d")$VERSION_SUFFIX" + else + export BUILD_VERSION="$BUILD_VERSION$VERSION_SUFFIX" + fi +} + +# Set some useful variables for OS X, if applicable +setup_macos() { + if [[ "$(uname)" == Darwin ]]; then + export MACOSX_DEPLOYMENT_TARGET=10.9 CC=clang CXX=clang++ + fi +} + +# Top-level entry point for things every package will need to do +# +# Usage: setup_env 0.2.0 +setup_env() { + setup_cuda + setup_build_version "$1" + setup_macos +} + +# Function to retry functions that sometimes timeout or have flaky failures +retry () { + $* || (sleep 1 && $*) || (sleep 2 && $*) || (sleep 4 && $*) || (sleep 8 && $*) +} + +# Inputs: +# PYTHON_VERSION (2.7, 3.5, 3.6, 3.7) +# UNICODE_ABI (bool) +# +# Outputs: +# PATH modified to put correct Python version in PATH +# +# Precondition: If Linux, you are in a soumith/manylinux-cuda* Docker image +setup_wheel_python() { + if [[ "$(uname)" == Darwin || "$OSTYPE" == "msys" ]]; then + eval "$(conda shell.bash hook)" + conda env remove -n "env$PYTHON_VERSION" || true + conda create -yn "env$PYTHON_VERSION" python="$PYTHON_VERSION" + conda activate "env$PYTHON_VERSION" + else + case "$PYTHON_VERSION" in + 2.7) + if [[ -n "$UNICODE_ABI" ]]; then + python_abi=cp27-cp27mu + else + python_abi=cp27-cp27m + fi + ;; + 3.5) python_abi=cp35-cp35m ;; + 3.6) python_abi=cp36-cp36m ;; + 3.7) python_abi=cp37-cp37m ;; + 3.8) python_abi=cp38-cp38 ;; + *) + echo "Unrecognized PYTHON_VERSION=$PYTHON_VERSION" + exit 1 + ;; + esac + export PATH="/opt/python/$python_abi/bin:$PATH" + fi +} + +# Install with pip a bit more robustly than the default +pip_install() { + retry pip install --progress-bar off "$@" +} + +# Install torch with pip, respecting PYTORCH_VERSION, and record the installed +# version into PYTORCH_VERSION, if applicable +setup_pip_pytorch_version() { + if [[ -z "$PYTORCH_VERSION" ]]; then + # Install latest prerelease version of torch, per our nightlies, consistent + # with the requested cuda version + pip_install --pre torch -f "https://download.pytorch.org/whl/nightly/${WHEEL_DIR}torch_nightly.html" + if [[ "$CUDA_VERSION" == "cpu" ]]; then + # CUDA and CPU are ABI compatible on the CPU-only parts, so strip + # in this case + export PYTORCH_VERSION="$(pip show torch | grep ^Version: | sed 's/Version: *//' | sed 's/+.\+//')" + else + export PYTORCH_VERSION="$(pip show torch | grep ^Version: | sed 's/Version: *//')" + fi + else + pip_install "torch==$PYTORCH_VERSION$PYTORCH_VERSION_SUFFIX" \ + -f https://download.pytorch.org/whl/torch_stable.html \ + -f https://download.pytorch.org/whl/nightly/torch_nightly.html + fi +} + +# Fill PYTORCH_VERSION with the latest conda nightly version, and +# CONDA_CHANNEL_FLAGS with appropriate flags to retrieve these versions +# +# You MUST have populated PYTORCH_VERSION_SUFFIX before hand. +setup_conda_pytorch_constraint() { + if [[ -z "$PYTORCH_VERSION" ]]; then + export CONDA_CHANNEL_FLAGS="-c pytorch-nightly" + export PYTORCH_VERSION="$(conda search --json 'pytorch[channel=pytorch-nightly]' | python -c "import sys, json, re; print(re.sub(r'\\+.*$', '', json.load(sys.stdin)['pytorch'][-1]['version']))")" + else + export CONDA_CHANNEL_FLAGS="-c pytorch -c pytorch-nightly" + fi + if [[ "$CU_VERSION" == cpu ]]; then + export CONDA_PYTORCH_BUILD_CONSTRAINT="- pytorch==$PYTORCH_VERSION${PYTORCH_VERSION_SUFFIX}" + export CONDA_PYTORCH_CONSTRAINT="- pytorch==$PYTORCH_VERSION" + else + export CONDA_PYTORCH_BUILD_CONSTRAINT="- pytorch==${PYTORCH_VERSION}${PYTORCH_VERSION_SUFFIX}" + export CONDA_PYTORCH_CONSTRAINT="- pytorch==${PYTORCH_VERSION}${PYTORCH_VERSION_SUFFIX}" + fi +} + +# Translate CUDA_VERSION into CUDA_CUDATOOLKIT_CONSTRAINT +setup_conda_cudatoolkit_constraint() { + export CONDA_CPUONLY_FEATURE="" + if [[ "$(uname)" == Darwin ]]; then + export CONDA_CUDATOOLKIT_CONSTRAINT="" + else + case "$CU_VERSION" in + cu100) + export CONDA_CUDATOOLKIT_CONSTRAINT="- cudatoolkit >=10.0,<10.1 # [not osx]" + ;; + cu92) + export CONDA_CUDATOOLKIT_CONSTRAINT="- cudatoolkit >=9.2,<9.3 # [not osx]" + ;; + cpu) + export CONDA_CUDATOOLKIT_CONSTRAINT="" + export CONDA_CPUONLY_FEATURE="- cpuonly" + ;; + *) + echo "Unrecognized CU_VERSION=$CU_VERSION" + exit 1 + ;; + esac + fi +} + +# Build the proper compiler package before building the final package +setup_visual_studio_constraint() { + if [[ "$OSTYPE" == "msys" ]]; then + export VSTOOLCHAIN_PACKAGE=vs2019 + export VSDEVCMD_ARGS='' + conda build $CONDA_CHANNEL_FLAGS --no-anaconda-upload packaging/$VSTOOLCHAIN_PACKAGE + cp packaging/$VSTOOLCHAIN_PACKAGE/conda_build_config.yaml packaging/torchtext/conda_build_config.yaml + fi +} diff --git a/packaging/torchtext/bld.bat b/packaging/torchtext/bld.bat new file mode 100644 index 0000000000..7e5a4861d3 --- /dev/null +++ b/packaging/torchtext/bld.bat @@ -0,0 +1,7 @@ +@echo off + +git submodule update --init --recursive +if errorlevel 1 exit /b 1 + +python setup.py install --single-version-externally-managed --record=record.txt +if errorlevel 1 exit /b 1 diff --git a/packaging/torchtext/build.sh b/packaging/torchtext/build.sh new file mode 100644 index 0000000000..5888bd687f --- /dev/null +++ b/packaging/torchtext/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -ex + +git submodule update --init --recursive +python setup.py install --single-version-externally-managed --record=record.txt diff --git a/packaging/torchtext/meta.yaml b/packaging/torchtext/meta.yaml new file mode 100644 index 0000000000..a79d8eafb7 --- /dev/null +++ b/packaging/torchtext/meta.yaml @@ -0,0 +1,46 @@ +package: + name: torchtext + version: "{{ environ.get('BUILD_VERSION') }}" + +source: + path: "{{ environ.get('SOURCE_ROOT_DIR') }}" + +requirements: + build: + - {{ compiler('c') }} # [win] + - {{ compiler('cxx') }} # [win] + - cmake + + host: + - python + - setuptools + - cpuonly + {{ environ.get('CONDA_PYTORCH_BUILD_CONSTRAINT') }} + + run: + - python + - requests + - tqdm + {{ environ.get('CONDA_PYTORCH_CONSTRAINT') }} + +build: + string: py{{py}} + +test: + imports: + - torchtext + - torchtext.datasets + - torchtext.data + - torchtext.experimental + + source_files: + - test + + requires: + - pytest + +about: + home: https://github.com/pytorch/text + license: BSD + license_file: LICENSE + summary: 'Data loaders and abstractions for text and NLP' diff --git a/packaging/vs2019/activate.bat b/packaging/vs2019/activate.bat new file mode 100644 index 0000000000..6f607ba751 --- /dev/null +++ b/packaging/vs2019/activate.bat @@ -0,0 +1,44 @@ +:: Set env vars that tell distutils to use the compiler that we put on path +SET DISTUTILS_USE_SDK=1 +SET MSSdk=1 + +SET "VS_VERSION=16.0" +SET "VS_MAJOR=16" +SET "VS_YEAR=2019" + +set "MSYS2_ARG_CONV_EXCL=/AI;/AL;/OUT;/out" +set "MSYS2_ENV_CONV_EXCL=CL" + +:: For Python 3.5+, ensure that we link with the dynamic runtime. See +:: http://stevedower.id.au/blog/building-for-python-3-5-part-two/ for more info +set "PY_VCRUNTIME_REDIST=%PREFIX%\\bin\\vcruntime140.dll" + +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -legacy -products * -version [16^,17^) -property installationPath`) do ( + if exist "%%i" if exist "%%i\VC\Auxiliary\Build\vcvarsall.bat" ( + set "VSINSTALLDIR=%%i\" + goto :vswhere + ) +) + +:vswhere + +:: Shorten PATH to avoid the `input line too long` error. +SET MyPath=%PATH% + +setlocal EnableDelayedExpansion + +SET TempPath="%MyPath:;=";"%" +SET var= +FOR %%a IN (%TempPath%) DO ( + IF EXIST %%~sa ( + SET "var=!var!;%%~sa" + ) +) + +set "TempPath=!var:~1!" +endlocal & set "PATH=%TempPath%" + +:: Shorten current directory too +FOR %%A IN (.) DO CD "%%~sA" + +:: other things added by install_activate.bat at package build time diff --git a/packaging/vs2019/conda_build_config.yaml b/packaging/vs2019/conda_build_config.yaml new file mode 100644 index 0000000000..358052ec01 --- /dev/null +++ b/packaging/vs2019/conda_build_config.yaml @@ -0,0 +1,24 @@ +blas_impl: + - mkl # [x86_64] +c_compiler: + - vs2019 # [win] +cxx_compiler: + - vs2019 # [win] +python: + - 3.5 + - 3.6 +# This differs from target_platform in that it determines what subdir the compiler +# will target, not what subdir the compiler package will be itself. +# For example, we need a win-64 vs2008_win-32 package, so that we compile win-32 +# code on win-64 miniconda. +cross_compiler_target_platform: + - win-64 # [win] +target_platform: + - win-64 # [win] +vc: + - 14 +zip_keys: + - # [win] + - vc # [win] + - c_compiler # [win] + - cxx_compiler # [win] diff --git a/packaging/vs2019/install_activate.bat b/packaging/vs2019/install_activate.bat new file mode 100644 index 0000000000..3c38253aa5 --- /dev/null +++ b/packaging/vs2019/install_activate.bat @@ -0,0 +1,30 @@ +set YEAR=2019 +set VER=16 + +mkdir "%PREFIX%\etc\conda\activate.d" +COPY "%RECIPE_DIR%\activate.bat" "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + +IF "%cross_compiler_target_platform%" == "win-64" ( + set "target_platform=amd64" + echo SET "CMAKE_GENERATOR=Visual Studio %VER% %YEAR% Win64" >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo pushd "%%VSINSTALLDIR%%" >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + IF "%VSDEVCMD_ARGS%" == "" ( + echo CALL "VC\Auxiliary\Build\vcvarsall.bat" x64 >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo popd >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo pushd "%%VSINSTALLDIR%%" >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo CALL "VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + ) ELSE ( + echo CALL "VC\Auxiliary\Build\vcvarsall.bat" x64 %VSDEVCMD_ARGS% >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo popd >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo pushd "%%VSINSTALLDIR%%" >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo CALL "VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 %VSDEVCMD_ARGS% >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + ) + echo popd >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + ) else ( + set "target_platform=x86" + echo SET "CMAKE_GENERATOR=Visual Studio %VER% %YEAR%" >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo pushd "%%VSINSTALLDIR%%" >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo CALL "VC\Auxiliary\Build\vcvars32.bat" >> "%PREFIX%\etc\conda\activate.d\vs%YEAR%_compiler_vars.bat" + echo popd + ) + diff --git a/packaging/vs2019/install_runtime.bat b/packaging/vs2019/install_runtime.bat new file mode 100644 index 0000000000..e09a5ccfb0 --- /dev/null +++ b/packaging/vs2019/install_runtime.bat @@ -0,0 +1,49 @@ +set VC_PATH=x86 +if "%ARCH%"=="64" ( + set VC_PATH=x64 +) + +set MSC_VER=2019 + +rem :: This should always be present for VC installed with VS. Not sure about VC installed with Visual C++ Build Tools 2015 +rem FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKEY_LOCAL_MACHINE\Software\Microsoft\DevDiv\VC\Servicing\14.0\IDE.x64" /v UpdateVersion`) DO ( +rem set SP=%%A +rem ) + +rem if not "%SP%" == "%PKG_VERSION%" ( +rem echo "Version detected from registry: %SP%" +rem echo "does not match version of package being built (%PKG_VERSION%)" +rem echo "Do you have current updates for VS 2015 installed?" +rem exit 1 +rem ) + + +REM ========== REQUIRES Win 10 SDK be installed, or files otherwise copied to location below! +robocopy "C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\%VC_PATH%" "%LIBRARY_BIN%" *.dll /E +robocopy "C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\%VC_PATH%" "%PREFIX%" *.dll /E +if %ERRORLEVEL% GEQ 8 exit 1 + +REM ========== This one comes from visual studio 2019 +set "VC_VER=142" + +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -legacy -products * -version [16^,17^) -property installationPath`) do ( + if exist "%%i" if exist "%%i\VC\Auxiliary\Build\vcvarsall.bat" ( + set "VS15VCVARSALL=%%i\VC\Auxiliary\Build\vcvarsall.bat" + goto :eof + ) +) + +@setlocal +call "%VS15VARSALL%" x64 + +set "REDIST_ROOT=%VCToolsRedistDir%%VC_PATH%" + +robocopy "%REDIST_ROOT%\Microsoft.VC%VC_VER%.CRT" "%LIBRARY_BIN%" *.dll /E +if %ERRORLEVEL% LSS 8 exit 0 +robocopy "%REDIST_ROOT%\Microsoft.VC%VC_VER%.CRT" "%PREFIX%" *.dll /E +if %ERRORLEVEL% LSS 8 exit 0 +robocopy "%REDIST_ROOT%\Microsoft.VC%VC_VER%.OpenMP" "%LIBRARY_BIN%" *.dll /E +if %ERRORLEVEL% LSS 8 exit 0 +robocopy "%REDIST_ROOT%\Microsoft.VC%VC_VER%.OpenMP" "%PREFIX%" *.dll /E +if %ERRORLEVEL% LSS 8 exit 0 +@endlocal diff --git a/packaging/vs2019/meta.yaml b/packaging/vs2019/meta.yaml new file mode 100644 index 0000000000..94a0ed4db3 --- /dev/null +++ b/packaging/vs2019/meta.yaml @@ -0,0 +1,24 @@ +{% set vcver="14.2" %} +{% set vcfeature="14" %} +{% set vsyear="2019" %} +{% set fullver="15.4.27004.2010" %} + +package: + name: vs{{ vsyear }} + version: {{ fullver }} + +build: + skip: True [not win] + script_env: + - VSDEVCMD_ARGS # [win] + +outputs: + - name: vs{{ vsyear }}_{{ cross_compiler_target_platform }} + script: install_activate.bat + track_features: + # VS 2019 is binary-compatible with VS 2017/vc 14.1 and 2015/vc14. Tools are "v142". + strong: + - vc{{ vcfeature }} + about: + summary: Activation and version verification of MSVC {{ vcver }} (VS {{ vsyear }}) compiler + license: BSD 3-clause diff --git a/requirements.txt b/requirements.txt index cc0a18140f..c9c761c82d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ sphinx_rtd_theme # Required for tests only: # Style-checking for PEP8 -flake8 +flake8==3.7.9 # Run unit tests pytest diff --git a/setup.py b/setup.py index 0c0cff5b03..e93583c5b5 100644 --- a/setup.py +++ b/setup.py @@ -1,29 +1,74 @@ #!/usr/bin/env python -import os import io -import re +import os +import shutil +import subprocess +from pathlib import Path +import distutils.command.clean from setuptools import setup, find_packages +from build_tools import setup_helpers + +ROOT_DIR = Path(__file__).parent.resolve() + def read(*names, **kwargs): - with io.open( - os.path.join(os.path.dirname(__file__), *names), - encoding=kwargs.get("encoding", "utf8") - ) as fp: + with io.open(ROOT_DIR.joinpath(*names), encoding=kwargs.get("encoding", "utf8")) as fp: return fp.read() -def find_version(*file_paths): - version_file = read(*file_paths) - version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", - version_file, re.M) - if version_match: - return version_match.group(1) - raise RuntimeError("Unable to find version string.") +def _get_version(): + version = '0.6.0a0' + sha = None + + try: + cmd = ['git', 'rev-parse', 'HEAD'] + sha = subprocess.check_output(cmd, cwd=str(ROOT_DIR)).decode('ascii').strip() + except Exception: + pass + + if os.getenv('BUILD_VERSION'): + version = os.getenv('BUILD_VERSION') + elif sha is not None: + version += '+' + sha[:7] + + if sha is None: + sha = 'Unknown' + return version, sha + +def _export_version(version, sha): + version_path = ROOT_DIR / 'torchtext' / 'version.py' + with open(version_path, 'w') as fileobj: + fileobj.write("__version__ = '{}'\n".format(version)) + fileobj.write("git_version = {}\n".format(repr(sha))) + + +VERSION, SHA = _get_version() +_export_version(VERSION, SHA) + +print('-- Building version ' + VERSION) + + +class clean(distutils.command.clean.clean): + def run(self): + # Run default behavior first + distutils.command.clean.clean.run(self) + + # Remove torchtext extension + for path in (ROOT_DIR / 'torchtext').glob('**/*.so'): + print(f'removing \'{path}\'') + path.unlink() + # Remove build directory + build_dirs = [ + ROOT_DIR / 'build', + ROOT_DIR / 'third_party' / 'build', + ] + for path in build_dirs: + if path.exists(): + print(f'removing \'{path}\' (and everything under it)') + shutil.rmtree(str(path), ignore_errors=True) -VERSION = find_version('torchtext', '__init__.py') -long_description = read('README.rst') setup_info = dict( # Metadata @@ -33,7 +78,7 @@ def find_version(*file_paths): author_email='jekbradbury@gmail.com', url='https://github.com/pytorch/text', description='Text utilities and datasets for PyTorch', - long_description=long_description, + long_description=read('README.rst'), license='BSD', install_requires=[ @@ -48,11 +93,17 @@ def find_version(*file_paths): 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3 :: Only', ], - # Package info - packages=find_packages(exclude=('test', 'test.*')), - - zip_safe=True, + packages=find_packages(exclude=('test*', 'build_tools*')), + zip_safe=False, + # Extension info + # If you are trying to use torchtext.so and see no registered op. + # See here: https://github.com/pytorch/vision/issues/2134" + ext_modules=setup_helpers.get_ext_modules(), + cmdclass={ + 'build_ext': setup_helpers.BuildExtension.with_options(no_python_abi_suffix=True), + 'clean': clean, + }, ) setup(**setup_info) diff --git a/test/common/assets.py b/test/common/assets.py new file mode 100644 index 0000000000..c7523bb619 --- /dev/null +++ b/test/common/assets.py @@ -0,0 +1,32 @@ +import os +import shutil +import atexit +import tempfile +from pathlib import Path + +_ASSET_DIR = (Path(__file__).parent.parent / "asset").resolve() + +_TEMP_DIR = None + + +def _init_temp_dir(): + """Initialize temporary directory and register clean up at the end of test.""" + global _TEMP_DIR + _TEMP_DIR = tempfile.TemporaryDirectory() # noqa + atexit.register(_TEMP_DIR.cleanup) + + +def get_asset_path(*path_components, use_temp_dir=False): + """Get the path to the file under `test/assets` directory. + When `use_temp_dir` is True, the asset is copied to a temporary location and + path to the temporary file is returned. + """ + path = str(_ASSET_DIR.joinpath(*path_components)) + if not use_temp_dir: + return path + + if _TEMP_DIR is None: + _init_temp_dir() + tgt = os.path.join(_TEMP_DIR.name, path_components[-1]) + shutil.copy(path, tgt) + return tgt diff --git a/test/common/test_markers.py b/test/common/test_markers.py deleted file mode 100644 index 903f5c5450..0000000000 --- a/test/common/test_markers.py +++ /dev/null @@ -1,7 +0,0 @@ -import pytest -import os - -slow = pytest.mark.skipif( - os.getenv('RUN_SLOW', 'False') == 'False', - reason="This test is slow." -) diff --git a/test/common/torchtext_test_case.py b/test/common/torchtext_test_case.py index fb62fb3403..249e5aa0c9 100644 --- a/test/common/torchtext_test_case.py +++ b/test/common/torchtext_test_case.py @@ -56,7 +56,7 @@ def write_test_ppid_dataset(self, data_format="csv"): "question2": "2+2=?", "label": "1"}, ] - with open(self.test_ppid_dataset_path, "w") as test_ppid_dataset_file: + with open(self.test_ppid_dataset_path, "w", encoding="utf-8") as test_ppid_dataset_file: for example in dict_dataset: if data_format == "json": test_ppid_dataset_file.write(json.dumps(example) + "\n") diff --git a/test/conftest.py b/test/conftest.py deleted file mode 100644 index 3860ed6e34..0000000000 --- a/test/conftest.py +++ /dev/null @@ -1,3 +0,0 @@ -def pytest_addoption(parser): - parser.addoption("--runslow", action="store_true", - help="Run slow tests") diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index b2723949b2..08c75292c4 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -1,10 +1,11 @@ +#!/user/bin/env python3 +# Note that all the tests in this module require dataset (either network access or cached) import os import shutil import torchtext.data as data from torchtext.datasets import AG_NEWS import torch from torch.testing import assert_allclose -from ..common.test_markers import slow from ..common.torchtext_test_case import TorchtextTestCase @@ -16,10 +17,16 @@ def conditional_remove(f): class TestDataset(TorchtextTestCase): - @slow def test_wikitext2_legacy(self): from torchtext.datasets import WikiText2 # smoke test to ensure wikitext2 works properly + + # NOTE + # test_wikitext2 and test_wikitext2_legacy have some cache incompatibility. + # Keeping one's cache make the other fail. So we need to clean up the cache dir + cachedir = os.path.join(self.project_root, ".data", "wikitext-2") + conditional_remove(cachedir) + ds = WikiText2 TEXT = data.Field(lower=True, batch_first=True) train, valid, test = ds.splits(TEXT) @@ -30,13 +37,20 @@ def test_wikitext2_legacy(self): train_iter, valid_iter, test_iter = ds.iters(batch_size=4, bptt_len=30) - # Delete the dataset after we're done to save disk space on CI - datafile = os.path.join(self.project_root, ".data", "wikitext-2") - conditional_remove(datafile) + conditional_remove(cachedir) def test_wikitext2(self): from torchtext.experimental.datasets import WikiText2 # smoke test to ensure wikitext2 works properly + + # NOTE + # test_wikitext2 and test_wikitext2_legacy have some cache incompatibility. + # Keeping one's cache make the other fail. So we need to clean up the cache dir + cachedir = os.path.join(self.project_root, ".data", "wikitext-2") + conditional_remove(cachedir) + cachefile = os.path.join(self.project_root, ".data", "wikitext-2-v1.zip") + conditional_remove(cachefile) + train_dataset, test_dataset, valid_dataset = WikiText2() self.assertEqual(len(train_dataset), 2049990) self.assertEqual(len(test_dataset), 241859) @@ -46,13 +60,9 @@ def test_wikitext2(self): tokens_ids = [vocab[token] for token in 'the player characters rest'.split()] self.assertEqual(tokens_ids, [2, 286, 503, 700]) - # Delete the dataset after we're done to save disk space on CI - datafile = os.path.join(self.project_root, ".data", "wikitext-2") - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", "wikitext-2-v1.zip") - conditional_remove(datafile) + conditional_remove(cachedir) + conditional_remove(cachefile) - @slow def test_penntreebank_legacy(self): from torchtext.datasets import PennTreebank # smoke test to ensure penn treebank works properly @@ -66,10 +76,6 @@ def test_penntreebank_legacy(self): train_iter, valid_iter, test_iter = ds.iters(batch_size=4, bptt_len=30) - # Delete the dataset after we're done to save disk space on CI - datafile = os.path.join(self.project_root, ".data", "penn-treebank") - conditional_remove(datafile) - def test_penntreebank(self): from torchtext.experimental.datasets import PennTreebank # smoke test to ensure wikitext2 works properly @@ -82,14 +88,6 @@ def test_penntreebank(self): tokens_ids = [vocab[token] for token in 'the player characters rest'.split()] self.assertEqual(tokens_ids, [2, 2550, 3344, 1125]) - # Delete the dataset after we're done to save disk space on CI - datafile = os.path.join(self.project_root, ".data", 'ptb.train.txt') - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", 'ptb.test.txt') - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", 'ptb.valid.txt') - conditional_remove(datafile) - def test_text_classification(self): # smoke test to ensure ag_news dataset works properly @@ -104,13 +102,6 @@ def test_text_classification(self): assert_allclose(ag_news_test[-1][1][:10], torch.tensor([2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]).long()) - # Delete the dataset after we're done to save disk space on CI - datafile = os.path.join(self.project_root, ".data", "ag_news_csv") - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", "ag_news_csv.tar.gz") - conditional_remove(datafile) - - @slow def test_imdb(self): from torchtext.experimental.datasets import IMDB from torchtext.vocab import Vocab @@ -131,11 +122,3 @@ def test_imdb(self): old_vocab = train_dataset.get_vocab() new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) new_train_data, new_test_data = IMDB(vocab=new_vocab) - - # Delete the dataset after we're done to save disk space on CI - datafile = os.path.join(self.project_root, ".data", "imdb") - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", "aclImdb") - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", "aclImdb_v1.tar.gz") - conditional_remove(datafile) diff --git a/test/data/test_dataset.py b/test/data/test_dataset.py index 6b3e974f75..849e6a770a 100644 --- a/test/data/test_dataset.py +++ b/test/data/test_dataset.py @@ -1,11 +1,13 @@ # -*- coding: utf-8 -*- import torchtext.data as data +import os +import sys import tempfile +import unittest import pytest from ..common.torchtext_test_case import TorchtextTestCase -import os class TestDataset(TorchtextTestCase): @@ -57,40 +59,6 @@ def test_tabular_simple_data(self): self.assertEqual(example.q2, expected_examples[i][1]) self.assertEqual(example.label, expected_examples[i][2]) - def test_json_dataset_one_key_multiple_fields(self): - self.write_test_ppid_dataset(data_format="json") - - question_field = data.Field(sequential=True) - spacy_tok_question_field = data.Field(sequential=True, tokenize="spacy") - label_field = data.Field(sequential=False) - fields = {"question1": [("q1", question_field), - ("q1_spacy", spacy_tok_question_field)], - "question2": [("q2", question_field), - ("q2_spacy", spacy_tok_question_field)], - "label": ("label", label_field)} - dataset = data.TabularDataset( - path=self.test_ppid_dataset_path, format="json", fields=fields) - expected_examples = [ - (["When", "do", "you", "use", "シ", "instead", "of", "し?"], - ["When", "do", "you", "use", "シ", "instead", "of", "し", "?"], - ["When", "do", "you", "use", "\"&\"", - "instead", "of", "\"and\"?"], - ["When", "do", "you", "use", "\"", "&", "\"", - "instead", "of", "\"", "and", "\"", "?"], "0"), - (["Where", "was", "Lincoln", "born?"], - ["Where", "was", "Lincoln", "born", "?"], - ["Which", "location", "was", "Abraham", "Lincoln", "born?"], - ["Which", "location", "was", "Abraham", "Lincoln", "born", "?"], - "1"), - (["What", "is", "2+2"], ["What", "is", "2", "+", "2"], - ["2+2=?"], ["2", "+", "2=", "?"], "1")] - for i, example in enumerate(dataset): - self.assertEqual(example.q1, expected_examples[i][0]) - self.assertEqual(example.q1_spacy, expected_examples[i][1]) - self.assertEqual(example.q2, expected_examples[i][2]) - self.assertEqual(example.q2_spacy, expected_examples[i][3]) - self.assertEqual(example.label, expected_examples[i][4]) - def test_json_valid_and_invalid_nested_key(self): self.write_test_nested_key_json_dataset() valid_fields = {'foods.vegetables.name': ('vegs', data.Field()), @@ -198,43 +166,7 @@ def test_csv_file_with_header(self): sort_within_batch=False, repeat=False) next(data_iter.__iter__()) - def test_csv_file_no_header_one_col_multiple_fields(self): - self.write_test_ppid_dataset(data_format="csv") - - question_field = data.Field(sequential=True) - spacy_tok_question_field = data.Field(sequential=True, tokenize="spacy") - label_field = data.Field(sequential=False) - # Field name/value as nested tuples - fields = [("ids", None), - (("q1", "q1_spacy"), (question_field, spacy_tok_question_field)), - (("q2", "q2_spacy"), (question_field, spacy_tok_question_field)), - ("label", label_field)] - dataset = data.TabularDataset( - path=self.test_ppid_dataset_path, format="csv", fields=fields) - expected_examples = [ - (["When", "do", "you", "use", "シ", "instead", "of", "し?"], - ["When", "do", "you", "use", "シ", "instead", "of", "し", "?"], - ["When", "do", "you", "use", "\"&\"", - "instead", "of", "\"and\"?"], - ["When", "do", "you", "use", "\"", "&", "\"", - "instead", "of", "\"", "and", "\"", "?"], "0"), - (["Where", "was", "Lincoln", "born?"], - ["Where", "was", "Lincoln", "born", "?"], - ["Which", "location", "was", "Abraham", "Lincoln", "born?"], - ["Which", "location", "was", "Abraham", "Lincoln", "born", "?"], - "1"), - (["What", "is", "2+2"], ["What", "is", "2", "+", "2"], - ["2+2=?"], ["2", "+", "2=", "?"], "1")] - for i, example in enumerate(dataset): - self.assertEqual(example.q1, expected_examples[i][0]) - self.assertEqual(example.q1_spacy, expected_examples[i][1]) - self.assertEqual(example.q2, expected_examples[i][2]) - self.assertEqual(example.q2_spacy, expected_examples[i][3]) - self.assertEqual(example.label, expected_examples[i][4]) - - # 6 Fields including None for ids - assert len(dataset.fields) == 6 - + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_csv_dataset_quotechar(self): # Based on issue #349 example_data = [("text", "label"), diff --git a/test/data/test_field.py b/test/data/test_field.py index 14fe043776..11b98bde68 100644 --- a/test/data/test_field.py +++ b/test/data/test_field.py @@ -6,10 +6,8 @@ import torch import torchtext.data as data import pytest -from torch.nn import init from ..common.torchtext_test_case import TorchtextTestCase, verify_numericalized_example -from ..common.test_markers import slow class TestField(TorchtextTestCase): @@ -866,23 +864,6 @@ def test_serialization(self): assert torch.all(torch.eq(original_numericalization, pickled_numericalization)) - @slow - def test_build_vocab(self): - nesting_field = data.Field(tokenize=list, init_token="", eos_token="") - - field = data.NestedField(nesting_field, init_token='', eos_token='', - include_lengths=True, - pad_first=True) - - sources = [[['a'], ['s', 'e', 'n', 't', 'e', 'n', 'c', 'e'], ['o', 'f'], - ['d', 'a', 't', 'a'], ['.']], - [['y', 'e', 't'], ['a', 'n', 'o', 't', 'h', 'e', 'r']], - [['o', 'n', 'e'], ['l', 'a', 's', 't'], ['s', 'e', 'n', 't']]] - - field.build_vocab(sources, vectors='glove.6B.50d', - unk_init=init.normal_, - vectors_cache=".vector_cache") - class TestLabelField(TorchtextTestCase): def test_init(self): diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 6c5b86d71b..dacc0adafd 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -1,16 +1,33 @@ -from ..common.torchtext_test_case import TorchtextTestCase -import sentencepiece as spm -from torchtext.data.functional import generate_sp_model, load_sp_model, \ - sentencepiece_numericalizer, sentencepiece_tokenizer, \ - custom_replace, simple_space_split import os +import unittest +import sys +import tempfile + +import sentencepiece as spm +import torch +from torchtext.data.functional import ( + generate_sp_model, + load_sp_model, + sentencepiece_numericalizer, + sentencepiece_tokenizer, + custom_replace, + simple_space_split, +) + +from ..common.torchtext_test_case import TorchtextTestCase +from ..common.assets import get_asset_path class TestFunctional(TorchtextTestCase): def test_generate_sp_model(self): # Test the function to train a sentencepiece tokenizer - data_path = 'test/asset/text_normalization_ag_news_test.csv' + # buck (fb internal) generates test environment which contains ',' in its path. + # SentencePieceTrainer considers such path as comma-delimited file list. + # So as workaround we copy the asset data to temporary directory and load it from there. + data_path = get_asset_path( + 'text_normalization_ag_news_test.csv', + use_temp_dir=True) generate_sp_model(data_path, vocab_size=23456, model_prefix='spm_user') @@ -27,9 +44,9 @@ def test_generate_sp_model(self): def test_sentencepiece_numericalizer(self): test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' - model_path = 'test/asset/spm_example.model' + model_path = get_asset_path('spm_example.model') sp_model = load_sp_model(model_path) - self.assertEqual(len(sp_model), 20000) + self.assertEqual(sp_model.GetPieceSize(), 20000) spm_generator = sentencepiece_numericalizer(sp_model) ref_results = [15340, 4286, 981, 1207, 1681, 17, 84, 684, 8896, 5366, @@ -41,9 +58,9 @@ def test_sentencepiece_numericalizer(self): def test_sentencepiece_tokenizer(self): test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' - model_path = 'test/asset/spm_example.model' + model_path = get_asset_path('spm_example.model') sp_model = load_sp_model(model_path) - self.assertEqual(len(sp_model), 20000) + self.assertEqual(sp_model.GetPieceSize(), 20000) spm_generator = sentencepiece_tokenizer(sp_model) ref_results = ['\u2581Sent', 'ence', 'P', 'ie', 'ce', '\u2581is', @@ -66,3 +83,62 @@ def test_simple_space_split(self): ref_results = ['test', 'simple', 'space', 'split', 'function'] self.assertEqual(list(simple_space_split(test_sample))[0], ref_results) + + +class ScriptableSP(torch.jit.ScriptModule): + def __init__(self, model_path): + super().__init__() + self.spm = load_sp_model(model_path) + + @torch.jit.script_method + def encode(self, input: str): + return self.spm.Encode(input) + + @torch.jit.script_method + def encode_as_ids(self, input: str): + return self.spm.EncodeAsIds(input) + + @torch.jit.script_method + def encode_as_pieces(self, input: str): + return self.spm.EncodeAsPieces(input) + + +class TestScriptableSP(unittest.TestCase): + def setUp(self): + model_path = get_asset_path('spm_example.model') + with tempfile.NamedTemporaryFile() as file: + torch.jit.script(ScriptableSP(model_path)).save(file.name) + self.model = torch.jit.load(file.name) + + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") + def test_encode(self): + input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' + expected = [ + '▁Sent', 'ence', 'P', 'ie', 'ce', '▁is', + '▁an', '▁un', 'super', 'vis', 'ed', '▁text', + '▁to', 'ken', 'izer', '▁and', + '▁de', 'to', 'ken', 'izer', + ] + output = self.model.encode(input) + self.assertEqual(expected, output) + + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") + def test_encode_as_ids(self): + input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' + expected = [ + 15340, 4286, 981, 1207, 1681, 17, 84, 684, 8896, 5366, + 144, 3689, 9, 5602, 12114, 6, 560, 649, 5602, 12114] + output = self.model.encode_as_ids(input) + self.assertEqual(expected, output) + + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") + def test_encode_as_pieces(self): + input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' + expected = [ + '\u2581Sent', 'ence', 'P', 'ie', 'ce', '\u2581is', + '\u2581an', '\u2581un', 'super', 'vis', 'ed', '\u2581text', + '\u2581to', 'ken', 'izer', '\u2581and', + '\u2581de', 'to', 'ken', 'izer', + ] + output = self.model.encode_as_pieces(input) + self.assertEqual(expected, output) diff --git a/test/data/test_subword.py b/test/data/test_subword.py index 88e57c5044..5122fd6997 100644 --- a/test/data/test_subword.py +++ b/test/data/test_subword.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 +# Note that all the tests in this module require dataset (either network access or cached) import unittest from torchtext import data diff --git a/test/data/test_utils.py b/test/data/test_utils.py index 29716cbaaf..c64ec09bf8 100644 --- a/test/data/test_utils.py +++ b/test/data/test_utils.py @@ -1,8 +1,10 @@ +import io + import torchtext.data as data -import pytest -from ..common.torchtext_test_case import TorchtextTestCase from torchtext.utils import unicode_csv_reader -import io + +from ..common.torchtext_test_case import TorchtextTestCase +from ..common.assets import get_asset_path class TestUtils(TorchtextTestCase): @@ -13,27 +15,6 @@ def test_get_tokenizer_split(self): assert data.get_tokenizer(str.split) == str.split assert data.get_tokenizer(str.split)(self.TEST_STR) == str.split(self.TEST_STR) - def test_get_tokenizer_spacy(self): - # Test SpaCy option, and verify it properly handles punctuation. - assert data.get_tokenizer("spacy")(str(self.TEST_STR)) == [ - "A", "string", ",", "particularly", "one", "with", "slightly", - "complex", "punctuation", "."] - - # TODO: Remove this once issue was been resolved. - # TODO# Add nltk data back in build_tools/travis/install.sh. - @pytest.mark.skip(reason=("Impractically slow! " - "https://github.com/alvations/sacremoses/issues/61")) - def test_get_tokenizer_moses(self): - # Test Moses option. - # Note that internally, MosesTokenizer converts to unicode if applicable - moses_tokenizer = data.get_tokenizer("moses") - assert moses_tokenizer(self.TEST_STR) == [ - "A", "string", ",", "particularly", "one", "with", "slightly", - "complex", "punctuation", "."] - - # Nonbreaking prefixes should tokenize the final period. - assert moses_tokenizer("abc def.") == ["abc", "def", "."] - def test_get_tokenizer_toktokt(self): # Test Toktok option. Test strings taken from NLTK doctests. # Note that internally, MosesTokenizer converts to unicode if applicable @@ -54,13 +35,13 @@ def test_text_nomalize_function(self): test_lines = [] tokenizer = data.get_tokenizer("basic_english") - data_path = 'test/asset/text_normalization_ag_news_test.csv' + data_path = get_asset_path('text_normalization_ag_news_test.csv') with io.open(data_path, encoding="utf8") as f: reader = unicode_csv_reader(f) for row in reader: test_lines.append(tokenizer(' , '.join(row))) - data_path = 'test/asset/text_normalization_ag_news_ref_results.test' + data_path = get_asset_path('text_normalization_ag_news_ref_results.test') with io.open(data_path, encoding="utf8") as ref_data: for line in ref_data: line = line.split() diff --git a/test/test_build.py b/test/test_build.py new file mode 100644 index 0000000000..f47d535204 --- /dev/null +++ b/test/test_build.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python3 +"""Tests that requires external resources (Network access to fetch dataset)""" +import os +from collections import Counter + +import numpy as np +import torch +import torchtext.data + +from .common.torchtext_test_case import TorchtextTestCase + + +class TestNestedField(TorchtextTestCase): + def test_build_vocab(self): + nesting_field = torchtext.data.Field(tokenize=list, init_token="", eos_token="") + + field = torchtext.data.NestedField( + nesting_field, init_token='', eos_token='', + include_lengths=True, + pad_first=True) + + sources = [ + [['a'], ['s', 'e', 'n', 't', 'e', 'n', 'c', 'e'], ['o', 'f'], ['d', 'a', 't', 'a'], ['.']], + [['y', 'e', 't'], ['a', 'n', 'o', 't', 'h', 'e', 'r']], + [['o', 'n', 'e'], ['l', 'a', 's', 't'], ['s', 'e', 'n', 't']] + ] + + field.build_vocab( + sources, vectors='glove.6B.50d', + unk_init=torch.nn.init.normal_, vectors_cache=".vector_cache") + + +class TestDataset(TorchtextTestCase): + def test_csv_file_no_header_one_col_multiple_fields(self): + self.write_test_ppid_dataset(data_format="csv") + + question_field = torchtext.data.Field(sequential=True) + spacy_tok_question_field = torchtext.data.Field(sequential=True, tokenize="spacy") + label_field = torchtext.data.Field(sequential=False) + # Field name/value as nested tuples + fields = [("ids", None), + (("q1", "q1_spacy"), (question_field, spacy_tok_question_field)), + (("q2", "q2_spacy"), (question_field, spacy_tok_question_field)), + ("label", label_field)] + dataset = torchtext.data.TabularDataset( + path=self.test_ppid_dataset_path, format="csv", fields=fields) + expected_examples = [ + (["When", "do", "you", "use", "シ", "instead", "of", "し?"], + ["When", "do", "you", "use", "シ", "instead", "of", "し", "?"], + ["When", "do", "you", "use", "\"&\"", + "instead", "of", "\"and\"?"], + ["When", "do", "you", "use", "\"", "&", "\"", + "instead", "of", "\"", "and", "\"", "?"], "0"), + (["Where", "was", "Lincoln", "born?"], + ["Where", "was", "Lincoln", "born", "?"], + ["Which", "location", "was", "Abraham", "Lincoln", "born?"], + ["Which", "location", "was", "Abraham", "Lincoln", "born", "?"], + "1"), + (["What", "is", "2+2"], ["What", "is", "2", "+", "2"], + ["2+2=?"], ["2", "+", "2=", "?"], "1")] + for i, example in enumerate(dataset): + self.assertEqual(example.q1, expected_examples[i][0]) + self.assertEqual(example.q1_spacy, expected_examples[i][1]) + self.assertEqual(example.q2, expected_examples[i][2]) + self.assertEqual(example.q2_spacy, expected_examples[i][3]) + self.assertEqual(example.label, expected_examples[i][4]) + + # 6 Fields including None for ids + assert len(dataset.fields) == 6 + + def test_json_dataset_one_key_multiple_fields(self): + self.write_test_ppid_dataset(data_format="json") + + question_field = torchtext.data.Field(sequential=True) + spacy_tok_question_field = torchtext.data.Field(sequential=True, tokenize="spacy") + label_field = torchtext.data.Field(sequential=False) + fields = {"question1": [("q1", question_field), + ("q1_spacy", spacy_tok_question_field)], + "question2": [("q2", question_field), + ("q2_spacy", spacy_tok_question_field)], + "label": ("label", label_field)} + dataset = torchtext.data.TabularDataset( + path=self.test_ppid_dataset_path, format="json", fields=fields) + expected_examples = [ + (["When", "do", "you", "use", "シ", "instead", "of", "し?"], + ["When", "do", "you", "use", "シ", "instead", "of", "し", "?"], + ["When", "do", "you", "use", "\"&\"", + "instead", "of", "\"and\"?"], + ["When", "do", "you", "use", "\"", "&", "\"", + "instead", "of", "\"", "and", "\"", "?"], "0"), + (["Where", "was", "Lincoln", "born?"], + ["Where", "was", "Lincoln", "born", "?"], + ["Which", "location", "was", "Abraham", "Lincoln", "born?"], + ["Which", "location", "was", "Abraham", "Lincoln", "born", "?"], + "1"), + (["What", "is", "2+2"], ["What", "is", "2", "+", "2"], + ["2+2=?"], ["2", "+", "2=", "?"], "1")] + for i, example in enumerate(dataset): + self.assertEqual(example.q1, expected_examples[i][0]) + self.assertEqual(example.q1_spacy, expected_examples[i][1]) + self.assertEqual(example.q2, expected_examples[i][2]) + self.assertEqual(example.q2_spacy, expected_examples[i][3]) + self.assertEqual(example.label, expected_examples[i][4]) + + +class TestDataUtils(TorchtextTestCase): + TEST_STR = "A string, particularly one with slightly complex punctuation." + + def test_get_tokenizer_spacy(self): + # Test SpaCy option, and verify it properly handles punctuation. + assert torchtext.data.get_tokenizer("spacy")(str(self.TEST_STR)) == [ + "A", "string", ",", "particularly", "one", "with", "slightly", + "complex", "punctuation", "."] + + def test_get_tokenizer_moses(self): + # Test Moses option. + # Note that internally, MosesTokenizer converts to unicode if applicable + moses_tokenizer = torchtext.data.get_tokenizer("moses") + assert moses_tokenizer(self.TEST_STR) == [ + "A", "string", ",", "particularly", "one", "with", "slightly", + "complex", "punctuation", "."] + + # Nonbreaking prefixes should tokenize the final period. + assert moses_tokenizer("abc def.") == ["abc", "def", "."] + + +class TestVocab(TorchtextTestCase): + def test_vectors_get_vecs(self): + vec = torchtext.vocab.GloVe(name='twitter.27B', dim='25') + self.assertEqual(vec.vectors.shape[0], len(vec)) + + tokens = ['chip', 'baby', 'Beautiful'] + token_vecs = vec.get_vecs_by_tokens(tokens).numpy() + self.assertEqual(token_vecs.shape[0], len(tokens)) + self.assertEqual(token_vecs.shape[1], vec.dim) + torch.testing.assert_allclose(vec[tokens[0]].numpy(), token_vecs[0]) + torch.testing.assert_allclose(vec[tokens[1]].numpy(), token_vecs[1]) + torch.testing.assert_allclose(vec[''].numpy(), token_vecs[2]) + + token_one_vec = vec.get_vecs_by_tokens(tokens[0], lower_case_backup=True).numpy() + self.assertEqual(token_one_vec.shape[0], vec.dim) + torch.testing.assert_allclose(vec[tokens[0].lower()].numpy(), token_one_vec) + + def test_download_charngram_vectors(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + # Build a vocab and get vectors twice to test caching, then once more + # to test string aliases. + for i in range(3): + if i == 2: + vectors = "charngram.100d" + else: + vectors = torchtext.vocab.CharNGram() + v = torchtext.vocab.Vocab( + c, min_freq=3, specials=['', '', ''], vectors=vectors) + expected_itos = ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.itos, expected_itos) + self.assertEqual(dict(v.stoi), expected_stoi) + vectors = v.vectors.numpy() + + # The first 5 entries in each vector. + expected_charngram = { + 'hello': [-0.44782442, -0.08937783, -0.34227219, + -0.16233221, -0.39343098], + 'world': [-0.29590717, -0.05275926, -0.37334684, 0.27117205, -0.3868292], + } + + for word in expected_charngram: + torch.testing.assert_allclose( + vectors[v.stoi[word], :5], expected_charngram[word]) + + torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(100)) + torch.testing.assert_allclose(vectors[v.stoi['OOV token']], np.zeros(100)) + + def test_download_custom_vectors(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + # Build a vocab and get vectors twice to test caching. + for _ in range(2): + v = torchtext.vocab.Vocab( + c, min_freq=3, specials=['', '', ''], + vectors=torchtext.vocab.Vectors( + 'wiki.simple.vec', + url=torchtext.vocab.FastText.url_base.format('simple') + ) + ) + + self.assertEqual(v.itos, ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) + vectors = v.vectors.numpy() + + # The first 5 entries in each vector. + expected_fasttext_simple_en = { + 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], + 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], + } + + for word in expected_fasttext_simple_en: + torch.testing.assert_allclose( + vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) + + torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) + + def test_download_fasttext_vectors(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + # Build a vocab and get vectors twice to test caching, then once more + # to test string aliases. + for i in range(3): + if i == 2: + vectors = "fasttext.simple.300d" + else: + vectors = torchtext.vocab.FastText(language='simple') + + v = torchtext.vocab.Vocab( + c, min_freq=3, specials=['', '', ''], vectors=vectors) + + expected_itos = ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.itos, expected_itos) + self.assertEqual(dict(v.stoi), expected_stoi) + vectors = v.vectors.numpy() + + # The first 5 entries in each vector. + expected_fasttext_simple_en = { + 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], + 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], + } + + for word in expected_fasttext_simple_en: + torch.testing.assert_allclose( + vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) + + torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) + torch.testing.assert_allclose(vectors[v.stoi['OOV token']], np.zeros(300)) + + def test_download_glove_vectors(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + + # Build a vocab and get vectors twice to test caching, then once more + # to test string aliases. + for i in range(3): + if i == 2: + vectors = "glove.twitter.27B.25d" + else: + vectors = torchtext.vocab.GloVe(name='twitter.27B', dim='25') + v = torchtext.vocab.Vocab( + c, min_freq=3, specials=['', '', ''], vectors=vectors) + + expected_itos = ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.itos, expected_itos) + self.assertEqual(dict(v.stoi), expected_stoi) + + vectors = v.vectors.numpy() + + # The first 5 entries in each vector. + expected_twitter = { + 'hello': [-0.77069, 0.12827, 0.33137, 0.0050893, -0.47605], + 'world': [0.10301, 0.095666, -0.14789, -0.22383, -0.14775], + } + + for word in expected_twitter: + torch.testing.assert_allclose( + vectors[v.stoi[word], :5], expected_twitter[word]) + + torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(25)) + torch.testing.assert_allclose(vectors[v.stoi['OOV token']], np.zeros(25)) + + def test_extend(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + # Build a vocab and get vectors twice to test caching. + for _ in range(2): + f = torchtext.vocab.FastText(language='simple') + v = torchtext.vocab.Vocab( + c, min_freq=3, specials=['', '', ''], vectors=f) + n_vocab = len(v) + v.extend(f) # extend the vocab with the words contained in f.itos + self.assertGreater(len(v), n_vocab) + + self.assertEqual(v.itos[:6], ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) + vectors = v.vectors.numpy() + + # The first 5 entries in each vector. + expected_fasttext_simple_en = { + 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], + 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], + } + + for word in expected_fasttext_simple_en: + torch.testing.assert_allclose( + vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) + + torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) + + def test_vectors_custom_cache(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + vector_cache = os.path.join('/tmp', 'vector_cache') + # Build a vocab and get vectors twice to test caching. + for i in range(2): + if i == 1: + self.assertTrue(os.path.exists(vector_cache)) + + v = torchtext.vocab.Vocab( + c, min_freq=3, specials=['', '', ''], + vectors=torchtext.vocab.Vectors( + 'wiki.simple.vec', cache=vector_cache, + url=torchtext.vocab.FastText.url_base.format('simple')) + ) + + self.assertEqual(v.itos, ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) + vectors = v.vectors.numpy() + + # The first 5 entries in each vector. + expected_fasttext_simple_en = { + 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], + 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], + } + + for word in expected_fasttext_simple_en: + torch.testing.assert_allclose( + vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) + + torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) diff --git a/test/test_utils.py b/test/test_utils.py index fc10978157..5489f838b2 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 +# Note that all the tests in this module require dataset (either network access or cached) import os from torchtext import utils from .common.torchtext_test_case import TorchtextTestCase diff --git a/test/test_vocab.py b/test/test_vocab.py index 446954cdf6..c09bff69f2 100644 --- a/test/test_vocab.py +++ b/test/test_vocab.py @@ -8,9 +8,7 @@ from numpy.testing import assert_allclose import torch from torchtext import vocab -from torchtext.vocab import Vectors, FastText, GloVe, CharNGram -from .common.test_markers import slow from .common.torchtext_test_case import TorchtextTestCase @@ -93,221 +91,6 @@ def test_vocab_set_vectors(self): [0.3, 0.4]]) assert_allclose(v.vectors.numpy(), expected_vectors) - @slow - def test_vocab_download_fasttext_vectors(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - # Build a vocab and get vectors twice to test caching, then once more - # to test string aliases. - for i in range(3): - if i == 2: - vectors = "fasttext.simple.300d" - else: - vectors = FastText(language='simple') - - v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors=vectors) - - expected_itos = ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.itos, expected_itos) - self.assertEqual(dict(v.stoi), expected_stoi) - vectors = v.vectors.numpy() - - # The first 5 entries in each vector. - expected_fasttext_simple_en = { - 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], - 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], - } - - for word in expected_fasttext_simple_en: - assert_allclose(vectors[v.stoi[word], :5], - expected_fasttext_simple_en[word]) - - assert_allclose(vectors[v.stoi['']], np.zeros(300)) - assert_allclose(vectors[v.stoi['OOV token']], np.zeros(300)) - # Delete the vectors after we're done to save disk space on CI - if os.environ.get("TRAVIS") == "true": - vec_file = os.path.join(self.project_root, ".vector_cache", "wiki.simple.vec") - conditional_remove(vec_file) - - @slow - def test_vocab_extend(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - # Build a vocab and get vectors twice to test caching. - for _ in range(2): - f = FastText(language='simple') - v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors=f) - n_vocab = len(v) - v.extend(f) # extend the vocab with the words contained in f.itos - self.assertGreater(len(v), n_vocab) - - self.assertEqual(v.itos[:6], ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) - vectors = v.vectors.numpy() - - # The first 5 entries in each vector. - expected_fasttext_simple_en = { - 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], - 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], - } - - for word in expected_fasttext_simple_en: - assert_allclose(vectors[v.stoi[word], :5], - expected_fasttext_simple_en[word]) - - assert_allclose(vectors[v.stoi['']], np.zeros(300)) - # Delete the vectors after we're done to save disk space on CI - if os.environ.get("TRAVIS") == "true": - vec_file = os.path.join(self.project_root, ".vector_cache", "wiki.simple.vec") - conditional_remove(vec_file) - - @slow - def test_vocab_download_custom_vectors(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - # Build a vocab and get vectors twice to test caching. - for _ in range(2): - v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors=Vectors('wiki.simple.vec', - url=FastText.url_base.format('simple'))) - - self.assertEqual(v.itos, ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) - vectors = v.vectors.numpy() - - # The first 5 entries in each vector. - expected_fasttext_simple_en = { - 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], - 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], - } - - for word in expected_fasttext_simple_en: - assert_allclose(vectors[v.stoi[word], :5], - expected_fasttext_simple_en[word]) - - assert_allclose(vectors[v.stoi['']], np.zeros(300)) - # Delete the vectors after we're done to save disk space on CI - if os.environ.get("TRAVIS") == "true": - vec_file = os.path.join(self.project_root, ".vector_cache", "wiki.simple.vec") - conditional_remove(vec_file) - - @slow - def test_vocab_vectors_custom_cache(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - vector_cache = os.path.join('/tmp', 'vector_cache') - # Build a vocab and get vectors twice to test caching. - for i in range(2): - if i == 1: - self.assertTrue(os.path.exists(vector_cache)) - - v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors=Vectors('wiki.simple.vec', cache=vector_cache, - url=FastText.url_base.format('simple'))) - - self.assertEqual(v.itos, ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) - vectors = v.vectors.numpy() - - # The first 5 entries in each vector. - expected_fasttext_simple_en = { - 'hello': [0.39567, 0.21454, -0.035389, -0.24299, -0.095645], - 'world': [0.10444, -0.10858, 0.27212, 0.13299, -0.33165], - } - - for word in expected_fasttext_simple_en: - assert_allclose(vectors[v.stoi[word], :5], - expected_fasttext_simple_en[word]) - - assert_allclose(vectors[v.stoi['']], np.zeros(300)) - # Delete the vectors after we're done to save disk space on CI - if os.environ.get("TRAVIS") == "true": - vec_file = os.path.join(vector_cache, "wiki.simple.vec") - conditional_remove(vec_file) - - @slow - def test_vocab_download_glove_vectors(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - - # Build a vocab and get vectors twice to test caching, then once more - # to test string aliases. - for i in range(3): - if i == 2: - vectors = "glove.twitter.27B.25d" - else: - vectors = GloVe(name='twitter.27B', dim='25') - v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors=vectors) - - expected_itos = ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.itos, expected_itos) - self.assertEqual(dict(v.stoi), expected_stoi) - - vectors = v.vectors.numpy() - - # The first 5 entries in each vector. - expected_twitter = { - 'hello': [-0.77069, 0.12827, 0.33137, 0.0050893, -0.47605], - 'world': [0.10301, 0.095666, -0.14789, -0.22383, -0.14775], - } - - for word in expected_twitter: - assert_allclose(vectors[v.stoi[word], :5], - expected_twitter[word]) - - assert_allclose(vectors[v.stoi['']], np.zeros(25)) - assert_allclose(vectors[v.stoi['OOV token']], np.zeros(25)) - # Delete the vectors after we're done to save disk space on CI - if os.environ.get("TRAVIS") == "true": - zip_file = os.path.join(self.project_root, ".vector_cache", - "glove.twitter.27B.zip") - conditional_remove(zip_file) - for dim in ["25", "50", "100", "200"]: - conditional_remove(os.path.join(self.project_root, ".vector_cache", - "glove.twitter.27B.{}d.txt".format(dim))) - - @slow - def test_vocab_download_charngram_vectors(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - # Build a vocab and get vectors twice to test caching, then once more - # to test string aliases. - for i in range(3): - if i == 2: - vectors = "charngram.100d" - else: - vectors = CharNGram() - v = vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors=vectors) - expected_itos = ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.itos, expected_itos) - self.assertEqual(dict(v.stoi), expected_stoi) - vectors = v.vectors.numpy() - - # The first 5 entries in each vector. - expected_charngram = { - 'hello': [-0.44782442, -0.08937783, -0.34227219, - -0.16233221, -0.39343098], - 'world': [-0.29590717, -0.05275926, -0.37334684, 0.27117205, -0.3868292], - } - - for word in expected_charngram: - assert_allclose(vectors[v.stoi[word], :5], - expected_charngram[word]) - - assert_allclose(vectors[v.stoi['']], np.zeros(100)) - assert_allclose(vectors[v.stoi['OOV token']], np.zeros(100)) - # Delete the vectors after we're done to save disk space on CI - if os.environ.get("TRAVIS") == "true": - conditional_remove( - os.path.join(self.project_root, ".vector_cache", "charNgram.txt")) - conditional_remove( - os.path.join(self.project_root, ".vector_cache", - "jmt_pre-trained_embeddings.tar.gz")) - def test_errors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) with self.assertRaises(ValueError): @@ -343,32 +126,6 @@ def test_serialization_backcompat(self): v_loaded = pickle.load(open(pickle_path, "rb")) assert v == v_loaded - @slow - def test_vectors_get_vecs(self): - vec = GloVe(name='twitter.27B', dim='25') - self.assertEqual(vec.vectors.shape[0], len(vec)) - - tokens = ['chip', 'baby', 'Beautiful'] - token_vecs = vec.get_vecs_by_tokens(tokens).numpy() - self.assertEqual(token_vecs.shape[0], len(tokens)) - self.assertEqual(token_vecs.shape[1], vec.dim) - assert_allclose(vec[tokens[0]].numpy(), token_vecs[0]) - assert_allclose(vec[tokens[1]].numpy(), token_vecs[1]) - assert_allclose(vec[''].numpy(), token_vecs[2]) - - token_one_vec = vec.get_vecs_by_tokens(tokens[0], lower_case_backup=True).numpy() - self.assertEqual(token_one_vec.shape[0], vec.dim) - assert_allclose(vec[tokens[0].lower()].numpy(), token_one_vec) - - # Delete the vectors after we're done to save disk space on CI - if os.environ.get("TRAVIS") == "true": - zip_file = os.path.join(self.project_root, ".vector_cache", - "glove.6B.zip") - conditional_remove(zip_file) - for dim in ["50", "100", "200", "300"]: - conditional_remove(os.path.join(self.project_root, ".vector_cache", - "glove.6B.{}d.txt".format(dim))) - def test_has_unk(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) v = vocab.Vocab(c) diff --git a/torchtext/__init__.py b/torchtext/__init__.py index db4484fdf1..c19fa01ec8 100644 --- a/torchtext/__init__.py +++ b/torchtext/__init__.py @@ -4,10 +4,40 @@ from . import vocab from . import experimental -__version__ = '0.6.0' + +try: + from .version import __version__, git_version # noqa: F401 +except ImportError: + pass __all__ = ['data', 'datasets', 'utils', 'vocab', 'experimental'] + + +def _init_extension(): + import os + import importlib + import torch + + # load the custom_op_library and register the custom ops + lib_dir = os.path.dirname(__file__) + loader_details = ( + importlib.machinery.ExtensionFileLoader, + importlib.machinery.EXTENSION_SUFFIXES + ) + + extfinder = importlib.machinery.FileFinder(lib_dir, loader_details) + ext_specs = extfinder.find_spec("_torchtext") + if ext_specs is None: + raise ImportError + torch.ops.load_library(ext_specs.origin) + torch.classes.load_library(ext_specs.origin) + + +_init_extension() + + +del _init_extension diff --git a/torchtext/csrc/sentencepiece.cpp b/torchtext/csrc/sentencepiece.cpp new file mode 100644 index 0000000000..06237b5d32 --- /dev/null +++ b/torchtext/csrc/sentencepiece.cpp @@ -0,0 +1,104 @@ +#include +#include +#include + +#ifdef _WIN32 +#include +PyMODINIT_FUNC PyInit__torchtext(void) { + // No need to do anything. + // extension.py will run on load + return NULL; +} +#endif + +namespace torchtext { +namespace { + +struct SentencePiece : torch::CustomClassHolder { +private: + sentencepiece::SentencePieceProcessor processor_; + +public: + // content_ holds the serialized model data passed at the initialization. + // We need this because the underlying SentencePieceProcessor class does not + // provide serialization mechanism, yet we still need to be able to serialize + // the model so that we can save the scripted object. pickle will get the + // serialized model from this content_ member, thus it needs to be public. + const std::string content_; + + explicit SentencePiece(const std::string &content) : content_(content) { + const auto status = processor_.LoadFromSerializedProto(content_); + if (!status.ok()) { + throw std::runtime_error("Failed to load SentencePiece model. Error: " + + status.ToString()); + } + } + + std::vector Encode(const std::string &input) const { + std::vector pieces; + processor_.Encode(input, &pieces); + return pieces; + } + + std::vector EncodeAsIds(const std::string &input) const { + const auto val = processor_.EncodeAsIds(input); + return std::vector(val.begin(), val.end()); + } + + std::vector EncodeAsPieces(const std::string &input) const { + return processor_.EncodeAsPieces(input); + } + + int64_t GetPieceSize() const { return processor_.GetPieceSize(); } +}; + +// Registers our custom class with torch. +static auto sentencepiece = + torch::class_("torchtext", "SentencePiece") + .def("Encode", &SentencePiece::Encode) + .def("EncodeAsIds", &SentencePiece::EncodeAsIds) + .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) + .def("GetPieceSize", &SentencePiece::GetPieceSize) + .def_pickle( + // __setstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return self->content_; + }, + // __getstate__ + [](std::string state) -> c10::intrusive_ptr { + return c10::make_intrusive(std::move(state)); + }); + +void generate_sp_model(const std::string &filename, const int64_t &vocab_size, + const std::string &model_type, + const std::string &model_prefix) { + const auto status = ::sentencepiece::SentencePieceTrainer::Train( + "--input=" + filename + " --model_prefix=" + model_prefix + + " --vocab_size=" + std::to_string(vocab_size) + + " --model_type=" + model_type); + if (!status.ok()) { + throw std::runtime_error("Failed to train SentencePiece model. Error: " + + status.ToString()); + } +} + +c10::intrusive_ptr load_sp_model(const std::string &path) { + std::ifstream file(path, std::ios::binary | std::ios::in); + if (!file) { + throw std::runtime_error("Failed to open file :" + path); + } + std::string content((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + return c10::make_intrusive(std::move(content)); +} + +static auto registry = + torch::RegisterOperators() + .op("torchtext::generate_sp_model", &generate_sp_model) + .op(torch::RegisterOperators::options() + .schema("torchtext::load_sp_model(str path) -> " + "__torch__.torch.classes.torchtext.SentencePiece model") + .catchAllKernel()); + +} // namespace +} // namespace torchtext diff --git a/torchtext/data/functional.py b/torchtext/data/functional.py index e1ef55da79..a1d7a3b41e 100644 --- a/torchtext/data/functional.py +++ b/torchtext/data/functional.py @@ -1,5 +1,8 @@ import re +import torch + + __all__ = [ "generate_sp_model", "load_sp_model", "sentencepiece_numericalizer", "sentencepiece_tokenizer", @@ -33,19 +36,7 @@ def generate_sp_model(filename, vocab_size=20000, >>> from torchtext.data.functional import generate_sp_model >>> generate_sp_model('test.csv', vocab_size=23456, model_prefix='spm_user') """ - try: - import sentencepiece as spm - except ModuleNotFoundError: - raise ImportWarning("Please install sentencepiece") - spm_training_string = "--input={} \ - --vocab_size={} \ - --model_prefix={} \ - --model_type={}".format(filename, - vocab_size, - model_prefix, - model_type) - spm.SentencePieceTrainer.train(spm_training_string) - return None + torch.ops.torchtext.generate_sp_model(filename, vocab_size, model_type, model_prefix) def load_sp_model(spm_path): @@ -61,13 +52,7 @@ def load_sp_model(spm_path): >>> from torchtext.data.functional import load_sp_model >>> sp_model = load_sp_model("m_user.model") """ - try: - import sentencepiece as spm - except ModuleNotFoundError: - raise ImportWarning("Please install sentencepiece") - sp_model = spm.SentencePieceProcessor() - sp_model.Load(spm_path) - return sp_model + return torch.ops.torchtext.load_sp_model(spm_path) def sentencepiece_numericalizer(sp_model): diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py index 9546cb9dac..c76a7335ff 100644 --- a/torchtext/data/iterator.py +++ b/torchtext/data/iterator.py @@ -3,6 +3,7 @@ import logging +import torch from .utils import RandomShuffler from .batch import Batch from .dataset import Dataset @@ -65,6 +66,12 @@ def __init__(self, dataset, batch_size, sort_key=None, device=None, + " or passing a string as an argument. This behavior will be" + " deprecated soon and currently defaults to cpu.") device = None + + if device is None: + device = torch.device('cpu') + elif isinstance(device, str): + device = torch.device(device) + self.device = device self.random_shuffler = RandomShuffler() diff --git a/torchtext/data/utils.py b/torchtext/data/utils.py index eb056679e9..5ecfad1958 100644 --- a/torchtext/data/utils.py +++ b/torchtext/data/utils.py @@ -6,7 +6,7 @@ from functools import partial -def _split_tokenizer(x): # noqa: F821 +def _split_tokenizer(x): # noqa: F821 # type: (str) -> List[str] return x.split() diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py index 402c853a68..d48cb6c812 100644 --- a/torchtext/experimental/datasets/raw/text_classification.py +++ b/torchtext/experimental/datasets/raw/text_classification.py @@ -1,7 +1,6 @@ import torch import io from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -import sys URLS = { 'AG_NEWS': diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index df879ea557..a600bfe340 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -1,45 +1,22 @@ import torch from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets import raw +from torchtext.experimental.datasets.raw import text_classification as raw +from torchtext.experimental.functional import ( + vocab_func, + totensor, + ngrams_func, + sequential_transforms, +) -def vocab_func(vocab): - def _forward(tok_iter): - return [vocab[tok] for tok in tok_iter] - return _forward - - -def totensor(dtype): - def _forward(ids_list): - return torch.tensor(ids_list).to(dtype) - return _forward - - -def ngrams_func(ngrams): - def _forward(token_list): - _token_list = [] - for _i in range(ngrams + 1): - _token_list += zip(*[token_list[i:] for i in range(_i)]) - return [' '.join(x) for x in _token_list] - return _forward - - -def build_vocab(data, transforms): +def _build_vocab(data, transforms): tok_list = [] for _, txt in data: tok_list.append(transforms(txt)) return build_vocab_from_iterator(tok_list) -def squential_transforms(*transforms): - def _forward(txt_input): - for transform in transforms: - txt_input = transform(txt_input) - return txt_input - return _forward - - class TextClassificationDataset(torch.utils.data.Dataset): """Defines an abstract text classification datasets. Currently, we only support the following datasets: @@ -87,32 +64,44 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, root='.data', ngrams=1, vocab=None, - tokenizer=None, data_select=('train', 'test')): +def _setup_datasets( + dataset_name, + root=".data", + ngrams=1, + vocab=None, + tokenizer=None, + data_select=("train", "test"), +): text_transform = [] if tokenizer is None: - tokenizer = get_tokenizer('basic_english') - text_transform = squential_transforms(tokenizer, ngrams_func(ngrams)) + tokenizer = get_tokenizer("basic_english") + text_transform = sequential_transforms(tokenizer, ngrams_func(ngrams)) if isinstance(data_select, str): data_select = [data_select] - if not set(data_select).issubset(set(('train', 'test'))): - raise TypeError('Given data selection {} is not supported!'.format(data_select)) - train, test = DATASETS[dataset_name](root=root) + if not set(data_select).issubset(set(("train", "test"))): + raise TypeError("Given data selection {} is not supported!".format(data_select)) + train, test = raw.DATASETS[dataset_name](root=root) # Cache raw text iterable dataset - raw_data = {'train': [(label, txt) for (label, txt) in train], - 'test': [(label, txt) for (label, txt) in test]} + raw_data = { + "train": [(label, txt) for (label, txt) in train], + "test": [(label, txt) for (label, txt) in test], + } if vocab is None: - if 'train' not in data_select: + if "train" not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - vocab = build_vocab(raw_data['train'], text_transform) - text_transform = squential_transforms(text_transform, vocab_func(vocab), - totensor(dtype=torch.long)) - label_transform = squential_transforms(totensor(dtype=torch.long)) - return tuple(TextClassificationDataset(raw_data[item], vocab, - (label_transform, text_transform)) - for item in data_select) + vocab = _build_vocab(raw_data["train"], text_transform) + text_transform = sequential_transforms( + text_transform, vocab_func(vocab), totensor(dtype=torch.long) + ) + label_transform = sequential_transforms(totensor(dtype=torch.long)) + return tuple( + TextClassificationDataset( + raw_data[item], vocab, (label_transform, text_transform) + ) + for item in data_select + ) def AG_NEWS(*args, **kwargs): @@ -155,7 +144,7 @@ def AG_NEWS(*args, **kwargs): """ - return _setup_datasets(*(('AG_NEWS',) + args), **kwargs) + return _setup_datasets(*(("AG_NEWS",) + args), **kwargs) def SogouNews(*args, **kwargs): @@ -509,66 +498,70 @@ def IMDB(*args, **kwargs): DATASETS = { - 'AG_NEWS': raw.AG_NEWS, - 'SogouNews': raw.SogouNews, - 'DBpedia': raw.DBpedia, - 'YelpReviewPolarity': raw.YelpReviewPolarity, - 'YelpReviewFull': raw.YelpReviewFull, - 'YahooAnswers': raw.YahooAnswers, - 'AmazonReviewPolarity': raw.AmazonReviewPolarity, - 'AmazonReviewFull': raw.AmazonReviewFull, - 'IMDB': raw.IMDB + "AG_NEWS": AG_NEWS, + "SogouNews": SogouNews, + "DBpedia": DBpedia, + "YelpReviewPolarity": YelpReviewPolarity, + "YelpReviewFull": YelpReviewFull, + "YahooAnswers": YahooAnswers, + "AmazonReviewPolarity": AmazonReviewPolarity, + "AmazonReviewFull": AmazonReviewFull, + "IMDB": IMDB, } LABELS = { - 'AG_NEWS': {1: 'World', - 2: 'Sports', - 3: 'Business', - 4: 'Sci/Tech'}, - 'SogouNews': {1: 'Sports', - 2: 'Finance', - 3: 'Entertainment', - 4: 'Automobile', - 5: 'Technology'}, - 'DBpedia': {1: 'Company', - 2: 'EducationalInstitution', - 3: 'Artist', - 4: 'Athlete', - 5: 'OfficeHolder', - 6: 'MeanOfTransportation', - 7: 'Building', - 8: 'NaturalPlace', - 9: 'Village', - 10: 'Animal', - 11: 'Plant', - 12: 'Album', - 13: 'Film', - 14: 'WrittenWork'}, - 'YelpReviewPolarity': {1: 'Negative polarity', - 2: 'Positive polarity'}, - 'YelpReviewFull': {1: 'score 1', - 2: 'score 2', - 3: 'score 3', - 4: 'score 4', - 5: 'score 5'}, - 'YahooAnswers': {1: 'Society & Culture', - 2: 'Science & Mathematics', - 3: 'Health', - 4: 'Education & Reference', - 5: 'Computers & Internet', - 6: 'Sports', - 7: 'Business & Finance', - 8: 'Entertainment & Music', - 9: 'Family & Relationships', - 10: 'Politics & Government'}, - 'AmazonReviewPolarity': {1: 'Negative polarity', - 2: 'Positive polarity'}, - 'AmazonReviewFull': {1: 'score 1', - 2: 'score 2', - 3: 'score 3', - 4: 'score 4', - 5: 'score 5'}, - 'IMDB': {0: 'Negative', - 1: 'Positive'} + "AG_NEWS": {1: "World", 2: "Sports", 3: "Business", 4: "Sci/Tech"}, + "SogouNews": { + 1: "Sports", + 2: "Finance", + 3: "Entertainment", + 4: "Automobile", + 5: "Technology", + }, + "DBpedia": { + 1: "Company", + 2: "EducationalInstitution", + 3: "Artist", + 4: "Athlete", + 5: "OfficeHolder", + 6: "MeanOfTransportation", + 7: "Building", + 8: "NaturalPlace", + 9: "Village", + 10: "Animal", + 11: "Plant", + 12: "Album", + 13: "Film", + 14: "WrittenWork", + }, + "YelpReviewPolarity": {1: "Negative polarity", 2: "Positive polarity"}, + "YelpReviewFull": { + 1: "score 1", + 2: "score 2", + 3: "score 3", + 4: "score 4", + 5: "score 5", + }, + "YahooAnswers": { + 1: "Society & Culture", + 2: "Science & Mathematics", + 3: "Health", + 4: "Education & Reference", + 5: "Computers & Internet", + 6: "Sports", + 7: "Business & Finance", + 8: "Entertainment & Music", + 9: "Family & Relationships", + 10: "Politics & Government", + }, + "AmazonReviewPolarity": {1: "Negative polarity", 2: "Positive polarity"}, + "AmazonReviewFull": { + 1: "score 1", + 2: "score 2", + 3: "score 3", + 4: "score 4", + 5: "score 5", + }, + "IMDB": {0: "Negative", 1: "Positive"}, } diff --git a/torchtext/experimental/functional.py b/torchtext/experimental/functional.py new file mode 100644 index 0000000000..2c9ac60541 --- /dev/null +++ b/torchtext/experimental/functional.py @@ -0,0 +1,34 @@ +import torch + + +def vocab_func(vocab): + def _forward(tok_iter): + return [vocab[tok] for tok in tok_iter] + + return _forward + + +def totensor(dtype): + def _forward(ids_list): + return torch.tensor(ids_list).to(dtype) + + return _forward + + +def ngrams_func(ngrams): + def _forward(token_list): + _token_list = [] + for _i in range(ngrams + 1): + _token_list += zip(*[token_list[i:] for i in range(_i)]) + return [" ".join(x) for x in _token_list] + + return _forward + + +def sequential_transforms(*transforms): + def _forward(txt_input): + for transform in transforms: + txt_input = transform(txt_input) + return txt_input + + return _forward From b79875bca3e7354fef31fb86baba1d49d895e7d9 Mon Sep 17 00:00:00 2001 From: Moto Hira Date: Thu, 28 May 2020 12:24:44 -0700 Subject: [PATCH 09/68] Import torchtext 20200528 Summary: Import up to #798 Addresses T67599333 Reviewed By: zhangguanheng66 Differential Revision: D21764935 fbshipit-source-id: f44d1db637799f2e95f420a8099fbf19545c7cbd --- packaging/build_wheel.bat | 2 ++ test/common/assets.py | 30 +++--------------------- test/data/test_functional.py | 45 +++++++++++++++++++----------------- torchtext/__init__.py | 2 +- 4 files changed, 30 insertions(+), 49 deletions(-) diff --git a/packaging/build_wheel.bat b/packaging/build_wheel.bat index 90bd865361..d9ba42ad04 100644 --- a/packaging/build_wheel.bat +++ b/packaging/build_wheel.bat @@ -17,4 +17,6 @@ if "%VSDEVCMD_ARGS%" == "" ( @echo on +set DISTUTILS_USE_SDK=1 + python setup.py bdist_wheel || exit /b 1 diff --git a/test/common/assets.py b/test/common/assets.py index c7523bb619..f863640c0c 100644 --- a/test/common/assets.py +++ b/test/common/assets.py @@ -1,32 +1,8 @@ -import os -import shutil -import atexit -import tempfile from pathlib import Path _ASSET_DIR = (Path(__file__).parent.parent / "asset").resolve() -_TEMP_DIR = None - -def _init_temp_dir(): - """Initialize temporary directory and register clean up at the end of test.""" - global _TEMP_DIR - _TEMP_DIR = tempfile.TemporaryDirectory() # noqa - atexit.register(_TEMP_DIR.cleanup) - - -def get_asset_path(*path_components, use_temp_dir=False): - """Get the path to the file under `test/assets` directory. - When `use_temp_dir` is True, the asset is copied to a temporary location and - path to the temporary file is returned. - """ - path = str(_ASSET_DIR.joinpath(*path_components)) - if not use_temp_dir: - return path - - if _TEMP_DIR is None: - _init_temp_dir() - tgt = os.path.join(_TEMP_DIR.name, path_components[-1]) - shutil.copy(path, tgt) - return tgt +def get_asset_path(*path_components): + """Get the path to the file under `test/assets` directory.""" + return str(_ASSET_DIR.joinpath(*path_components)) diff --git a/test/data/test_functional.py b/test/data/test_functional.py index dacc0adafd..ff5b12ab17 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -1,6 +1,8 @@ import os import unittest import sys +import uuid +import shutil import tempfile import sentencepiece as spm @@ -20,27 +22,28 @@ class TestFunctional(TorchtextTestCase): def test_generate_sp_model(self): - # Test the function to train a sentencepiece tokenizer - - # buck (fb internal) generates test environment which contains ',' in its path. - # SentencePieceTrainer considers such path as comma-delimited file list. - # So as workaround we copy the asset data to temporary directory and load it from there. - data_path = get_asset_path( - 'text_normalization_ag_news_test.csv', - use_temp_dir=True) - generate_sp_model(data_path, - vocab_size=23456, - model_prefix='spm_user') - - sp_user = spm.SentencePieceProcessor() - sp_user.Load('spm_user.model') - - self.assertEqual(len(sp_user), 23456) - - if os.path.isfile('spm_user.model'): - os.remove('spm_user.model') - if os.path.isfile('spm_user.vocab'): - os.remove('spm_user.vocab') + """Test the function to train a sentencepiece tokenizer""" + + asset_name = 'text_normalization_ag_news_test.csv' + asset_path = get_asset_path(asset_name) + # We use temporary directory for two reasons: + # 1. buck (fb internal) generates test environment which contains ',' in its path. + # SentencePieceTrainer considers such path as comma-delimited file list. + # So as workaround we copy the asset data to temporary directory and load it from there. + # 2. when fb infra performs stress tests, multiple instances of this test run. + # The name of the generated models have to be unique and they need to be cleaned up. + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + + model_prefix = os.path.join(dir_name, f'spm_user_{uuid.uuid4()}') + model_file = f'{model_prefix}.model' + generate_sp_model(data_path, vocab_size=23456, model_prefix=model_prefix) + + sp_user = spm.SentencePieceProcessor() + sp_user.Load(model_file) + + self.assertEqual(len(sp_user), 23456) def test_sentencepiece_numericalizer(self): test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' diff --git a/torchtext/__init__.py b/torchtext/__init__.py index c19fa01ec8..97191542ec 100644 --- a/torchtext/__init__.py +++ b/torchtext/__init__.py @@ -32,7 +32,7 @@ def _init_extension(): extfinder = importlib.machinery.FileFinder(lib_dir, loader_details) ext_specs = extfinder.find_spec("_torchtext") if ext_specs is None: - raise ImportError + raise ImportError("torchtext C++ Extension is not found.") torch.ops.load_library(ext_specs.origin) torch.classes.load_library(ext_specs.origin) From be0f74955b614843342ff955d9060faf0b204832 Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Thu, 4 Jun 2020 19:24:00 -0700 Subject: [PATCH 10/68] 20200604 torchtext github import Summary: Import from github master Reviewed By: zhangguanheng66 Differential Revision: D21886238 fbshipit-source-id: a8f098e299466dd1701fe7ceb6a97c2a2fc54b9d --- packaging/build_wheel.sh | 2 +- .../{build_wheel.bat => vc_env_helper.bat} | 21 +++++++++++++++++-- torchtext/utils.py | 8 ++++--- 3 files changed, 25 insertions(+), 6 deletions(-) rename packaging/{build_wheel.bat => vc_env_helper.bat} (59%) diff --git a/packaging/build_wheel.sh b/packaging/build_wheel.sh index 1bfa107ff2..064622c801 100755 --- a/packaging/build_wheel.sh +++ b/packaging/build_wheel.sh @@ -13,7 +13,7 @@ setup_pip_pytorch_version git submodule update --init --recursive python setup.py clean if [[ "$OSTYPE" == "msys" ]]; then - "$script_dir/build_wheel.bat" + "$script_dir/vc_env_helper.bat" python setup.py bdist_wheel else python setup.py bdist_wheel fi diff --git a/packaging/build_wheel.bat b/packaging/vc_env_helper.bat similarity index 59% rename from packaging/build_wheel.bat rename to packaging/vc_env_helper.bat index d9ba42ad04..9410135677 100644 --- a/packaging/build_wheel.bat +++ b/packaging/vc_env_helper.bat @@ -1,6 +1,9 @@ @echo on -for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -legacy -products * -version [15^,17^) -property installationPath`) do ( +set VC_VERSION_LOWER=16 +set VC_VERSION_UPPER=17 + +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -legacy -products * -version [%VC_VERSION_LOWER%^,%VC_VERSION_UPPER%^) -property installationPath`) do ( if exist "%%i" if exist "%%i\VC\Auxiliary\Build\vcvarsall.bat" ( set "VS15INSTALLDIR=%%i" set "VS15VCVARSALL=%%i\VC\Auxiliary\Build\vcvarsall.bat" @@ -19,4 +22,18 @@ if "%VSDEVCMD_ARGS%" == "" ( set DISTUTILS_USE_SDK=1 -python setup.py bdist_wheel || exit /b 1 +set args=%1 +shift +:start +if [%1] == [] goto done +set args=%args% %1 +shift +goto start + +:done +if "%args%" == "" ( + echo Usage: vc_env_helper.bat [command] [args] + echo e.g. vc_env_helper.bat cl /c test.cpp +) + +%args% || exit /b 1 diff --git a/torchtext/utils.py b/torchtext/utils.py index 45f242f84b..41ac14ecbb 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -78,9 +78,11 @@ def _process_response(r, root, filename): root, filename = os.path.split(path) if not os.path.exists(root): - raise RuntimeError( - "Download directory {} does not exist. " - "Did you create it?".format(root)) + try: + os.makedirs(root) + except OSError: + print("Can't create the download directory {}.".format(root)) + raise if 'drive.google.com' not in url: response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'}, stream=True) From 4fd0fe23a52e8ef62d8dd932e1850aabd9b04ca5 Mon Sep 17 00:00:00 2001 From: Nayef Ahmed Date: Mon, 8 Jun 2020 14:25:49 -0700 Subject: [PATCH 11/68] Import torchtext 20200605 Summary: Import from github master Reviewed By: zhangguanheng66 Differential Revision: D21907519 fbshipit-source-id: f22370d97796da5f2cb9f76f506c80f18fefea7f --- .travis.yml | 23 - docs/source/experimental_datasets.rst | 48 +- docs/source/experimental_transforms.rst | 22 + docs/source/index.rst | 2 + test/data/test_builtin_datasets.py | 44 +- test/data/test_functional.py | 104 +++- test/test_utils.py | 28 + torchtext/csrc/regex.cpp | 44 ++ torchtext/experimental/datasets/__init__.py | 3 +- .../datasets/language_modeling.py | 191 +++--- .../experimental/datasets/raw/__init__.py | 11 +- .../datasets/raw/language_modeling.py | 184 ++++++ .../experimental/datasets/raw/translation.py | 544 +++++++++++++++++ .../experimental/datasets/translation.py | 551 ++++++++++++++++++ torchtext/experimental/transforms.py | 114 ++++ torchtext/utils.py | 18 +- 16 files changed, 1795 insertions(+), 136 deletions(-) delete mode 100644 .travis.yml create mode 100644 docs/source/experimental_transforms.rst create mode 100644 torchtext/csrc/regex.cpp create mode 100644 torchtext/experimental/datasets/raw/language_modeling.py create mode 100644 torchtext/experimental/datasets/raw/translation.py create mode 100644 torchtext/experimental/datasets/translation.py create mode 100644 torchtext/experimental/transforms.py diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 83f69ea383..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -dist: trusty - -language: python - -cache: - directories: - - /home/travis/download - - /home/travis/.cache/pip - -# This matrix tests that the code works on Python 3.5, -# 3.6 (same versions as PyTorch CI), and passes lint. -matrix: - fast_finish: true - include: - - env: PYTHON_VERSION="3.6" RUN_FLAKE8="true" SKIP_TESTS="true" - sudo: required - -notifications: - email: false - -install: source build_tools/travis/install.sh -script: bash build_tools/travis/test_script.sh -after_success: source build_tools/travis/after_success.sh diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index d9d59539d0..e9debd8224 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -1,5 +1,5 @@ torchtext.experimental.datasets -================================ +=============================== .. currentmodule:: torchtext.experimental.datasets @@ -41,13 +41,13 @@ Text Classification ^^^^^^^^^^^^^^^^^^^ TextClassificationDataset -~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: TextClassificationDataset :members: __init__ AG_NEWS -~~~~~~ +~~~~~~~ AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. @@ -55,7 +55,7 @@ AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ SogouNews -~~~~~~~~ +~~~~~~~~~ SogouNews dataset is subclass of ``TextClassificationDataset`` class. @@ -63,7 +63,7 @@ SogouNews dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ DBpedia -~~~~~~ +~~~~~~~ DBpedia dataset is subclass of ``TextClassificationDataset`` class. @@ -71,7 +71,7 @@ DBpedia dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YelpReviewPolarity -~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~ YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. @@ -79,7 +79,7 @@ YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YelpReviewFull -~~~~~~~~~~~~~ +~~~~~~~~~~~~~~ YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. @@ -87,7 +87,7 @@ YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YahooAnswers -~~~~~~~~~~~ +~~~~~~~~~~~~ YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. @@ -95,7 +95,7 @@ YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ AmazonReviewPolarity -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. @@ -103,7 +103,7 @@ AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ AmazonReviewFull -~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~ AmazonReviewFull dataset is subclass of ``TextClassificationDataset`` class. @@ -139,3 +139,31 @@ PennTreebank .. autoclass:: PennTreebank :members: __init__ + + +Machine Translation +^^^^^^^^^^^^^^^^^^^ + +Language modeling datasets are subclasses of ``TranslationDataset`` class. + +.. autoclass:: TranslationDataset + :members: __init__ + +Multi30k +~~~~~~~~ + +.. autoclass:: Multi30k + :members: __init__ + +IWSLT +~~~~~ + +.. autoclass:: IWSLT + :members: __init__ + +WMT14 +~~~~~ + +.. autoclass:: WMT14 + :members: __init__ + diff --git a/docs/source/experimental_transforms.rst b/docs/source/experimental_transforms.rst new file mode 100644 index 0000000000..ff00b374ef --- /dev/null +++ b/docs/source/experimental_transforms.rst @@ -0,0 +1,22 @@ +.. role:: hidden + :class: hidden-section + +torchtext.experimental.transforms +================================= + +.. automodule:: torchtext.experimental.transforms +.. currentmodule:: torchtext.experimental.transforms + +:hidden:`BasicEnglishNormalize` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: BasicEnglishNormalize + :members: + :special-members: __init__ + +:hidden:`RegexTokenizer` +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: RegexTokenizer + :members: + :special-members: __init__ \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 08fb745c4f..dfa9d7c4c0 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -17,6 +17,8 @@ popular datasets for natural language. torchtext.vocab torchtext.utils experimental_datasets + experimental_functional + experimental_transforms examples .. automodule:: torchtext diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 08c75292c4..2bb4065df9 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -1,6 +1,7 @@ #!/user/bin/env python3 # Note that all the tests in this module require dataset (either network access or cached) import os +import glob import shutil import torchtext.data as data from torchtext.datasets import AG_NEWS @@ -10,10 +11,11 @@ def conditional_remove(f): - if os.path.isfile(f): - os.remove(f) - elif os.path.isdir(f): - shutil.rmtree(f) + for path in glob.glob(f): + if os.path.isfile(path): + os.remove(path) + elif os.path.isdir(path): + shutil.rmtree(path) class TestDataset(TorchtextTestCase): @@ -78,7 +80,7 @@ def test_penntreebank_legacy(self): def test_penntreebank(self): from torchtext.experimental.datasets import PennTreebank - # smoke test to ensure wikitext2 works properly + # smoke test to ensure penn treebank works properly train_dataset, test_dataset, valid_dataset = PennTreebank() self.assertEqual(len(train_dataset), 924412) self.assertEqual(len(test_dataset), 82114) @@ -122,3 +124,35 @@ def test_imdb(self): old_vocab = train_dataset.get_vocab() new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) new_train_data, new_test_data = IMDB(vocab=new_vocab) + + def test_multi30k(self): + from torchtext.experimental.datasets.translation import Multi30k + # smoke test to ensure multi30k works properly + train_dataset, valid_dataset, test_dataset = Multi30k() + self.assertEqual(len(train_dataset), 29000) + self.assertEqual(len(valid_dataset), 1000) + self.assertEqual(len(test_dataset), 1014) + + de_vocab, en_vocab = train_dataset.get_vocab() + de_tokens_ids = [ + de_vocab[token] for token in + 'Zwei Männer verpacken Donuts in Kunststofffolie'.split() + ] + self.assertEqual(de_tokens_ids, [19, 29, 18703, 4448, 5, 6240]) + + en_tokens_ids = [ + en_vocab[token] for token in + 'Two young White males are outside near many bushes'.split() + ] + self.assertEqual(en_tokens_ids, + [17, 23, 1167, 806, 15, 55, 82, 334, 1337]) + + datafile = os.path.join(self.project_root, ".data", "train*") + conditional_remove(datafile) + datafile = os.path.join(self.project_root, ".data", "val*") + conditional_remove(datafile) + datafile = os.path.join(self.project_root, ".data", "test*") + conditional_remove(datafile) + datafile = os.path.join(self.project_root, ".data", + "multi30k_task*.tar.gz") + conditional_remove(datafile) diff --git a/test/data/test_functional.py b/test/data/test_functional.py index ff5b12ab17..9b93580f72 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -1,12 +1,12 @@ import os -import unittest -import sys import uuid import shutil +import unittest import tempfile import sentencepiece as spm import torch +import torchtext.data as data from torchtext.data.functional import ( generate_sp_model, load_sp_model, @@ -15,6 +15,10 @@ custom_replace, simple_space_split, ) +from torchtext.experimental.transforms import ( + BasicEnglishNormalize, + RegexTokenizer +) from ..common.torchtext_test_case import TorchtextTestCase from ..common.assets import get_asset_path @@ -22,7 +26,9 @@ class TestFunctional(TorchtextTestCase): def test_generate_sp_model(self): - """Test the function to train a sentencepiece tokenizer""" + """ + Test the function to train a sentencepiece tokenizer. + """ asset_name = 'text_normalization_ag_news_test.csv' asset_path = get_asset_path(asset_name) @@ -59,7 +65,6 @@ def test_sentencepiece_numericalizer(self): ref_results) def test_sentencepiece_tokenizer(self): - test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' model_path = get_asset_path('spm_example.model') sp_model = load_sp_model(model_path) @@ -74,6 +79,87 @@ def test_sentencepiece_tokenizer(self): self.assertEqual(list(spm_generator([test_sample]))[0], ref_results) + # TODO(Nayef211): uncomment and replace the test below with this once + # https://github.com/pytorch/pytorch/issues/38207 is closed + # def test_BasicEnglishNormalize(self): + # test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' + # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', + # 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] + + # basic_english_normalize = BasicEnglishNormalize() + # experimental_eager_tokens = basic_english_normalize(test_sample) + + # jit_basic_english_normalize = torch.jit.script(basic_english_normalize) + # experimental_jit_tokens = jit_basic_english_normalize(test_sample) + + # basic_english_tokenizer = data.get_tokenizer("basic_english") + # eager_tokens = basic_english_tokenizer(test_sample) + + # self.assertEqual(experimental_jit_tokens, ref_results) + # self.assertEqual(experimental_jit_tokens, eager_tokens) + # self.assertEqual(experimental_jit_tokens, experimental_eager_tokens) + + def test_BasicEnglishNormalize(self): + test_sample = 'Basic English Normalization for a Line of Text' + ref_results = ['basic', 'english', 'normalization', + 'for', 'a', 'line', 'of', 'text'] + + basic_english_normalize = BasicEnglishNormalize() + experimental_eager_tokens = basic_english_normalize(test_sample) + + basic_english_tokenizer = data.get_tokenizer("basic_english") + tokens_eager = basic_english_tokenizer(test_sample) + + self.assertEqual(experimental_eager_tokens, ref_results) + self.assertEqual(experimental_eager_tokens, tokens_eager) + + # TODO(Nayef211): uncomment and replace the test below with this once + # https://github.com/pytorch/pytorch/issues/38207 is closed + # def test_RegexTokenizer(self): + # test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' + # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', + # 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] + # patterns_list = [ + # (r'\'', ' \' '), + # (r'\"', ''), + # (r'\.', ' . '), + # (r'
', ' '), + # (r',', ' , '), + # (r'\(', ' ( '), + # (r'\)', ' ) '), + # (r'\!', ' ! '), + # (r'\?', ' ? '), + # (r'\;', ' '), + # (r'\:', ' '), + # (r'\s+', ' ')] + + # regex_tokenizer = RegexTokenizer(patterns_list) + # eager_tokens = regex_tokenizer(test_sample) + + # jit_regex_tokenizer = torch.jit.script(regex_tokenizer) + # jit_tokens = jit_regex_tokenizer(test_sample) + + # self.assertEqual(jit_tokens, ref_results) + # self.assertEqual(jit_tokens, eager_tokens) + + def test_RegexTokenizer(self): + test_sample = '"Basic Regex Tokenization". For a Line of Text' + ref_results = ['Basic', 'Regex', 'Tokenization', '.', + 'For', 'a', 'Line', 'of', 'Text'] + patterns_list = [ + (r'\"', ''), + (r'\.', ' . '), + (r'\s+', ' ')] + + regex_tokenizer = RegexTokenizer(patterns_list) + eager_tokens = regex_tokenizer(test_sample) + + jit_regex_tokenizer = torch.jit.script(regex_tokenizer) + jit_tokens = jit_regex_tokenizer(test_sample) + + self.assertEqual(jit_tokens, eager_tokens) + self.assertEqual(jit_tokens, ref_results) + def test_custom_replace(self): custom_replace_transform = custom_replace([(r'S', 's'), (r'\s+', ' ')]) test_sample = ['test cuStom replace', 'with uSer instruction'] @@ -109,11 +195,11 @@ def encode_as_pieces(self, input: str): class TestScriptableSP(unittest.TestCase): def setUp(self): model_path = get_asset_path('spm_example.model') - with tempfile.NamedTemporaryFile() as file: - torch.jit.script(ScriptableSP(model_path)).save(file.name) - self.model = torch.jit.load(file.name) + with tempfile.TemporaryDirectory() as dir_name: + jit_model_path = os.path.join(dir_name, 'spm_example.model') + torch.jit.script(ScriptableSP(model_path)).save(jit_model_path) + self.model = torch.jit.load(jit_model_path) - @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ @@ -125,7 +211,6 @@ def test_encode(self): output = self.model.encode(input) self.assertEqual(expected, output) - @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode_as_ids(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ @@ -134,7 +219,6 @@ def test_encode_as_ids(self): output = self.model.encode_as_ids(input) self.assertEqual(expected, output) - @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode_as_pieces(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ diff --git a/test/test_utils.py b/test/test_utils.py index 5489f838b2..73ee992de3 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -42,6 +42,34 @@ def test_download_extract_tar(self): conditional_remove(f) conditional_remove(archive_path) + def test_download_extract_gz(self): + # create root directory for downloading data + root = '.data' + if not os.path.exists(root): + os.makedirs(root) + + # ensure archive is not already downloaded, if it is then delete + url = 'https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz' + target_archive_path = os.path.join(root, 'val.5.en.gz') + conditional_remove(target_archive_path) + + # download archive and ensure is in correct location + archive_path = utils.download_from_url(url) + assert target_archive_path == archive_path + + # extract files and ensure they are correct + files = utils.extract_archive(archive_path) + assert files == [os.path.join(root, 'val.5.en')] + + # extract files with overwrite option True + files = utils.extract_archive(archive_path, overwrite=True) + assert files == [os.path.join(root, 'val.5.en')] + + # remove files and archive + for f in files: + conditional_remove(f) + conditional_remove(archive_path) + def test_download_extract_zip(self): # create root directory for downloading data root = '.data' diff --git a/torchtext/csrc/regex.cpp b/torchtext/csrc/regex.cpp new file mode 100644 index 0000000000..8e6db16507 --- /dev/null +++ b/torchtext/csrc/regex.cpp @@ -0,0 +1,44 @@ +#include +#include +#include + +namespace torchtext { +namespace { + +struct Regex : torch::CustomClassHolder { +private: + std::regex re_; + +public: + // re_str_ holds the serialized regex string passed at the initialization. + // We need this because we need to be able to serialize the model so that we + // can save the scripted object. pickle will get the + // serialized model from this re_str_ member, thus it needs to be public. + std::string re_str_; + + explicit Regex(const std::string &re_str) : re_str_(re_str) { + re_ = std::regex(re_str_); + } + + std::string Sub(const std::string &str, const std::string &repl) const { + return std::regex_replace(str, re_, repl); + } +}; + +// Registers our custom class with torch. +static auto regex = + torch::class_("torchtext", "Regex") + .def(torch::init()) + .def("Sub", &Regex::Sub) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return self->re_str_; + }, + // __setstate__ + [](std::string state) -> c10::intrusive_ptr { + return c10::make_intrusive(std::move(state)); + }); + +} // namespace +} // namespace torchtext diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index ac2faa423b..d91f60ff55 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -1,4 +1,4 @@ -from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank # NOQA +from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank, WMTNewsCrawl # NOQA from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB @@ -7,6 +7,7 @@ 'WikiText2', 'WikiText103', 'PennTreebank', + 'WMTNewsCrawl', 'IMDB', 'AG_NEWS', 'SogouNews', diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index 6c0ec5799e..f44de4af88 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -1,22 +1,15 @@ import torch -import logging -import io -from torchtext.utils import download_from_url, extract_archive -from torchtext.vocab import build_vocab_from_iterator from torchtext.data.utils import get_tokenizer -from torchtext.vocab import Vocab -from torchtext.data.functional import numericalize_tokens_from_iterator - -URLS = { - 'WikiText2': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip', - 'WikiText103': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip', - 'PennTreebank': - ['https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt'] -} +from torchtext.vocab import build_vocab_from_iterator +from torchtext.experimental.datasets.raw import language_modeling as raw +from torchtext.experimental.functional import vocab_func, totensor, sequential_transforms + + +def build_vocab(data, transforms): + tok_list = [] + for txt in data: + tok_list.append(transforms(txt)) + return build_vocab_from_iterator(tok_list) class LanguageModelingDataset(torch.utils.data.Dataset): @@ -26,10 +19,11 @@ class LanguageModelingDataset(torch.utils.data.Dataset): - WikiText2 - WikiText103 - PennTreebank + - WMTNewsCrawl """ - def __init__(self, data, vocab): + def __init__(self, data, vocab, transforms, single_line): """Initiate language modeling dataset. Arguments: @@ -37,22 +31,24 @@ def __init__(self, data, vocab): numericalizing the string tokens. torch.tensor([token_id_1, token_id_2, token_id_3, token_id1]).long() vocab: Vocabulary object used for dataset. - - Examples: - >>> from torchtext.vocab import build_vocab_from_iterator - >>> data = torch.tensor([token_id_1, token_id_2, - token_id_3, token_id_1]).long() - >>> vocab = build_vocab_from_iterator([['language', 'modeling']]) - >>> dataset = LanguageModelingDataset(data, vocab) + transforms: Text string transforms. """ super(LanguageModelingDataset, self).__init__() - self.data = data self.vocab = vocab + self.transforms = transforms + self.single_line = single_line + if single_line: + self.data = torch.cat(tuple(transforms(row) for row in data), axis=0) + else: + self.data = data def __getitem__(self, i): - return self.data[i] + if self.single_line: + return self.data[i] + else: + return self.transforms(self.data[i]) def __len__(self): return len(self.data) @@ -65,63 +61,45 @@ def get_vocab(self): return self.vocab -def _get_datafile_path(key, extracted_files): - for fname in extracted_files: - if key in fname: - return fname - - -def _setup_datasets(dataset_name, tokenizer=get_tokenizer("basic_english"), - root='.data', vocab=None, removed_tokens=[], - data_select=('train', 'test', 'valid')): +def _setup_datasets(dataset_name, tokenizer=None, root='.data', vocab=None, + data_select=('train', 'test', 'valid'), single_line=True): + if tokenizer is None: + tokenizer = get_tokenizer('basic_english') + text_transform = sequential_transforms(tokenizer) if isinstance(data_select, str): data_select = [data_select] - if not set(data_select).issubset(set(('train', 'test', 'valid'))): - raise TypeError('data_select is not supported!') - - if dataset_name == 'PennTreebank': - extracted_files = [] - select_to_index = {'train': 0, 'test': 1, 'valid': 2} - extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], - root=root) for key in data_select] + if not set(data_select).issubset(set(('train', 'valid', 'test'))): + raise TypeError('Given data selection {} is not supported!'.format(data_select)) + + if not single_line and dataset_name != 'WikiText103': + raise TypeError('single_line must be True except for WikiText103') + if dataset_name == 'WMTNewsCrawl': + train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) + if single_line: + raw_data = {'train': [" ".join([txt for txt in train]), ]} + else: + raw_data = {'train': [txt for txt in train]} else: - dataset_tar = download_from_url(URLS[dataset_name], root=root) - extracted_files = extract_archive(dataset_tar) - - _path = {} - for item in data_select: - _path[item] = _get_datafile_path(item, extracted_files) + train, test, valid = raw.DATASETS[dataset_name](root=root, data_select=('train', 'test', 'valid')) + # Cache raw text iterable dataset + if single_line: + raw_data = {'train': [" ".join([txt for txt in train]), ], + 'valid': [" ".join(txt for txt in valid), ], + 'test': [" ".join(txt for txt in test), ]} + else: + raw_data = {'train': [txt for txt in train], + 'valid': [txt for txt in valid], + 'test': [txt for txt in test]} if vocab is None: - if 'train' not in _path.keys(): + if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - logging.info('Building Vocab based on {}'.format(_path['train'])) - txt_iter = iter(tokenizer(row) for row in io.open(_path['train'], - encoding="utf8")) - vocab = build_vocab_from_iterator(txt_iter) - logging.info('Vocab has {} entries'.format(len(vocab))) - else: - if not isinstance(vocab, Vocab): - raise TypeError("Passed vocabulary is not of type Vocab") - - data = {} - for item in _path.keys(): - data[item] = [] - logging.info('Creating {} data'.format(item)) - txt_iter = iter(tokenizer(row) for row in io.open(_path[item], - encoding="utf8")) - _iter = numericalize_tokens_from_iterator( - vocab, txt_iter, removed_tokens) - for tokens in _iter: - data[item] += [token_id for token_id in tokens] - - for key in data_select: - if data[key] == []: - raise TypeError('Dataset {} is empty!'.format(key)) - - return tuple(LanguageModelingDataset(torch.tensor(data[d]).long(), vocab) - for d in data_select) + vocab = build_vocab(raw_data['train'], text_transform) + text_transform = sequential_transforms(text_transform, vocab_func(vocab), + totensor(dtype=torch.long)) + return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform, single_line) + for item in data_select) def WikiText2(*args, **kwargs): @@ -138,7 +116,6 @@ def WikiText2(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -146,6 +123,10 @@ def WikiText2(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText2 @@ -175,12 +156,6 @@ def WikiText103(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: the returned datasets (Default: ('train', 'test','valid')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test'). - If 'train' is not in the tuple, an vocab object should be provided which will - be used to process valid and/or test data. - removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -188,6 +163,10 @@ def WikiText103(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText103 @@ -217,7 +196,6 @@ def PennTreebank(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -225,6 +203,10 @@ def PennTreebank(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import PennTreebank @@ -238,3 +220,42 @@ def PennTreebank(*args, **kwargs): """ return _setup_datasets(*(("PennTreebank",) + args), **kwargs) + + +def WMTNewsCrawl(*args, **kwargs): + """ Defines WMTNewsCrawl datasets. + + Create language modeling dataset: WMTNewsCrawl + returns the train set + + Arguments: + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well (see example below). A custom tokenizer is callable + function with input of a string and output of a token list. + root: Directory where the datasets are saved. Default: ".data" + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + data_select: a string or tupel for the returned datasets + (Default: ('train',)) + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. + Examples: + >>> from torchtext.experimental.datasets import WMTNewsCrawl + >>> from torchtext.data.utils import get_tokenizer + >>> tokenizer = get_tokenizer("spacy") + >>> train_dataset, = WMTNewsCrawl(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) + + +DATASETS = { + 'WikiText2': WikiText2, + 'WikiText103': WikiText103, + 'PennTreebank': PennTreebank, + 'WMTNewsCrawl': WMTNewsCrawl +} diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py index 61accbe2a1..26892050d6 100644 --- a/torchtext/experimental/datasets/raw/__init__.py +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -1,6 +1,8 @@ from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB +from .translation import Multi30k, IWSLT, WMT14 +from .language_modeling import WikiText2, WikiText103, PennTreebank, WMTNewsCrawl __all__ = ['IMDB', 'AG_NEWS', @@ -10,4 +12,11 @@ 'YelpReviewFull', 'YahooAnswers', 'AmazonReviewPolarity', - 'AmazonReviewFull'] + 'AmazonReviewFull', + 'Multi30k', + 'IWSLT', + 'WMT14', + 'WikiText2', + 'WikiText103', + 'PennTreebank', + 'WMTNewsCrawl'] diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py new file mode 100644 index 0000000000..a867108978 --- /dev/null +++ b/torchtext/experimental/datasets/raw/language_modeling.py @@ -0,0 +1,184 @@ +import torch +import logging +import io +from torchtext.utils import download_from_url, extract_archive + +URLS = { + 'WikiText2': + 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip', + 'WikiText103': + 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip', + 'PennTreebank': + ['https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt', + 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt', + 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt'], + 'WMTNewsCrawl': 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' +} + + +class RawTextIterableDataset(torch.utils.data.IterableDataset): + """Defines an abstraction for raw text iterable datasets. + """ + + def __init__(self, iterator, start=0, num_lines=None): + """Initiate language modeling dataset. + """ + super(RawTextIterableDataset, self).__init__() + self._iterator = iterator + self.has_setup = False + self.start = start + self.num_lines = num_lines + + def setup_iter(self, start=0, num_lines=None): + self.start = start + self.num_lines = num_lines + self.has_setup = True + + def __iter__(self): + if not self.has_setup: + self.setup_iter() + for i, item in enumerate(self._iterator): + if i >= self.start: + yield item + if (self.num_lines is not None) and (i == (self.start + self.num_lines)): + break + + def get_iterator(self): + return self._iterator + + +def _setup_datasets(dataset_name, root='.data', data_select=('train', 'test', 'valid'), **kwargs): + if isinstance(data_select, str): + data_select = [data_select] + if not set(data_select).issubset(set(('train', 'test', 'valid'))): + raise TypeError('data_select is not supported!') + + if dataset_name == 'PennTreebank': + extracted_files = [] + select_to_index = {'train': 0, 'test': 1, 'valid': 2} + extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], + root=root) for key in data_select] + elif dataset_name == 'WMTNewsCrawl': + if not (data_select == ['train'] or set(data_select).issubset(set(('train',)))): + raise ValueError("WMTNewsCrawl only creates a training dataset. " + "data_select should be 'train' " + "or ('train',), got {}.".format(data_select)) + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files = extract_archive(dataset_tar) + year = kwargs.get('year', 2010) + language = kwargs.get('language', 'en') + file_name = 'news.{}.{}.shuffled'.format(year, language) + extracted_files = [f for f in extracted_files if file_name in f] + else: + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files = extract_archive(dataset_tar) + + _path = {} + for item in data_select: + for fname in extracted_files: + if item in fname: + _path[item] = fname + + data = {} + for item in _path.keys(): + logging.info('Creating {} data'.format(item)) + data[item] = iter(io.open(_path[item], encoding="utf8")) + + return tuple(RawTextIterableDataset(data[item]) for item in data_select) + + +def WikiText2(*args, **kwargs): + """ Defines WikiText2 datasets. + + Create language modeling dataset: WikiText2 + Separately returns the train/test/valid set + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tupel for the returned datasets + (Default: ('train', 'test','valid')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.raw.datasets import WikiText2 + >>> train_dataset, test_dataset, valid_dataset = WikiText2() + >>> valid_dataset, = WikiText2(data_select='valid') + + """ + + return _setup_datasets(*(("WikiText2",) + args), **kwargs) + + +def WikiText103(*args, **kwargs): + """ Defines WikiText103 datasets. + + Create language modeling dataset: WikiText103 + Separately returns the train/test/valid set + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: the returned datasets (Default: ('train', 'test','valid')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test'). + If 'train' is not in the tuple, an vocab object should be provided which will + be used to process valid and/or test data. + + Examples: + >>> from torchtext.experimental.datasets.raw import WikiText103 + >>> train_dataset, test_dataset, valid_dataset = WikiText103() + >>> valid_dataset, = WikiText103(data_select='valid') + """ + + return _setup_datasets(*(("WikiText103",) + args), **kwargs) + + +def PennTreebank(*args, **kwargs): + """ Defines PennTreebank datasets. + + Create language modeling dataset: PennTreebank + Separately returns the train/test/valid set + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test','valid')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets.raw import PennTreebank + >>> train_dataset, test_dataset, valid_dataset = PennTreebank() + >>> valid_dataset, = PennTreebank(data_select='valid') + + """ + + return _setup_datasets(*(("PennTreebank",) + args), **kwargs) + + +def WMTNewsCrawl(*args, **kwargs): + """ Defines WMT News Crawl. + + Create language modeling dataset: WMTNewsCrawl + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. + (Default: 'train') + """ + + return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) + + +DATASETS = { + 'WikiText2': WikiText2, + 'WikiText103': WikiText103, + 'PennTreebank': PennTreebank, + 'WMTNewsCrawl': WMTNewsCrawl +} diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py new file mode 100644 index 0000000000..19f5275d41 --- /dev/null +++ b/torchtext/experimental/datasets/raw/translation.py @@ -0,0 +1,544 @@ +import torch +import os +import io +import codecs +import xml.etree.ElementTree as ET +from collections import defaultdict + +from torchtext.utils import (download_from_url, extract_archive, + unicode_csv_reader) + +URLS = { + 'Multi30k': [ + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz" + ], + 'WMT14': + 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8', + 'IWSLT': + 'https://wit3.fbk.eu/archive/2016-01//texts/{}/{}/{}.tgz' +} + + +def _read_text_iterator(path): + with io.open(path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield " ".join(row) + + +def _clean_xml_file(f_xml): + f_txt = os.path.splitext(f_xml)[0] + with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: + root = ET.parse(f_xml).getroot()[0] + for doc in root.findall('doc'): + for e in doc.findall('seg'): + fd_txt.write(e.text.strip() + '\n') + + +def _clean_tags_file(f_orig): + xml_tags = [ + '= self.start: + yield item + if (self.num_lines is not None) and (i == (self.start + + self.num_lines)): + break + + def get_iterator(self): + return (self._src_iterator, self._tgt_iterator) + + +def Multi30k(train_filenames=("train.de", "train.en"), + valid_filenames=("val.de", "val.en"), + test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), + root='.data'): + """ Define translation datasets: Multi30k + Separately returns train/valid/test datasets as a tuple + The available dataset include: + test_2016_flickr.cs + test_2016_flickr.de + test_2016_flickr.en + test_2016_flickr.fr + test_2017_flickr.de + test_2017_flickr.en + test_2017_flickr.fr + test_2017_mscoco.de + test_2017_mscoco.en + test_2017_mscoco.fr + test_2018_flickr.en + train.cs + train.de + train.en + train.fr + val.cs + val.de + val.en + val.fr + test_2016.1.de + test_2016.1.en + test_2016.2.de + test_2016.2.en + test_2016.3.de + test_2016.3.en + test_2016.4.de + test_2016.4.en + test_2016.5.de + test_2016.5.en + train.1.de + train.1.en + train.2.de + train.2.en + train.3.de + train.3.en + train.4.de + train.4.en + train.5.de + train.5.en + val.1.de + val.1.en + val.2.de + val.2.en + val.3.de + val.3.en + val.4.de + val.4.en + val.5.de + val.5.en + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de', 'train.en') + valid_filenames: the source and target filenames for valid. + Default: ('val.de', 'val.en') + test_filenames: the source and target filenames for test. + Default: ('test2016.de', 'test2016.en') + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets import Multi30k + >>> train_dataset, valid_dataset, test_dataset = Multi30k() + """ + return _setup_datasets("Multi30k", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root) + + +def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), + valid_filenames=('IWSLT16.TED.tst2013.de-en.de', + 'IWSLT16.TED.tst2013.de-en.en'), + test_filenames=('IWSLT16.TED.tst2014.de-en.de', + 'IWSLT16.TED.tst2014.de-en.en'), + root='.data'): + """ Define translation datasets: IWSLT + Separately returns train/valid/test datasets + The available datasets include: + IWSLT16.TED.dev2010.ar-en.ar + IWSLT16.TED.dev2010.ar-en.en + IWSLT16.TED.dev2010.cs-en.cs + IWSLT16.TED.dev2010.cs-en.en + IWSLT16.TED.dev2010.de-en.de + IWSLT16.TED.dev2010.de-en.en + IWSLT16.TED.dev2010.en-ar.ar + IWSLT16.TED.dev2010.en-ar.en + IWSLT16.TED.dev2010.en-cs.cs + IWSLT16.TED.dev2010.en-cs.en + IWSLT16.TED.dev2010.en-de.de + IWSLT16.TED.dev2010.en-de.en + IWSLT16.TED.dev2010.en-fr.en + IWSLT16.TED.dev2010.en-fr.fr + IWSLT16.TED.dev2010.fr-en.en + IWSLT16.TED.dev2010.fr-en.fr + IWSLT16.TED.tst2010.ar-en.ar + IWSLT16.TED.tst2010.ar-en.en + IWSLT16.TED.tst2010.cs-en.cs + IWSLT16.TED.tst2010.cs-en.en + IWSLT16.TED.tst2010.de-en.de + IWSLT16.TED.tst2010.de-en.en + IWSLT16.TED.tst2010.en-ar.ar + IWSLT16.TED.tst2010.en-ar.en + IWSLT16.TED.tst2010.en-cs.cs + IWSLT16.TED.tst2010.en-cs.en + IWSLT16.TED.tst2010.en-de.de + IWSLT16.TED.tst2010.en-de.en + IWSLT16.TED.tst2010.en-fr.en + IWSLT16.TED.tst2010.en-fr.fr + IWSLT16.TED.tst2010.fr-en.en + IWSLT16.TED.tst2010.fr-en.fr + IWSLT16.TED.tst2011.ar-en.ar + IWSLT16.TED.tst2011.ar-en.en + IWSLT16.TED.tst2011.cs-en.cs + IWSLT16.TED.tst2011.cs-en.en + IWSLT16.TED.tst2011.de-en.de + IWSLT16.TED.tst2011.de-en.en + IWSLT16.TED.tst2011.en-ar.ar + IWSLT16.TED.tst2011.en-ar.en + IWSLT16.TED.tst2011.en-cs.cs + IWSLT16.TED.tst2011.en-cs.en + IWSLT16.TED.tst2011.en-de.de + IWSLT16.TED.tst2011.en-de.en + IWSLT16.TED.tst2011.en-fr.en + IWSLT16.TED.tst2011.en-fr.fr + IWSLT16.TED.tst2011.fr-en.en + IWSLT16.TED.tst2011.fr-en.fr + IWSLT16.TED.tst2012.ar-en.ar + IWSLT16.TED.tst2012.ar-en.en + IWSLT16.TED.tst2012.cs-en.cs + IWSLT16.TED.tst2012.cs-en.en + IWSLT16.TED.tst2012.de-en.de + IWSLT16.TED.tst2012.de-en.en + IWSLT16.TED.tst2012.en-ar.ar + IWSLT16.TED.tst2012.en-ar.en + IWSLT16.TED.tst2012.en-cs.cs + IWSLT16.TED.tst2012.en-cs.en + IWSLT16.TED.tst2012.en-de.de + IWSLT16.TED.tst2012.en-de.en + IWSLT16.TED.tst2012.en-fr.en + IWSLT16.TED.tst2012.en-fr.fr + IWSLT16.TED.tst2012.fr-en.en + IWSLT16.TED.tst2012.fr-en.fr + IWSLT16.TED.tst2013.ar-en.ar + IWSLT16.TED.tst2013.ar-en.en + IWSLT16.TED.tst2013.cs-en.cs + IWSLT16.TED.tst2013.cs-en.en + IWSLT16.TED.tst2013.de-en.de + IWSLT16.TED.tst2013.de-en.en + IWSLT16.TED.tst2013.en-ar.ar + IWSLT16.TED.tst2013.en-ar.en + IWSLT16.TED.tst2013.en-cs.cs + IWSLT16.TED.tst2013.en-cs.en + IWSLT16.TED.tst2013.en-de.de + IWSLT16.TED.tst2013.en-de.en + IWSLT16.TED.tst2013.en-fr.en + IWSLT16.TED.tst2013.en-fr.fr + IWSLT16.TED.tst2013.fr-en.en + IWSLT16.TED.tst2013.fr-en.fr + IWSLT16.TED.tst2014.ar-en.ar + IWSLT16.TED.tst2014.ar-en.en + IWSLT16.TED.tst2014.de-en.de + IWSLT16.TED.tst2014.de-en.en + IWSLT16.TED.tst2014.en-ar.ar + IWSLT16.TED.tst2014.en-ar.en + IWSLT16.TED.tst2014.en-de.de + IWSLT16.TED.tst2014.en-de.en + IWSLT16.TED.tst2014.en-fr.en + IWSLT16.TED.tst2014.en-fr.fr + IWSLT16.TED.tst2014.fr-en.en + IWSLT16.TED.tst2014.fr-en.fr + IWSLT16.TEDX.dev2012.de-en.de + IWSLT16.TEDX.dev2012.de-en.en + IWSLT16.TEDX.tst2013.de-en.de + IWSLT16.TEDX.tst2013.de-en.en + IWSLT16.TEDX.tst2014.de-en.de + IWSLT16.TEDX.tst2014.de-en.en + train.ar + train.ar-en.ar + train.ar-en.en + train.cs + train.cs-en.cs + train.cs-en.en + train.de + train.de-en.de + train.de-en.en + train.en + train.en-ar.ar + train.en-ar.en + train.en-cs.cs + train.en-cs.en + train.en-de.de + train.en-de.en + train.en-fr.en + train.en-fr.fr + train.fr + train.fr-en.en + train.fr-en.fr + train.tags.ar-en.ar + train.tags.ar-en.en + train.tags.cs-en.cs + train.tags.cs-en.en + train.tags.de-en.de + train.tags.de-en.en + train.tags.en-ar.ar + train.tags.en-ar.en + train.tags.en-cs.cs + train.tags.en-cs.en + train.tags.en-de.de + train.tags.en-de.en + train.tags.en-fr.en + train.tags.en-fr.fr + train.tags.fr-en.en + train.tags.fr-en.fr + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de-en.de', 'train.de-en.en') + valid_filenames: the source and target filenames for valid. + Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') + test_filenames: the source and target filenames for test. + Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets.raw import IWSLT + >>> train_dataset, valid_dataset, test_dataset = IWSLT() + """ + src_language = train_filenames[0].split(".")[-1] + tgt_language = train_filenames[1].split(".")[-1] + languages = "-".join([src_language, tgt_language]) + URLS["IWSLT"] = URLS["IWSLT"].format(src_language, tgt_language, languages) + + return _setup_datasets( + "IWSLT", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root, + ) + + +def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', + 'train.tok.clean.bpe.32000.en'), + valid_filenames=('newstest2013.tok.bpe.32000.de', + 'newstest2013.tok.bpe.32000.en'), + test_filenames=('newstest2014.tok.bpe.32000.de', + 'newstest2014.tok.bpe.32000.en'), + root='.data'): + """ Define translation datasets: WMT14 + Separately returns train/valid/test datasets + The available datasets include: + newstest2016.en + newstest2016.de + newstest2015.en + newstest2015.de + newstest2014.en + newstest2014.de + newstest2013.en + newstest2013.de + newstest2012.en + newstest2012.de + newstest2011.tok.de + newstest2011.en + newstest2011.de + newstest2010.tok.de + newstest2010.en + newstest2010.de + newstest2009.tok.de + newstest2009.en + newstest2009.de + newstest2016.tok.de + newstest2015.tok.de + newstest2014.tok.de + newstest2013.tok.de + newstest2012.tok.de + newstest2010.tok.en + newstest2009.tok.en + newstest2015.tok.en + newstest2014.tok.en + newstest2013.tok.en + newstest2012.tok.en + newstest2011.tok.en + newstest2016.tok.en + newstest2009.tok.bpe.32000.en + newstest2011.tok.bpe.32000.en + newstest2010.tok.bpe.32000.en + newstest2013.tok.bpe.32000.en + newstest2012.tok.bpe.32000.en + newstest2015.tok.bpe.32000.en + newstest2014.tok.bpe.32000.en + newstest2016.tok.bpe.32000.en + train.tok.clean.bpe.32000.en + newstest2009.tok.bpe.32000.de + newstest2010.tok.bpe.32000.de + newstest2011.tok.bpe.32000.de + newstest2013.tok.bpe.32000.de + newstest2012.tok.bpe.32000.de + newstest2014.tok.bpe.32000.de + newstest2016.tok.bpe.32000.de + newstest2015.tok.bpe.32000.de + train.tok.clean.bpe.32000.de + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') + valid_filenames: the source and target filenames for valid. + Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') + test_filenames: the source and target filenames for test. + Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets import WMT14 + >>> train_dataset, valid_dataset, test_dataset = WMT14() + """ + + return _setup_datasets("WMT14", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root) + + +DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py new file mode 100644 index 0000000000..5fad51135d --- /dev/null +++ b/torchtext/experimental/datasets/translation.py @@ -0,0 +1,551 @@ +import torch +import logging + +from torchtext.experimental.datasets import raw +from torchtext.vocab import build_vocab_from_iterator +from torchtext.data.utils import get_tokenizer +from ..functional import vocab_func, totensor, sequential_transforms + + +def build_vocab(data, transforms, index): + tok_list = [] + for line in data: + tok_list.append(transforms(line[index])) + return build_vocab_from_iterator(tok_list) + + +def _setup_datasets(dataset_name, + train_filenames, + valid_filenames, + test_filenames, + data_select=('train', 'test', 'valid'), + root='.data', + vocab=(None, None), + tokenizer=None, + removed_tokens=['']): + src_vocab, tgt_vocab = vocab + if tokenizer is None: + src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') + tgt_tokenizer = get_tokenizer("spacy", language='en_core_web_sm') + elif isinstance(tokenizer, tuple): + if len(tokenizer) == 2: + src_tokenizer, tgt_tokenizer = tokenizer + else: + raise ValueError("tokenizer must have length of two for" + "source and target") + else: + raise ValueError( + "tokenizer must be an instance of tuple with length two" + "or None") + train, val, test = DATASETS[dataset_name](train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root) + raw_data = { + "train": [line for line in train], + "valid": [line for line in val], + "test": [line for line in test] + } + src_text_vocab_transform = sequential_transforms(src_tokenizer) + tgt_text_vocab_transform = sequential_transforms(tgt_tokenizer) + + if src_vocab is None: + if 'train' not in data_select: + raise TypeError("Must pass a vocab if train is not selected.") + logging.info('Building src Vocab based on train data') + src_vocab = build_vocab(raw_data["train"], + src_text_vocab_transform, + index=0) + else: + if not isinstance(src_vocab, Vocab): + raise TypeError("Passed src vocabulary is not of type Vocab") + logging.info('src Vocab has {} entries'.format(len(src_vocab))) + + if tgt_vocab is None: + if 'train' not in data_select: + raise TypeError("Must pass a vocab if train is not selected.") + logging.info('Building tgt Vocab based on train data') + tgt_vocab = build_vocab(raw_data["train"], + tgt_text_vocab_transform, + index=1) + else: + if not isinstance(tgt_vocab, Vocab): + raise TypeError("Passed tgt vocabulary is not of type Vocab") + logging.info('tgt Vocab has {} entries'.format(len(tgt_vocab))) + + logging.info('Building datasets for {}'.format(data_select)) + datasets = [] + for key in data_select: + src_text_transform = sequential_transforms(src_text_vocab_transform, + vocab_func(src_vocab), + totensor(dtype=torch.long)) + tgt_text_transform = sequential_transforms(tgt_text_vocab_transform, + vocab_func(tgt_vocab), + totensor(dtype=torch.long)) + datasets.append( + TranslationDataset(raw_data[key], (src_vocab, tgt_vocab), + (src_text_transform, tgt_text_transform))) + + return tuple(datasets) + + +class TranslationDataset(torch.utils.data.Dataset): + """Defines a dataset for translation. + Currently, we only support the following datasets: + - Multi30k + - WMT14 + - IWSLT + """ + def __init__(self, data, vocab, transforms): + """Initiate translation dataset. + + Arguments: + data: a tuple of source and target tensors, which include token ids + numericalizing the string tokens. + [(src_tensor0, tgt_tensor0), (src_tensor1, tgt_tensor1)] + vocab: source and target Vocabulary object used for dataset. + (src_vocab, tgt_vocab) + transforms: a tuple of source and target string transforms. + + Examples: + >>> from torchtext.vocab import build_vocab_from_iterator + >>> src_data = torch.Tensor([token_id_s1, token_id_s2, + token_id_s3, token_id_s1]).long() + >>> tgt_data = torch.Tensor([token_id_t1, token_id_t2, + token_id_t3, token_id_t1]).long() + >>> src_vocab = build_vocab_from_iterator([['Übersetzungsdatensatz']]) + >>> tgt_vocab = build_vocab_from_iterator([['translation', 'dataset']]) + >>> dataset = TranslationDataset([(src_data, tgt_data)], + (src_vocab, tgt_vocab)) + """ + + super(TranslationDataset, self).__init__() + self.data = data + self.vocab = vocab + self.transforms = transforms + + def __getitem__(self, i): + source = self.transforms[0](self.data[i][0]) + target = self.transforms[1](self.data[i][1]) + return (source, target) + + def __len__(self): + return len(self.data) + + def get_vocab(self): + return self.vocab + + +def Multi30k(train_filenames=("train.de", "train.en"), + valid_filenames=("val.de", "val.en"), + test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), + tokenizer=None, + root='.data', + vocab=(None, None), + data_select=('train', 'valid', 'test'), + removed_tokens=['']): + """ Define translation datasets: Multi30k + Separately returns train/valid/test datasets as a tuple + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de', 'train.en') + valid_filenames: the source and target filenames for valid. + Default: ('val.de', 'val.en') + test_filenames: the source and target filenames for test. + Default: ('test2016.de', 'test2016.en') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + root: Directory where the datasets are saved. Default: ".data" + vocab: Source and target Vocabulary objects used for dataset. If None, it + will generate a new vocabulary based on the train data set. It has to be + in a form of tuple. + Default: (None, None) + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + removed_tokens: removed tokens from output dataset (Default: '') + The available dataset include: + test_2016_flickr.cs + test_2016_flickr.de + test_2016_flickr.en + test_2016_flickr.fr + test_2017_flickr.de + test_2017_flickr.en + test_2017_flickr.fr + test_2017_mscoco.de + test_2017_mscoco.en + test_2017_mscoco.fr + test_2018_flickr.en + train.cs + train.de + train.en + train.fr + val.cs + val.de + val.en + val.fr + test_2016.1.de + test_2016.1.en + test_2016.2.de + test_2016.2.en + test_2016.3.de + test_2016.3.en + test_2016.4.de + test_2016.4.en + test_2016.5.de + test_2016.5.en + train.1.de + train.1.en + train.2.de + train.2.en + train.3.de + train.3.en + train.4.de + train.4.en + train.5.de + train.5.en + val.1.de + val.1.en + val.2.de + val.2.en + val.3.de + val.3.en + val.4.de + val.4.en + val.5.de + val.5.en + + Examples: + >>> from torchtext.datasets import Multi30k + >>> from torchtext.data.utils import get_tokenizer + >>> tokenizer = (get_tokenizer("spacy", language='de'), + get_tokenizer("basic_english")) + >>> train_dataset, valid_dataset, test_dataset = Multi30k(tokenizer=tokenizer) + >>> src_vocab, tgt_vocab = train_dataset.get_vocab() + >>> src_data, tgt_data = train_dataset[10] + """ + return _setup_datasets("Multi30k", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + tokenizer=tokenizer, + root=root, + vocab=vocab, + removed_tokens=removed_tokens) + + +def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), + valid_filenames=('IWSLT16.TED.tst2013.de-en.de', + 'IWSLT16.TED.tst2013.de-en.en'), + test_filenames=('IWSLT16.TED.tst2014.de-en.de', + 'IWSLT16.TED.tst2014.de-en.en'), + tokenizer=None, + root='.data', + vocab=(None, None), + data_select=('train', 'valid', 'test'), + removed_tokens=['']): + """ Define translation datasets: IWSLT + Separately returns train/valid/test datasets + The available datasets include: + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de-en.de', 'train.de-en.en') + valid_filenames: the source and target filenames for valid. + Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') + test_filenames: the source and target filenames for test. + Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + root: Directory where the datasets are saved. Default: ".data" + vocab: Source and target Vocabulary objects used for dataset. If None, it + will generate a new vocabulary based on the train data set. It has to be + in a form of tuple. + Default: (None, None) + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + removed_tokens: removed tokens from output dataset (Default: '') + The available datasets include: + IWSLT16.TED.dev2010.ar-en.ar + IWSLT16.TED.dev2010.ar-en.en + IWSLT16.TED.dev2010.cs-en.cs + IWSLT16.TED.dev2010.cs-en.en + IWSLT16.TED.dev2010.de-en.de + IWSLT16.TED.dev2010.de-en.en + IWSLT16.TED.dev2010.en-ar.ar + IWSLT16.TED.dev2010.en-ar.en + IWSLT16.TED.dev2010.en-cs.cs + IWSLT16.TED.dev2010.en-cs.en + IWSLT16.TED.dev2010.en-de.de + IWSLT16.TED.dev2010.en-de.en + IWSLT16.TED.dev2010.en-fr.en + IWSLT16.TED.dev2010.en-fr.fr + IWSLT16.TED.dev2010.fr-en.en + IWSLT16.TED.dev2010.fr-en.fr + IWSLT16.TED.tst2010.ar-en.ar + IWSLT16.TED.tst2010.ar-en.en + IWSLT16.TED.tst2010.cs-en.cs + IWSLT16.TED.tst2010.cs-en.en + IWSLT16.TED.tst2010.de-en.de + IWSLT16.TED.tst2010.de-en.en + IWSLT16.TED.tst2010.en-ar.ar + IWSLT16.TED.tst2010.en-ar.en + IWSLT16.TED.tst2010.en-cs.cs + IWSLT16.TED.tst2010.en-cs.en + IWSLT16.TED.tst2010.en-de.de + IWSLT16.TED.tst2010.en-de.en + IWSLT16.TED.tst2010.en-fr.en + IWSLT16.TED.tst2010.en-fr.fr + IWSLT16.TED.tst2010.fr-en.en + IWSLT16.TED.tst2010.fr-en.fr + IWSLT16.TED.tst2011.ar-en.ar + IWSLT16.TED.tst2011.ar-en.en + IWSLT16.TED.tst2011.cs-en.cs + IWSLT16.TED.tst2011.cs-en.en + IWSLT16.TED.tst2011.de-en.de + IWSLT16.TED.tst2011.de-en.en + IWSLT16.TED.tst2011.en-ar.ar + IWSLT16.TED.tst2011.en-ar.en + IWSLT16.TED.tst2011.en-cs.cs + IWSLT16.TED.tst2011.en-cs.en + IWSLT16.TED.tst2011.en-de.de + IWSLT16.TED.tst2011.en-de.en + IWSLT16.TED.tst2011.en-fr.en + IWSLT16.TED.tst2011.en-fr.fr + IWSLT16.TED.tst2011.fr-en.en + IWSLT16.TED.tst2011.fr-en.fr + IWSLT16.TED.tst2012.ar-en.ar + IWSLT16.TED.tst2012.ar-en.en + IWSLT16.TED.tst2012.cs-en.cs + IWSLT16.TED.tst2012.cs-en.en + IWSLT16.TED.tst2012.de-en.de + IWSLT16.TED.tst2012.de-en.en + IWSLT16.TED.tst2012.en-ar.ar + IWSLT16.TED.tst2012.en-ar.en + IWSLT16.TED.tst2012.en-cs.cs + IWSLT16.TED.tst2012.en-cs.en + IWSLT16.TED.tst2012.en-de.de + IWSLT16.TED.tst2012.en-de.en + IWSLT16.TED.tst2012.en-fr.en + IWSLT16.TED.tst2012.en-fr.fr + IWSLT16.TED.tst2012.fr-en.en + IWSLT16.TED.tst2012.fr-en.fr + IWSLT16.TED.tst2013.ar-en.ar + IWSLT16.TED.tst2013.ar-en.en + IWSLT16.TED.tst2013.cs-en.cs + IWSLT16.TED.tst2013.cs-en.en + IWSLT16.TED.tst2013.de-en.de + IWSLT16.TED.tst2013.de-en.en + IWSLT16.TED.tst2013.en-ar.ar + IWSLT16.TED.tst2013.en-ar.en + IWSLT16.TED.tst2013.en-cs.cs + IWSLT16.TED.tst2013.en-cs.en + IWSLT16.TED.tst2013.en-de.de + IWSLT16.TED.tst2013.en-de.en + IWSLT16.TED.tst2013.en-fr.en + IWSLT16.TED.tst2013.en-fr.fr + IWSLT16.TED.tst2013.fr-en.en + IWSLT16.TED.tst2013.fr-en.fr + IWSLT16.TED.tst2014.ar-en.ar + IWSLT16.TED.tst2014.ar-en.en + IWSLT16.TED.tst2014.de-en.de + IWSLT16.TED.tst2014.de-en.en + IWSLT16.TED.tst2014.en-ar.ar + IWSLT16.TED.tst2014.en-ar.en + IWSLT16.TED.tst2014.en-de.de + IWSLT16.TED.tst2014.en-de.en + IWSLT16.TED.tst2014.en-fr.en + IWSLT16.TED.tst2014.en-fr.fr + IWSLT16.TED.tst2014.fr-en.en + IWSLT16.TED.tst2014.fr-en.fr + IWSLT16.TEDX.dev2012.de-en.de + IWSLT16.TEDX.dev2012.de-en.en + IWSLT16.TEDX.tst2013.de-en.de + IWSLT16.TEDX.tst2013.de-en.en + IWSLT16.TEDX.tst2014.de-en.de + IWSLT16.TEDX.tst2014.de-en.en + train.ar + train.ar-en.ar + train.ar-en.en + train.cs + train.cs-en.cs + train.cs-en.en + train.de + train.de-en.de + train.de-en.en + train.en + train.en-ar.ar + train.en-ar.en + train.en-cs.cs + train.en-cs.en + train.en-de.de + train.en-de.en + train.en-fr.en + train.en-fr.fr + train.fr + train.fr-en.en + train.fr-en.fr + train.tags.ar-en.ar + train.tags.ar-en.en + train.tags.cs-en.cs + train.tags.cs-en.en + train.tags.de-en.de + train.tags.de-en.en + train.tags.en-ar.ar + train.tags.en-ar.en + train.tags.en-cs.cs + train.tags.en-cs.en + train.tags.en-de.de + train.tags.en-de.en + train.tags.en-fr.en + train.tags.en-fr.fr + train.tags.fr-en.en + train.tags.fr-en.fr + + Examples: + >>> from torchtext.datasets import IWSLT + >>> from torchtext.data.utils import get_tokenizer + >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> tgt_tokenizer = get_tokenizer("basic_english") + >>> train_dataset, valid_dataset, test_dataset = IWSLT(tokenizer=(src_tokenizer, + tgt_tokenizer)) + >>> src_vocab, tgt_vocab = train_dataset.get_vocab() + >>> src_data, tgt_data = train_dataset[10] + """ + + return _setup_datasets("IWSLT", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + tokenizer=tokenizer, + root=root, + vocab=vocab, + removed_tokens=removed_tokens) + + +def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', + 'train.tok.clean.bpe.32000.en'), + valid_filenames=('newstest2013.tok.bpe.32000.de', + 'newstest2013.tok.bpe.32000.en'), + test_filenames=('newstest2014.tok.bpe.32000.de', + 'newstest2014.tok.bpe.32000.en'), + tokenizer=None, + root='.data', + vocab=(None, None), + data_select=('train', 'valid', 'test'), + removed_tokens=['']): + """ Define translation datasets: WMT14 + Separately returns train/valid/test datasets + The available datasets include: + newstest2016.en + newstest2016.de + newstest2015.en + newstest2015.de + newstest2014.en + newstest2014.de + newstest2013.en + newstest2013.de + newstest2012.en + newstest2012.de + newstest2011.tok.de + newstest2011.en + newstest2011.de + newstest2010.tok.de + newstest2010.en + newstest2010.de + newstest2009.tok.de + newstest2009.en + newstest2009.de + newstest2016.tok.de + newstest2015.tok.de + newstest2014.tok.de + newstest2013.tok.de + newstest2012.tok.de + newstest2010.tok.en + newstest2009.tok.en + newstest2015.tok.en + newstest2014.tok.en + newstest2013.tok.en + newstest2012.tok.en + newstest2011.tok.en + newstest2016.tok.en + newstest2009.tok.bpe.32000.en + newstest2011.tok.bpe.32000.en + newstest2010.tok.bpe.32000.en + newstest2013.tok.bpe.32000.en + newstest2012.tok.bpe.32000.en + newstest2015.tok.bpe.32000.en + newstest2014.tok.bpe.32000.en + newstest2016.tok.bpe.32000.en + train.tok.clean.bpe.32000.en + newstest2009.tok.bpe.32000.de + newstest2010.tok.bpe.32000.de + newstest2011.tok.bpe.32000.de + newstest2013.tok.bpe.32000.de + newstest2012.tok.bpe.32000.de + newstest2014.tok.bpe.32000.de + newstest2016.tok.bpe.32000.de + newstest2015.tok.bpe.32000.de + train.tok.clean.bpe.32000.de + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') + valid_filenames: the source and target filenames for valid. + Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') + test_filenames: the source and target filenames for test. + Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + root: Directory where the datasets are saved. Default: ".data" + vocab: Source and target Vocabulary objects used for dataset. If None, it + will generate a new vocabulary based on the train data set. It has to be + in a form of tuple. + Default: (None, None) + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + removed_tokens: removed tokens from output dataset (Default: '') + + Examples: + >>> from torchtext.datasets import WMT14 + >>> from torchtext.data.utils import get_tokenizer + >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> tgt_tokenizer = get_tokenizer("basic_english") + >>> train_dataset, valid_dataset, test_dataset = WMT14(tokenizer=(src_tokenizer, + tgt_tokenizer)) + >>> src_vocab, tgt_vocab = train_dataset.get_vocab() + >>> src_data, tgt_data = train_dataset[10] + """ + + return _setup_datasets("WMT14", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + tokenizer=tokenizer, + root=root, + vocab=vocab, + removed_tokens=removed_tokens) + + +DATASETS = {'Multi30k': raw.Multi30k, 'IWSLT': raw.IWSLT, 'WMT14': raw.WMT14} diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py new file mode 100644 index 0000000000..f7f53670be --- /dev/null +++ b/torchtext/experimental/transforms.py @@ -0,0 +1,114 @@ +import torch +import torch.nn as nn +from typing import List, Tuple + + +__all__ = [ + 'BasicEnglishNormalize', + 'RegexTokenizer' +] + + +class BasicEnglishNormalize(nn.Module): + r"""Basic normalization for a string sentence. + + Normalization includes + - lowercasing + - complete some basic text normalization for English words as follows: + - add spaces before and after '\'' + - remove '\"', + - add spaces before and after '.' + - replace '
'with single space + - add spaces before and after ',' + - add spaces before and after '(' + - add spaces before and after ')' + - add spaces before and after '!' + - add spaces before and after '?' + - replace ';' with single space + - replace ':' with single space + - replace multiple spaces with single space + + Examples: + >>> import torch + >>> from torchtext.experimental.transforms import BasicEnglishNormalize + >>> test_sample = 'Basic English Normalization for a Line of Text' + >>> basic_english_normalize = BasicEnglishNormalize() + >>> jit_basic_english_normalize = torch.jit.script(basic_english_normalize) + >>> tokens = jit_basic_english_normalize(test_sample) + """ + + regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] + + def __init__(self): + super(BasicEnglishNormalize, self).__init__() + patterns_list = [ + (r'\'', ' \' '), + (r'\"', ''), + (r'\.', ' . '), + (r'
', ' '), + (r',', ' , '), + (r'\(', ' ( '), + (r'\)', ' ) '), + (r'\!', ' ! '), + (r'\?', ' ? '), + (r'\;', ' '), + (r'\:', ' '), + (r'\s+', ' ')] + + regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) + replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) + self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) + + def forward(self, line: str) -> List[str]: + r""" + Args: + line (str): a line of text to tokenize. + Returns: + List[str]: a list of tokens after normalizing and splitting on whitespace. + """ + + line = line.lower() + for regex, replacement_string in self.regex_and_replacement_string_pairs: + line = regex.Sub(line, replacement_string) + return line.split() + + +class RegexTokenizer(nn.Module): + r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. + + Args: + patterns_list (List[Tuple[str, str]]): a list of tuples (ordered pairs) which contain the regex pattern string + as the first element and the replacement string as the second element. + + Examples: + >>> import torch + >>> from torchtext.experimental.transforms import RegexTokenizer + >>> test_sample = 'Basic Regex Tokenization for a Line of Text' + >>> patterns_list = [ + (r'\'', ' \' '), + (r'\"', '')] + >>> regex_tokenizer = RegexTokenizer(patterns_list) + >>> jit_regex_tokenizer = torch.jit.script(regex_tokenizer) + >>> tokens = jit_regex_tokenizer(test_sample) + """ + + regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] + + def __init__(self, patterns_list: List[Tuple[str, str]]): + super(RegexTokenizer, self).__init__() + + regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) + replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) + self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) + + def forward(self, line: str) -> List[str]: + r""" + Args: + line (str): a line of text to tokenize. + Returns: + List[str]: a list of tokens after normalizing and splitting on whitespace. + """ + + for regex, replacement_string in self.regex_and_replacement_string_pairs: + line = regex.Sub(line, replacement_string) + return line.split() diff --git a/torchtext/utils.py b/torchtext/utils.py index 41ac14ecbb..b892396a15 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -7,6 +7,7 @@ import re import sys import zipfile +import gzip def reporthook(t): @@ -197,6 +198,21 @@ def extract_archive(from_path, to_path=None, overwrite=False): files = [f for f in files if os.path.isfile(f)] return files + elif from_path.endswith('.gz'): + default_block_size = 65536 + filename = from_path[:-3] + files = [filename] + with gzip.open(from_path, 'rb') as gzfile, \ + open(filename, 'wb') as d_file: + while True: + block = gzfile.read(default_block_size) + if not block: + break + else: + d_file.write(block) + d_file.write(block) + return files + else: raise NotImplementedError( - "We currently only support tar.gz, .tgz and zip achives.") + "We currently only support tar.gz, .tgz, .gz and zip achives.") From 2fe0031076db11eba7cb2a4b8304a318aa6c280f Mon Sep 17 00:00:00 2001 From: Nayef Ahmed Date: Wed, 10 Jun 2020 08:30:50 -0700 Subject: [PATCH 12/68] Back out "Import torchtext 20200605" Summary: Original commit changeset: f22370d97796 Reviewed By: zhangguanheng66 Differential Revision: D21964222 fbshipit-source-id: c316836596fc3e232e63abc59e172f237b551cc5 --- .travis.yml | 23 + docs/source/experimental_datasets.rst | 48 +- docs/source/experimental_transforms.rst | 22 - docs/source/index.rst | 2 - test/data/test_builtin_datasets.py | 44 +- test/data/test_functional.py | 104 +--- test/test_utils.py | 28 - torchtext/csrc/regex.cpp | 44 -- torchtext/experimental/datasets/__init__.py | 3 +- .../datasets/language_modeling.py | 191 +++--- .../experimental/datasets/raw/__init__.py | 11 +- .../datasets/raw/language_modeling.py | 184 ------ .../experimental/datasets/raw/translation.py | 544 ----------------- .../experimental/datasets/translation.py | 551 ------------------ torchtext/experimental/transforms.py | 114 ---- torchtext/utils.py | 18 +- 16 files changed, 136 insertions(+), 1795 deletions(-) create mode 100644 .travis.yml delete mode 100644 docs/source/experimental_transforms.rst delete mode 100644 torchtext/csrc/regex.cpp delete mode 100644 torchtext/experimental/datasets/raw/language_modeling.py delete mode 100644 torchtext/experimental/datasets/raw/translation.py delete mode 100644 torchtext/experimental/datasets/translation.py delete mode 100644 torchtext/experimental/transforms.py diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..83f69ea383 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,23 @@ +dist: trusty + +language: python + +cache: + directories: + - /home/travis/download + - /home/travis/.cache/pip + +# This matrix tests that the code works on Python 3.5, +# 3.6 (same versions as PyTorch CI), and passes lint. +matrix: + fast_finish: true + include: + - env: PYTHON_VERSION="3.6" RUN_FLAKE8="true" SKIP_TESTS="true" + sudo: required + +notifications: + email: false + +install: source build_tools/travis/install.sh +script: bash build_tools/travis/test_script.sh +after_success: source build_tools/travis/after_success.sh diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index e9debd8224..d9d59539d0 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -1,5 +1,5 @@ torchtext.experimental.datasets -=============================== +================================ .. currentmodule:: torchtext.experimental.datasets @@ -41,13 +41,13 @@ Text Classification ^^^^^^^^^^^^^^^^^^^ TextClassificationDataset -~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: TextClassificationDataset :members: __init__ AG_NEWS -~~~~~~~ +~~~~~~ AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. @@ -55,7 +55,7 @@ AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ SogouNews -~~~~~~~~~ +~~~~~~~~ SogouNews dataset is subclass of ``TextClassificationDataset`` class. @@ -63,7 +63,7 @@ SogouNews dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ DBpedia -~~~~~~~ +~~~~~~ DBpedia dataset is subclass of ``TextClassificationDataset`` class. @@ -71,7 +71,7 @@ DBpedia dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YelpReviewPolarity -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~ YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. @@ -79,7 +79,7 @@ YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YelpReviewFull -~~~~~~~~~~~~~~ +~~~~~~~~~~~~~ YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. @@ -87,7 +87,7 @@ YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YahooAnswers -~~~~~~~~~~~~ +~~~~~~~~~~~ YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. @@ -95,7 +95,7 @@ YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ AmazonReviewPolarity -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~ AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. @@ -103,7 +103,7 @@ AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ AmazonReviewFull -~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~ AmazonReviewFull dataset is subclass of ``TextClassificationDataset`` class. @@ -139,31 +139,3 @@ PennTreebank .. autoclass:: PennTreebank :members: __init__ - - -Machine Translation -^^^^^^^^^^^^^^^^^^^ - -Language modeling datasets are subclasses of ``TranslationDataset`` class. - -.. autoclass:: TranslationDataset - :members: __init__ - -Multi30k -~~~~~~~~ - -.. autoclass:: Multi30k - :members: __init__ - -IWSLT -~~~~~ - -.. autoclass:: IWSLT - :members: __init__ - -WMT14 -~~~~~ - -.. autoclass:: WMT14 - :members: __init__ - diff --git a/docs/source/experimental_transforms.rst b/docs/source/experimental_transforms.rst deleted file mode 100644 index ff00b374ef..0000000000 --- a/docs/source/experimental_transforms.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. role:: hidden - :class: hidden-section - -torchtext.experimental.transforms -================================= - -.. automodule:: torchtext.experimental.transforms -.. currentmodule:: torchtext.experimental.transforms - -:hidden:`BasicEnglishNormalize` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: BasicEnglishNormalize - :members: - :special-members: __init__ - -:hidden:`RegexTokenizer` -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: RegexTokenizer - :members: - :special-members: __init__ \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index dfa9d7c4c0..08fb745c4f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -17,8 +17,6 @@ popular datasets for natural language. torchtext.vocab torchtext.utils experimental_datasets - experimental_functional - experimental_transforms examples .. automodule:: torchtext diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 2bb4065df9..08c75292c4 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -1,7 +1,6 @@ #!/user/bin/env python3 # Note that all the tests in this module require dataset (either network access or cached) import os -import glob import shutil import torchtext.data as data from torchtext.datasets import AG_NEWS @@ -11,11 +10,10 @@ def conditional_remove(f): - for path in glob.glob(f): - if os.path.isfile(path): - os.remove(path) - elif os.path.isdir(path): - shutil.rmtree(path) + if os.path.isfile(f): + os.remove(f) + elif os.path.isdir(f): + shutil.rmtree(f) class TestDataset(TorchtextTestCase): @@ -80,7 +78,7 @@ def test_penntreebank_legacy(self): def test_penntreebank(self): from torchtext.experimental.datasets import PennTreebank - # smoke test to ensure penn treebank works properly + # smoke test to ensure wikitext2 works properly train_dataset, test_dataset, valid_dataset = PennTreebank() self.assertEqual(len(train_dataset), 924412) self.assertEqual(len(test_dataset), 82114) @@ -124,35 +122,3 @@ def test_imdb(self): old_vocab = train_dataset.get_vocab() new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) new_train_data, new_test_data = IMDB(vocab=new_vocab) - - def test_multi30k(self): - from torchtext.experimental.datasets.translation import Multi30k - # smoke test to ensure multi30k works properly - train_dataset, valid_dataset, test_dataset = Multi30k() - self.assertEqual(len(train_dataset), 29000) - self.assertEqual(len(valid_dataset), 1000) - self.assertEqual(len(test_dataset), 1014) - - de_vocab, en_vocab = train_dataset.get_vocab() - de_tokens_ids = [ - de_vocab[token] for token in - 'Zwei Männer verpacken Donuts in Kunststofffolie'.split() - ] - self.assertEqual(de_tokens_ids, [19, 29, 18703, 4448, 5, 6240]) - - en_tokens_ids = [ - en_vocab[token] for token in - 'Two young White males are outside near many bushes'.split() - ] - self.assertEqual(en_tokens_ids, - [17, 23, 1167, 806, 15, 55, 82, 334, 1337]) - - datafile = os.path.join(self.project_root, ".data", "train*") - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", "val*") - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", "test*") - conditional_remove(datafile) - datafile = os.path.join(self.project_root, ".data", - "multi30k_task*.tar.gz") - conditional_remove(datafile) diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 9b93580f72..ff5b12ab17 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -1,12 +1,12 @@ import os +import unittest +import sys import uuid import shutil -import unittest import tempfile import sentencepiece as spm import torch -import torchtext.data as data from torchtext.data.functional import ( generate_sp_model, load_sp_model, @@ -15,10 +15,6 @@ custom_replace, simple_space_split, ) -from torchtext.experimental.transforms import ( - BasicEnglishNormalize, - RegexTokenizer -) from ..common.torchtext_test_case import TorchtextTestCase from ..common.assets import get_asset_path @@ -26,9 +22,7 @@ class TestFunctional(TorchtextTestCase): def test_generate_sp_model(self): - """ - Test the function to train a sentencepiece tokenizer. - """ + """Test the function to train a sentencepiece tokenizer""" asset_name = 'text_normalization_ag_news_test.csv' asset_path = get_asset_path(asset_name) @@ -65,6 +59,7 @@ def test_sentencepiece_numericalizer(self): ref_results) def test_sentencepiece_tokenizer(self): + test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' model_path = get_asset_path('spm_example.model') sp_model = load_sp_model(model_path) @@ -79,87 +74,6 @@ def test_sentencepiece_tokenizer(self): self.assertEqual(list(spm_generator([test_sample]))[0], ref_results) - # TODO(Nayef211): uncomment and replace the test below with this once - # https://github.com/pytorch/pytorch/issues/38207 is closed - # def test_BasicEnglishNormalize(self): - # test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' - # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', - # 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] - - # basic_english_normalize = BasicEnglishNormalize() - # experimental_eager_tokens = basic_english_normalize(test_sample) - - # jit_basic_english_normalize = torch.jit.script(basic_english_normalize) - # experimental_jit_tokens = jit_basic_english_normalize(test_sample) - - # basic_english_tokenizer = data.get_tokenizer("basic_english") - # eager_tokens = basic_english_tokenizer(test_sample) - - # self.assertEqual(experimental_jit_tokens, ref_results) - # self.assertEqual(experimental_jit_tokens, eager_tokens) - # self.assertEqual(experimental_jit_tokens, experimental_eager_tokens) - - def test_BasicEnglishNormalize(self): - test_sample = 'Basic English Normalization for a Line of Text' - ref_results = ['basic', 'english', 'normalization', - 'for', 'a', 'line', 'of', 'text'] - - basic_english_normalize = BasicEnglishNormalize() - experimental_eager_tokens = basic_english_normalize(test_sample) - - basic_english_tokenizer = data.get_tokenizer("basic_english") - tokens_eager = basic_english_tokenizer(test_sample) - - self.assertEqual(experimental_eager_tokens, ref_results) - self.assertEqual(experimental_eager_tokens, tokens_eager) - - # TODO(Nayef211): uncomment and replace the test below with this once - # https://github.com/pytorch/pytorch/issues/38207 is closed - # def test_RegexTokenizer(self): - # test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' - # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', - # 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] - # patterns_list = [ - # (r'\'', ' \' '), - # (r'\"', ''), - # (r'\.', ' . '), - # (r'
', ' '), - # (r',', ' , '), - # (r'\(', ' ( '), - # (r'\)', ' ) '), - # (r'\!', ' ! '), - # (r'\?', ' ? '), - # (r'\;', ' '), - # (r'\:', ' '), - # (r'\s+', ' ')] - - # regex_tokenizer = RegexTokenizer(patterns_list) - # eager_tokens = regex_tokenizer(test_sample) - - # jit_regex_tokenizer = torch.jit.script(regex_tokenizer) - # jit_tokens = jit_regex_tokenizer(test_sample) - - # self.assertEqual(jit_tokens, ref_results) - # self.assertEqual(jit_tokens, eager_tokens) - - def test_RegexTokenizer(self): - test_sample = '"Basic Regex Tokenization". For a Line of Text' - ref_results = ['Basic', 'Regex', 'Tokenization', '.', - 'For', 'a', 'Line', 'of', 'Text'] - patterns_list = [ - (r'\"', ''), - (r'\.', ' . '), - (r'\s+', ' ')] - - regex_tokenizer = RegexTokenizer(patterns_list) - eager_tokens = regex_tokenizer(test_sample) - - jit_regex_tokenizer = torch.jit.script(regex_tokenizer) - jit_tokens = jit_regex_tokenizer(test_sample) - - self.assertEqual(jit_tokens, eager_tokens) - self.assertEqual(jit_tokens, ref_results) - def test_custom_replace(self): custom_replace_transform = custom_replace([(r'S', 's'), (r'\s+', ' ')]) test_sample = ['test cuStom replace', 'with uSer instruction'] @@ -195,11 +109,11 @@ def encode_as_pieces(self, input: str): class TestScriptableSP(unittest.TestCase): def setUp(self): model_path = get_asset_path('spm_example.model') - with tempfile.TemporaryDirectory() as dir_name: - jit_model_path = os.path.join(dir_name, 'spm_example.model') - torch.jit.script(ScriptableSP(model_path)).save(jit_model_path) - self.model = torch.jit.load(jit_model_path) + with tempfile.NamedTemporaryFile() as file: + torch.jit.script(ScriptableSP(model_path)).save(file.name) + self.model = torch.jit.load(file.name) + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ @@ -211,6 +125,7 @@ def test_encode(self): output = self.model.encode(input) self.assertEqual(expected, output) + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode_as_ids(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ @@ -219,6 +134,7 @@ def test_encode_as_ids(self): output = self.model.encode_as_ids(input) self.assertEqual(expected, output) + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode_as_pieces(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ diff --git a/test/test_utils.py b/test/test_utils.py index 73ee992de3..5489f838b2 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -42,34 +42,6 @@ def test_download_extract_tar(self): conditional_remove(f) conditional_remove(archive_path) - def test_download_extract_gz(self): - # create root directory for downloading data - root = '.data' - if not os.path.exists(root): - os.makedirs(root) - - # ensure archive is not already downloaded, if it is then delete - url = 'https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz' - target_archive_path = os.path.join(root, 'val.5.en.gz') - conditional_remove(target_archive_path) - - # download archive and ensure is in correct location - archive_path = utils.download_from_url(url) - assert target_archive_path == archive_path - - # extract files and ensure they are correct - files = utils.extract_archive(archive_path) - assert files == [os.path.join(root, 'val.5.en')] - - # extract files with overwrite option True - files = utils.extract_archive(archive_path, overwrite=True) - assert files == [os.path.join(root, 'val.5.en')] - - # remove files and archive - for f in files: - conditional_remove(f) - conditional_remove(archive_path) - def test_download_extract_zip(self): # create root directory for downloading data root = '.data' diff --git a/torchtext/csrc/regex.cpp b/torchtext/csrc/regex.cpp deleted file mode 100644 index 8e6db16507..0000000000 --- a/torchtext/csrc/regex.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include - -namespace torchtext { -namespace { - -struct Regex : torch::CustomClassHolder { -private: - std::regex re_; - -public: - // re_str_ holds the serialized regex string passed at the initialization. - // We need this because we need to be able to serialize the model so that we - // can save the scripted object. pickle will get the - // serialized model from this re_str_ member, thus it needs to be public. - std::string re_str_; - - explicit Regex(const std::string &re_str) : re_str_(re_str) { - re_ = std::regex(re_str_); - } - - std::string Sub(const std::string &str, const std::string &repl) const { - return std::regex_replace(str, re_, repl); - } -}; - -// Registers our custom class with torch. -static auto regex = - torch::class_("torchtext", "Regex") - .def(torch::init()) - .def("Sub", &Regex::Sub) - .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> std::string { - return self->re_str_; - }, - // __setstate__ - [](std::string state) -> c10::intrusive_ptr { - return c10::make_intrusive(std::move(state)); - }); - -} // namespace -} // namespace torchtext diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index d91f60ff55..ac2faa423b 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -1,4 +1,4 @@ -from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank, WMTNewsCrawl # NOQA +from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank # NOQA from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB @@ -7,7 +7,6 @@ 'WikiText2', 'WikiText103', 'PennTreebank', - 'WMTNewsCrawl', 'IMDB', 'AG_NEWS', 'SogouNews', diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index f44de4af88..6c0ec5799e 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -1,15 +1,22 @@ import torch -from torchtext.data.utils import get_tokenizer +import logging +import io +from torchtext.utils import download_from_url, extract_archive from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets.raw import language_modeling as raw -from torchtext.experimental.functional import vocab_func, totensor, sequential_transforms - - -def build_vocab(data, transforms): - tok_list = [] - for txt in data: - tok_list.append(transforms(txt)) - return build_vocab_from_iterator(tok_list) +from torchtext.data.utils import get_tokenizer +from torchtext.vocab import Vocab +from torchtext.data.functional import numericalize_tokens_from_iterator + +URLS = { + 'WikiText2': + 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip', + 'WikiText103': + 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip', + 'PennTreebank': + ['https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt', + 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt', + 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt'] +} class LanguageModelingDataset(torch.utils.data.Dataset): @@ -19,11 +26,10 @@ class LanguageModelingDataset(torch.utils.data.Dataset): - WikiText2 - WikiText103 - PennTreebank - - WMTNewsCrawl """ - def __init__(self, data, vocab, transforms, single_line): + def __init__(self, data, vocab): """Initiate language modeling dataset. Arguments: @@ -31,24 +37,22 @@ def __init__(self, data, vocab, transforms, single_line): numericalizing the string tokens. torch.tensor([token_id_1, token_id_2, token_id_3, token_id1]).long() vocab: Vocabulary object used for dataset. - transforms: Text string transforms. + + Examples: + >>> from torchtext.vocab import build_vocab_from_iterator + >>> data = torch.tensor([token_id_1, token_id_2, + token_id_3, token_id_1]).long() + >>> vocab = build_vocab_from_iterator([['language', 'modeling']]) + >>> dataset = LanguageModelingDataset(data, vocab) """ super(LanguageModelingDataset, self).__init__() + self.data = data self.vocab = vocab - self.transforms = transforms - self.single_line = single_line - if single_line: - self.data = torch.cat(tuple(transforms(row) for row in data), axis=0) - else: - self.data = data def __getitem__(self, i): - if self.single_line: - return self.data[i] - else: - return self.transforms(self.data[i]) + return self.data[i] def __len__(self): return len(self.data) @@ -61,45 +65,63 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, tokenizer=None, root='.data', vocab=None, - data_select=('train', 'test', 'valid'), single_line=True): - if tokenizer is None: - tokenizer = get_tokenizer('basic_english') - text_transform = sequential_transforms(tokenizer) +def _get_datafile_path(key, extracted_files): + for fname in extracted_files: + if key in fname: + return fname + + +def _setup_datasets(dataset_name, tokenizer=get_tokenizer("basic_english"), + root='.data', vocab=None, removed_tokens=[], + data_select=('train', 'test', 'valid')): if isinstance(data_select, str): data_select = [data_select] - if not set(data_select).issubset(set(('train', 'valid', 'test'))): - raise TypeError('Given data selection {} is not supported!'.format(data_select)) - - if not single_line and dataset_name != 'WikiText103': - raise TypeError('single_line must be True except for WikiText103') - if dataset_name == 'WMTNewsCrawl': - train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) - if single_line: - raw_data = {'train': [" ".join([txt for txt in train]), ]} - else: - raw_data = {'train': [txt for txt in train]} + if not set(data_select).issubset(set(('train', 'test', 'valid'))): + raise TypeError('data_select is not supported!') + + if dataset_name == 'PennTreebank': + extracted_files = [] + select_to_index = {'train': 0, 'test': 1, 'valid': 2} + extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], + root=root) for key in data_select] else: - train, test, valid = raw.DATASETS[dataset_name](root=root, data_select=('train', 'test', 'valid')) - # Cache raw text iterable dataset - if single_line: - raw_data = {'train': [" ".join([txt for txt in train]), ], - 'valid': [" ".join(txt for txt in valid), ], - 'test': [" ".join(txt for txt in test), ]} - else: - raw_data = {'train': [txt for txt in train], - 'valid': [txt for txt in valid], - 'test': [txt for txt in test]} + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files = extract_archive(dataset_tar) + + _path = {} + for item in data_select: + _path[item] = _get_datafile_path(item, extracted_files) if vocab is None: - if 'train' not in data_select: + if 'train' not in _path.keys(): raise TypeError("Must pass a vocab if train is not selected.") - vocab = build_vocab(raw_data['train'], text_transform) - text_transform = sequential_transforms(text_transform, vocab_func(vocab), - totensor(dtype=torch.long)) - return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform, single_line) - for item in data_select) + logging.info('Building Vocab based on {}'.format(_path['train'])) + txt_iter = iter(tokenizer(row) for row in io.open(_path['train'], + encoding="utf8")) + vocab = build_vocab_from_iterator(txt_iter) + logging.info('Vocab has {} entries'.format(len(vocab))) + else: + if not isinstance(vocab, Vocab): + raise TypeError("Passed vocabulary is not of type Vocab") + + data = {} + for item in _path.keys(): + data[item] = [] + logging.info('Creating {} data'.format(item)) + txt_iter = iter(tokenizer(row) for row in io.open(_path[item], + encoding="utf8")) + _iter = numericalize_tokens_from_iterator( + vocab, txt_iter, removed_tokens) + for tokens in _iter: + data[item] += [token_id for token_id in tokens] + + for key in data_select: + if data[key] == []: + raise TypeError('Dataset {} is empty!'.format(key)) + + return tuple(LanguageModelingDataset(torch.tensor(data[d]).long(), vocab) + for d in data_select) def WikiText2(*args, **kwargs): @@ -116,6 +138,7 @@ def WikiText2(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. + removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -123,10 +146,6 @@ def WikiText2(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText2 @@ -156,6 +175,12 @@ def WikiText103(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. + data_select: the returned datasets (Default: ('train', 'test','valid')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test'). + If 'train' is not in the tuple, an vocab object should be provided which will + be used to process valid and/or test data. + removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -163,10 +188,6 @@ def WikiText103(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText103 @@ -196,6 +217,7 @@ def PennTreebank(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. + removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -203,10 +225,6 @@ def PennTreebank(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import PennTreebank @@ -220,42 +238,3 @@ def PennTreebank(*args, **kwargs): """ return _setup_datasets(*(("PennTreebank",) + args), **kwargs) - - -def WMTNewsCrawl(*args, **kwargs): - """ Defines WMTNewsCrawl datasets. - - Create language modeling dataset: WMTNewsCrawl - returns the train set - - Arguments: - tokenizer: the tokenizer used to preprocess raw text data. - The default one is basic_english tokenizer in fastText. spacy tokenizer - is supported as well (see example below). A custom tokenizer is callable - function with input of a string and output of a token list. - root: Directory where the datasets are saved. Default: ".data" - vocab: Vocabulary used for dataset. If None, it will generate a new - vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets - (Default: ('train',)) - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. - Examples: - >>> from torchtext.experimental.datasets import WMTNewsCrawl - >>> from torchtext.data.utils import get_tokenizer - >>> tokenizer = get_tokenizer("spacy") - >>> train_dataset, = WMTNewsCrawl(tokenizer=tokenizer, data_select='train') - - """ - - return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) - - -DATASETS = { - 'WikiText2': WikiText2, - 'WikiText103': WikiText103, - 'PennTreebank': PennTreebank, - 'WMTNewsCrawl': WMTNewsCrawl -} diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py index 26892050d6..61accbe2a1 100644 --- a/torchtext/experimental/datasets/raw/__init__.py +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -1,8 +1,6 @@ from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB -from .translation import Multi30k, IWSLT, WMT14 -from .language_modeling import WikiText2, WikiText103, PennTreebank, WMTNewsCrawl __all__ = ['IMDB', 'AG_NEWS', @@ -12,11 +10,4 @@ 'YelpReviewFull', 'YahooAnswers', 'AmazonReviewPolarity', - 'AmazonReviewFull', - 'Multi30k', - 'IWSLT', - 'WMT14', - 'WikiText2', - 'WikiText103', - 'PennTreebank', - 'WMTNewsCrawl'] + 'AmazonReviewFull'] diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py deleted file mode 100644 index a867108978..0000000000 --- a/torchtext/experimental/datasets/raw/language_modeling.py +++ /dev/null @@ -1,184 +0,0 @@ -import torch -import logging -import io -from torchtext.utils import download_from_url, extract_archive - -URLS = { - 'WikiText2': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip', - 'WikiText103': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip', - 'PennTreebank': - ['https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt'], - 'WMTNewsCrawl': 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' -} - - -class RawTextIterableDataset(torch.utils.data.IterableDataset): - """Defines an abstraction for raw text iterable datasets. - """ - - def __init__(self, iterator, start=0, num_lines=None): - """Initiate language modeling dataset. - """ - super(RawTextIterableDataset, self).__init__() - self._iterator = iterator - self.has_setup = False - self.start = start - self.num_lines = num_lines - - def setup_iter(self, start=0, num_lines=None): - self.start = start - self.num_lines = num_lines - self.has_setup = True - - def __iter__(self): - if not self.has_setup: - self.setup_iter() - for i, item in enumerate(self._iterator): - if i >= self.start: - yield item - if (self.num_lines is not None) and (i == (self.start + self.num_lines)): - break - - def get_iterator(self): - return self._iterator - - -def _setup_datasets(dataset_name, root='.data', data_select=('train', 'test', 'valid'), **kwargs): - if isinstance(data_select, str): - data_select = [data_select] - if not set(data_select).issubset(set(('train', 'test', 'valid'))): - raise TypeError('data_select is not supported!') - - if dataset_name == 'PennTreebank': - extracted_files = [] - select_to_index = {'train': 0, 'test': 1, 'valid': 2} - extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], - root=root) for key in data_select] - elif dataset_name == 'WMTNewsCrawl': - if not (data_select == ['train'] or set(data_select).issubset(set(('train',)))): - raise ValueError("WMTNewsCrawl only creates a training dataset. " - "data_select should be 'train' " - "or ('train',), got {}.".format(data_select)) - dataset_tar = download_from_url(URLS[dataset_name], root=root) - extracted_files = extract_archive(dataset_tar) - year = kwargs.get('year', 2010) - language = kwargs.get('language', 'en') - file_name = 'news.{}.{}.shuffled'.format(year, language) - extracted_files = [f for f in extracted_files if file_name in f] - else: - dataset_tar = download_from_url(URLS[dataset_name], root=root) - extracted_files = extract_archive(dataset_tar) - - _path = {} - for item in data_select: - for fname in extracted_files: - if item in fname: - _path[item] = fname - - data = {} - for item in _path.keys(): - logging.info('Creating {} data'.format(item)) - data[item] = iter(io.open(_path[item], encoding="utf8")) - - return tuple(RawTextIterableDataset(data[item]) for item in data_select) - - -def WikiText2(*args, **kwargs): - """ Defines WikiText2 datasets. - - Create language modeling dataset: WikiText2 - Separately returns the train/test/valid set - - Arguments: - root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tupel for the returned datasets - (Default: ('train', 'test','valid')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - - Examples: - >>> from torchtext.experimental.raw.datasets import WikiText2 - >>> train_dataset, test_dataset, valid_dataset = WikiText2() - >>> valid_dataset, = WikiText2(data_select='valid') - - """ - - return _setup_datasets(*(("WikiText2",) + args), **kwargs) - - -def WikiText103(*args, **kwargs): - """ Defines WikiText103 datasets. - - Create language modeling dataset: WikiText103 - Separately returns the train/test/valid set - - Arguments: - root: Directory where the datasets are saved. Default: ".data" - data_select: the returned datasets (Default: ('train', 'test','valid')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test'). - If 'train' is not in the tuple, an vocab object should be provided which will - be used to process valid and/or test data. - - Examples: - >>> from torchtext.experimental.datasets.raw import WikiText103 - >>> train_dataset, test_dataset, valid_dataset = WikiText103() - >>> valid_dataset, = WikiText103(data_select='valid') - """ - - return _setup_datasets(*(("WikiText103",) + args), **kwargs) - - -def PennTreebank(*args, **kwargs): - """ Defines PennTreebank datasets. - - Create language modeling dataset: PennTreebank - Separately returns the train/test/valid set - - Arguments: - root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets - (Default: ('train', 'test','valid')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - - Examples: - >>> from torchtext.experimental.datasets.raw import PennTreebank - >>> train_dataset, test_dataset, valid_dataset = PennTreebank() - >>> valid_dataset, = PennTreebank(data_select='valid') - - """ - - return _setup_datasets(*(("PennTreebank",) + args), **kwargs) - - -def WMTNewsCrawl(*args, **kwargs): - """ Defines WMT News Crawl. - - Create language modeling dataset: WMTNewsCrawl - - Arguments: - root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. - (Default: 'train') - """ - - return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) - - -DATASETS = { - 'WikiText2': WikiText2, - 'WikiText103': WikiText103, - 'PennTreebank': PennTreebank, - 'WMTNewsCrawl': WMTNewsCrawl -} diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py deleted file mode 100644 index 19f5275d41..0000000000 --- a/torchtext/experimental/datasets/raw/translation.py +++ /dev/null @@ -1,544 +0,0 @@ -import torch -import os -import io -import codecs -import xml.etree.ElementTree as ET -from collections import defaultdict - -from torchtext.utils import (download_from_url, extract_archive, - unicode_csv_reader) - -URLS = { - 'Multi30k': [ - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz" - ], - 'WMT14': - 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8', - 'IWSLT': - 'https://wit3.fbk.eu/archive/2016-01//texts/{}/{}/{}.tgz' -} - - -def _read_text_iterator(path): - with io.open(path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield " ".join(row) - - -def _clean_xml_file(f_xml): - f_txt = os.path.splitext(f_xml)[0] - with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: - root = ET.parse(f_xml).getroot()[0] - for doc in root.findall('doc'): - for e in doc.findall('seg'): - fd_txt.write(e.text.strip() + '\n') - - -def _clean_tags_file(f_orig): - xml_tags = [ - '= self.start: - yield item - if (self.num_lines is not None) and (i == (self.start + - self.num_lines)): - break - - def get_iterator(self): - return (self._src_iterator, self._tgt_iterator) - - -def Multi30k(train_filenames=("train.de", "train.en"), - valid_filenames=("val.de", "val.en"), - test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), - root='.data'): - """ Define translation datasets: Multi30k - Separately returns train/valid/test datasets as a tuple - The available dataset include: - test_2016_flickr.cs - test_2016_flickr.de - test_2016_flickr.en - test_2016_flickr.fr - test_2017_flickr.de - test_2017_flickr.en - test_2017_flickr.fr - test_2017_mscoco.de - test_2017_mscoco.en - test_2017_mscoco.fr - test_2018_flickr.en - train.cs - train.de - train.en - train.fr - val.cs - val.de - val.en - val.fr - test_2016.1.de - test_2016.1.en - test_2016.2.de - test_2016.2.en - test_2016.3.de - test_2016.3.en - test_2016.4.de - test_2016.4.en - test_2016.5.de - test_2016.5.en - train.1.de - train.1.en - train.2.de - train.2.en - train.3.de - train.3.en - train.4.de - train.4.en - train.5.de - train.5.en - val.1.de - val.1.en - val.2.de - val.2.en - val.3.de - val.3.en - val.4.de - val.4.en - val.5.de - val.5.en - - Arguments: - train_filenames: the source and target filenames for training. - Default: ('train.de', 'train.en') - valid_filenames: the source and target filenames for valid. - Default: ('val.de', 'val.en') - test_filenames: the source and target filenames for test. - Default: ('test2016.de', 'test2016.en') - root: Directory where the datasets are saved. Default: ".data" - - Examples: - >>> from torchtext.datasets import Multi30k - >>> train_dataset, valid_dataset, test_dataset = Multi30k() - """ - return _setup_datasets("Multi30k", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root) - - -def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), - valid_filenames=('IWSLT16.TED.tst2013.de-en.de', - 'IWSLT16.TED.tst2013.de-en.en'), - test_filenames=('IWSLT16.TED.tst2014.de-en.de', - 'IWSLT16.TED.tst2014.de-en.en'), - root='.data'): - """ Define translation datasets: IWSLT - Separately returns train/valid/test datasets - The available datasets include: - IWSLT16.TED.dev2010.ar-en.ar - IWSLT16.TED.dev2010.ar-en.en - IWSLT16.TED.dev2010.cs-en.cs - IWSLT16.TED.dev2010.cs-en.en - IWSLT16.TED.dev2010.de-en.de - IWSLT16.TED.dev2010.de-en.en - IWSLT16.TED.dev2010.en-ar.ar - IWSLT16.TED.dev2010.en-ar.en - IWSLT16.TED.dev2010.en-cs.cs - IWSLT16.TED.dev2010.en-cs.en - IWSLT16.TED.dev2010.en-de.de - IWSLT16.TED.dev2010.en-de.en - IWSLT16.TED.dev2010.en-fr.en - IWSLT16.TED.dev2010.en-fr.fr - IWSLT16.TED.dev2010.fr-en.en - IWSLT16.TED.dev2010.fr-en.fr - IWSLT16.TED.tst2010.ar-en.ar - IWSLT16.TED.tst2010.ar-en.en - IWSLT16.TED.tst2010.cs-en.cs - IWSLT16.TED.tst2010.cs-en.en - IWSLT16.TED.tst2010.de-en.de - IWSLT16.TED.tst2010.de-en.en - IWSLT16.TED.tst2010.en-ar.ar - IWSLT16.TED.tst2010.en-ar.en - IWSLT16.TED.tst2010.en-cs.cs - IWSLT16.TED.tst2010.en-cs.en - IWSLT16.TED.tst2010.en-de.de - IWSLT16.TED.tst2010.en-de.en - IWSLT16.TED.tst2010.en-fr.en - IWSLT16.TED.tst2010.en-fr.fr - IWSLT16.TED.tst2010.fr-en.en - IWSLT16.TED.tst2010.fr-en.fr - IWSLT16.TED.tst2011.ar-en.ar - IWSLT16.TED.tst2011.ar-en.en - IWSLT16.TED.tst2011.cs-en.cs - IWSLT16.TED.tst2011.cs-en.en - IWSLT16.TED.tst2011.de-en.de - IWSLT16.TED.tst2011.de-en.en - IWSLT16.TED.tst2011.en-ar.ar - IWSLT16.TED.tst2011.en-ar.en - IWSLT16.TED.tst2011.en-cs.cs - IWSLT16.TED.tst2011.en-cs.en - IWSLT16.TED.tst2011.en-de.de - IWSLT16.TED.tst2011.en-de.en - IWSLT16.TED.tst2011.en-fr.en - IWSLT16.TED.tst2011.en-fr.fr - IWSLT16.TED.tst2011.fr-en.en - IWSLT16.TED.tst2011.fr-en.fr - IWSLT16.TED.tst2012.ar-en.ar - IWSLT16.TED.tst2012.ar-en.en - IWSLT16.TED.tst2012.cs-en.cs - IWSLT16.TED.tst2012.cs-en.en - IWSLT16.TED.tst2012.de-en.de - IWSLT16.TED.tst2012.de-en.en - IWSLT16.TED.tst2012.en-ar.ar - IWSLT16.TED.tst2012.en-ar.en - IWSLT16.TED.tst2012.en-cs.cs - IWSLT16.TED.tst2012.en-cs.en - IWSLT16.TED.tst2012.en-de.de - IWSLT16.TED.tst2012.en-de.en - IWSLT16.TED.tst2012.en-fr.en - IWSLT16.TED.tst2012.en-fr.fr - IWSLT16.TED.tst2012.fr-en.en - IWSLT16.TED.tst2012.fr-en.fr - IWSLT16.TED.tst2013.ar-en.ar - IWSLT16.TED.tst2013.ar-en.en - IWSLT16.TED.tst2013.cs-en.cs - IWSLT16.TED.tst2013.cs-en.en - IWSLT16.TED.tst2013.de-en.de - IWSLT16.TED.tst2013.de-en.en - IWSLT16.TED.tst2013.en-ar.ar - IWSLT16.TED.tst2013.en-ar.en - IWSLT16.TED.tst2013.en-cs.cs - IWSLT16.TED.tst2013.en-cs.en - IWSLT16.TED.tst2013.en-de.de - IWSLT16.TED.tst2013.en-de.en - IWSLT16.TED.tst2013.en-fr.en - IWSLT16.TED.tst2013.en-fr.fr - IWSLT16.TED.tst2013.fr-en.en - IWSLT16.TED.tst2013.fr-en.fr - IWSLT16.TED.tst2014.ar-en.ar - IWSLT16.TED.tst2014.ar-en.en - IWSLT16.TED.tst2014.de-en.de - IWSLT16.TED.tst2014.de-en.en - IWSLT16.TED.tst2014.en-ar.ar - IWSLT16.TED.tst2014.en-ar.en - IWSLT16.TED.tst2014.en-de.de - IWSLT16.TED.tst2014.en-de.en - IWSLT16.TED.tst2014.en-fr.en - IWSLT16.TED.tst2014.en-fr.fr - IWSLT16.TED.tst2014.fr-en.en - IWSLT16.TED.tst2014.fr-en.fr - IWSLT16.TEDX.dev2012.de-en.de - IWSLT16.TEDX.dev2012.de-en.en - IWSLT16.TEDX.tst2013.de-en.de - IWSLT16.TEDX.tst2013.de-en.en - IWSLT16.TEDX.tst2014.de-en.de - IWSLT16.TEDX.tst2014.de-en.en - train.ar - train.ar-en.ar - train.ar-en.en - train.cs - train.cs-en.cs - train.cs-en.en - train.de - train.de-en.de - train.de-en.en - train.en - train.en-ar.ar - train.en-ar.en - train.en-cs.cs - train.en-cs.en - train.en-de.de - train.en-de.en - train.en-fr.en - train.en-fr.fr - train.fr - train.fr-en.en - train.fr-en.fr - train.tags.ar-en.ar - train.tags.ar-en.en - train.tags.cs-en.cs - train.tags.cs-en.en - train.tags.de-en.de - train.tags.de-en.en - train.tags.en-ar.ar - train.tags.en-ar.en - train.tags.en-cs.cs - train.tags.en-cs.en - train.tags.en-de.de - train.tags.en-de.en - train.tags.en-fr.en - train.tags.en-fr.fr - train.tags.fr-en.en - train.tags.fr-en.fr - - Arguments: - train_filenames: the source and target filenames for training. - Default: ('train.de-en.de', 'train.de-en.en') - valid_filenames: the source and target filenames for valid. - Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') - test_filenames: the source and target filenames for test. - Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') - root: Directory where the datasets are saved. Default: ".data" - - Examples: - >>> from torchtext.datasets.raw import IWSLT - >>> train_dataset, valid_dataset, test_dataset = IWSLT() - """ - src_language = train_filenames[0].split(".")[-1] - tgt_language = train_filenames[1].split(".")[-1] - languages = "-".join([src_language, tgt_language]) - URLS["IWSLT"] = URLS["IWSLT"].format(src_language, tgt_language, languages) - - return _setup_datasets( - "IWSLT", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root, - ) - - -def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', - 'train.tok.clean.bpe.32000.en'), - valid_filenames=('newstest2013.tok.bpe.32000.de', - 'newstest2013.tok.bpe.32000.en'), - test_filenames=('newstest2014.tok.bpe.32000.de', - 'newstest2014.tok.bpe.32000.en'), - root='.data'): - """ Define translation datasets: WMT14 - Separately returns train/valid/test datasets - The available datasets include: - newstest2016.en - newstest2016.de - newstest2015.en - newstest2015.de - newstest2014.en - newstest2014.de - newstest2013.en - newstest2013.de - newstest2012.en - newstest2012.de - newstest2011.tok.de - newstest2011.en - newstest2011.de - newstest2010.tok.de - newstest2010.en - newstest2010.de - newstest2009.tok.de - newstest2009.en - newstest2009.de - newstest2016.tok.de - newstest2015.tok.de - newstest2014.tok.de - newstest2013.tok.de - newstest2012.tok.de - newstest2010.tok.en - newstest2009.tok.en - newstest2015.tok.en - newstest2014.tok.en - newstest2013.tok.en - newstest2012.tok.en - newstest2011.tok.en - newstest2016.tok.en - newstest2009.tok.bpe.32000.en - newstest2011.tok.bpe.32000.en - newstest2010.tok.bpe.32000.en - newstest2013.tok.bpe.32000.en - newstest2012.tok.bpe.32000.en - newstest2015.tok.bpe.32000.en - newstest2014.tok.bpe.32000.en - newstest2016.tok.bpe.32000.en - train.tok.clean.bpe.32000.en - newstest2009.tok.bpe.32000.de - newstest2010.tok.bpe.32000.de - newstest2011.tok.bpe.32000.de - newstest2013.tok.bpe.32000.de - newstest2012.tok.bpe.32000.de - newstest2014.tok.bpe.32000.de - newstest2016.tok.bpe.32000.de - newstest2015.tok.bpe.32000.de - train.tok.clean.bpe.32000.de - - Arguments: - train_filenames: the source and target filenames for training. - Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') - valid_filenames: the source and target filenames for valid. - Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') - test_filenames: the source and target filenames for test. - Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') - root: Directory where the datasets are saved. Default: ".data" - - Examples: - >>> from torchtext.datasets import WMT14 - >>> train_dataset, valid_dataset, test_dataset = WMT14() - """ - - return _setup_datasets("WMT14", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root) - - -DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py deleted file mode 100644 index 5fad51135d..0000000000 --- a/torchtext/experimental/datasets/translation.py +++ /dev/null @@ -1,551 +0,0 @@ -import torch -import logging - -from torchtext.experimental.datasets import raw -from torchtext.vocab import build_vocab_from_iterator -from torchtext.data.utils import get_tokenizer -from ..functional import vocab_func, totensor, sequential_transforms - - -def build_vocab(data, transforms, index): - tok_list = [] - for line in data: - tok_list.append(transforms(line[index])) - return build_vocab_from_iterator(tok_list) - - -def _setup_datasets(dataset_name, - train_filenames, - valid_filenames, - test_filenames, - data_select=('train', 'test', 'valid'), - root='.data', - vocab=(None, None), - tokenizer=None, - removed_tokens=['']): - src_vocab, tgt_vocab = vocab - if tokenizer is None: - src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') - tgt_tokenizer = get_tokenizer("spacy", language='en_core_web_sm') - elif isinstance(tokenizer, tuple): - if len(tokenizer) == 2: - src_tokenizer, tgt_tokenizer = tokenizer - else: - raise ValueError("tokenizer must have length of two for" - "source and target") - else: - raise ValueError( - "tokenizer must be an instance of tuple with length two" - "or None") - train, val, test = DATASETS[dataset_name](train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root) - raw_data = { - "train": [line for line in train], - "valid": [line for line in val], - "test": [line for line in test] - } - src_text_vocab_transform = sequential_transforms(src_tokenizer) - tgt_text_vocab_transform = sequential_transforms(tgt_tokenizer) - - if src_vocab is None: - if 'train' not in data_select: - raise TypeError("Must pass a vocab if train is not selected.") - logging.info('Building src Vocab based on train data') - src_vocab = build_vocab(raw_data["train"], - src_text_vocab_transform, - index=0) - else: - if not isinstance(src_vocab, Vocab): - raise TypeError("Passed src vocabulary is not of type Vocab") - logging.info('src Vocab has {} entries'.format(len(src_vocab))) - - if tgt_vocab is None: - if 'train' not in data_select: - raise TypeError("Must pass a vocab if train is not selected.") - logging.info('Building tgt Vocab based on train data') - tgt_vocab = build_vocab(raw_data["train"], - tgt_text_vocab_transform, - index=1) - else: - if not isinstance(tgt_vocab, Vocab): - raise TypeError("Passed tgt vocabulary is not of type Vocab") - logging.info('tgt Vocab has {} entries'.format(len(tgt_vocab))) - - logging.info('Building datasets for {}'.format(data_select)) - datasets = [] - for key in data_select: - src_text_transform = sequential_transforms(src_text_vocab_transform, - vocab_func(src_vocab), - totensor(dtype=torch.long)) - tgt_text_transform = sequential_transforms(tgt_text_vocab_transform, - vocab_func(tgt_vocab), - totensor(dtype=torch.long)) - datasets.append( - TranslationDataset(raw_data[key], (src_vocab, tgt_vocab), - (src_text_transform, tgt_text_transform))) - - return tuple(datasets) - - -class TranslationDataset(torch.utils.data.Dataset): - """Defines a dataset for translation. - Currently, we only support the following datasets: - - Multi30k - - WMT14 - - IWSLT - """ - def __init__(self, data, vocab, transforms): - """Initiate translation dataset. - - Arguments: - data: a tuple of source and target tensors, which include token ids - numericalizing the string tokens. - [(src_tensor0, tgt_tensor0), (src_tensor1, tgt_tensor1)] - vocab: source and target Vocabulary object used for dataset. - (src_vocab, tgt_vocab) - transforms: a tuple of source and target string transforms. - - Examples: - >>> from torchtext.vocab import build_vocab_from_iterator - >>> src_data = torch.Tensor([token_id_s1, token_id_s2, - token_id_s3, token_id_s1]).long() - >>> tgt_data = torch.Tensor([token_id_t1, token_id_t2, - token_id_t3, token_id_t1]).long() - >>> src_vocab = build_vocab_from_iterator([['Übersetzungsdatensatz']]) - >>> tgt_vocab = build_vocab_from_iterator([['translation', 'dataset']]) - >>> dataset = TranslationDataset([(src_data, tgt_data)], - (src_vocab, tgt_vocab)) - """ - - super(TranslationDataset, self).__init__() - self.data = data - self.vocab = vocab - self.transforms = transforms - - def __getitem__(self, i): - source = self.transforms[0](self.data[i][0]) - target = self.transforms[1](self.data[i][1]) - return (source, target) - - def __len__(self): - return len(self.data) - - def get_vocab(self): - return self.vocab - - -def Multi30k(train_filenames=("train.de", "train.en"), - valid_filenames=("val.de", "val.en"), - test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), - tokenizer=None, - root='.data', - vocab=(None, None), - data_select=('train', 'valid', 'test'), - removed_tokens=['']): - """ Define translation datasets: Multi30k - Separately returns train/valid/test datasets as a tuple - - Arguments: - train_filenames: the source and target filenames for training. - Default: ('train.de', 'train.en') - valid_filenames: the source and target filenames for valid. - Default: ('val.de', 'val.en') - test_filenames: the source and target filenames for test. - Default: ('test2016.de', 'test2016.en') - tokenizer: the tokenizer used to preprocess source and target raw text data. - It has to be in a form of tuple. - Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) - root: Directory where the datasets are saved. Default: ".data" - vocab: Source and target Vocabulary objects used for dataset. If None, it - will generate a new vocabulary based on the train data set. It has to be - in a form of tuple. - Default: (None, None) - data_select: a string or tuple for the returned datasets - (Default: ('train', 'valid', 'test')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - removed_tokens: removed tokens from output dataset (Default: '') - The available dataset include: - test_2016_flickr.cs - test_2016_flickr.de - test_2016_flickr.en - test_2016_flickr.fr - test_2017_flickr.de - test_2017_flickr.en - test_2017_flickr.fr - test_2017_mscoco.de - test_2017_mscoco.en - test_2017_mscoco.fr - test_2018_flickr.en - train.cs - train.de - train.en - train.fr - val.cs - val.de - val.en - val.fr - test_2016.1.de - test_2016.1.en - test_2016.2.de - test_2016.2.en - test_2016.3.de - test_2016.3.en - test_2016.4.de - test_2016.4.en - test_2016.5.de - test_2016.5.en - train.1.de - train.1.en - train.2.de - train.2.en - train.3.de - train.3.en - train.4.de - train.4.en - train.5.de - train.5.en - val.1.de - val.1.en - val.2.de - val.2.en - val.3.de - val.3.en - val.4.de - val.4.en - val.5.de - val.5.en - - Examples: - >>> from torchtext.datasets import Multi30k - >>> from torchtext.data.utils import get_tokenizer - >>> tokenizer = (get_tokenizer("spacy", language='de'), - get_tokenizer("basic_english")) - >>> train_dataset, valid_dataset, test_dataset = Multi30k(tokenizer=tokenizer) - >>> src_vocab, tgt_vocab = train_dataset.get_vocab() - >>> src_data, tgt_data = train_dataset[10] - """ - return _setup_datasets("Multi30k", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - tokenizer=tokenizer, - root=root, - vocab=vocab, - removed_tokens=removed_tokens) - - -def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), - valid_filenames=('IWSLT16.TED.tst2013.de-en.de', - 'IWSLT16.TED.tst2013.de-en.en'), - test_filenames=('IWSLT16.TED.tst2014.de-en.de', - 'IWSLT16.TED.tst2014.de-en.en'), - tokenizer=None, - root='.data', - vocab=(None, None), - data_select=('train', 'valid', 'test'), - removed_tokens=['']): - """ Define translation datasets: IWSLT - Separately returns train/valid/test datasets - The available datasets include: - - Arguments: - train_filenames: the source and target filenames for training. - Default: ('train.de-en.de', 'train.de-en.en') - valid_filenames: the source and target filenames for valid. - Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') - test_filenames: the source and target filenames for test. - Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') - tokenizer: the tokenizer used to preprocess source and target raw text data. - It has to be in a form of tuple. - Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) - root: Directory where the datasets are saved. Default: ".data" - vocab: Source and target Vocabulary objects used for dataset. If None, it - will generate a new vocabulary based on the train data set. It has to be - in a form of tuple. - Default: (None, None) - data_select: a string or tuple for the returned datasets - (Default: ('train', 'valid', 'test')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - removed_tokens: removed tokens from output dataset (Default: '') - The available datasets include: - IWSLT16.TED.dev2010.ar-en.ar - IWSLT16.TED.dev2010.ar-en.en - IWSLT16.TED.dev2010.cs-en.cs - IWSLT16.TED.dev2010.cs-en.en - IWSLT16.TED.dev2010.de-en.de - IWSLT16.TED.dev2010.de-en.en - IWSLT16.TED.dev2010.en-ar.ar - IWSLT16.TED.dev2010.en-ar.en - IWSLT16.TED.dev2010.en-cs.cs - IWSLT16.TED.dev2010.en-cs.en - IWSLT16.TED.dev2010.en-de.de - IWSLT16.TED.dev2010.en-de.en - IWSLT16.TED.dev2010.en-fr.en - IWSLT16.TED.dev2010.en-fr.fr - IWSLT16.TED.dev2010.fr-en.en - IWSLT16.TED.dev2010.fr-en.fr - IWSLT16.TED.tst2010.ar-en.ar - IWSLT16.TED.tst2010.ar-en.en - IWSLT16.TED.tst2010.cs-en.cs - IWSLT16.TED.tst2010.cs-en.en - IWSLT16.TED.tst2010.de-en.de - IWSLT16.TED.tst2010.de-en.en - IWSLT16.TED.tst2010.en-ar.ar - IWSLT16.TED.tst2010.en-ar.en - IWSLT16.TED.tst2010.en-cs.cs - IWSLT16.TED.tst2010.en-cs.en - IWSLT16.TED.tst2010.en-de.de - IWSLT16.TED.tst2010.en-de.en - IWSLT16.TED.tst2010.en-fr.en - IWSLT16.TED.tst2010.en-fr.fr - IWSLT16.TED.tst2010.fr-en.en - IWSLT16.TED.tst2010.fr-en.fr - IWSLT16.TED.tst2011.ar-en.ar - IWSLT16.TED.tst2011.ar-en.en - IWSLT16.TED.tst2011.cs-en.cs - IWSLT16.TED.tst2011.cs-en.en - IWSLT16.TED.tst2011.de-en.de - IWSLT16.TED.tst2011.de-en.en - IWSLT16.TED.tst2011.en-ar.ar - IWSLT16.TED.tst2011.en-ar.en - IWSLT16.TED.tst2011.en-cs.cs - IWSLT16.TED.tst2011.en-cs.en - IWSLT16.TED.tst2011.en-de.de - IWSLT16.TED.tst2011.en-de.en - IWSLT16.TED.tst2011.en-fr.en - IWSLT16.TED.tst2011.en-fr.fr - IWSLT16.TED.tst2011.fr-en.en - IWSLT16.TED.tst2011.fr-en.fr - IWSLT16.TED.tst2012.ar-en.ar - IWSLT16.TED.tst2012.ar-en.en - IWSLT16.TED.tst2012.cs-en.cs - IWSLT16.TED.tst2012.cs-en.en - IWSLT16.TED.tst2012.de-en.de - IWSLT16.TED.tst2012.de-en.en - IWSLT16.TED.tst2012.en-ar.ar - IWSLT16.TED.tst2012.en-ar.en - IWSLT16.TED.tst2012.en-cs.cs - IWSLT16.TED.tst2012.en-cs.en - IWSLT16.TED.tst2012.en-de.de - IWSLT16.TED.tst2012.en-de.en - IWSLT16.TED.tst2012.en-fr.en - IWSLT16.TED.tst2012.en-fr.fr - IWSLT16.TED.tst2012.fr-en.en - IWSLT16.TED.tst2012.fr-en.fr - IWSLT16.TED.tst2013.ar-en.ar - IWSLT16.TED.tst2013.ar-en.en - IWSLT16.TED.tst2013.cs-en.cs - IWSLT16.TED.tst2013.cs-en.en - IWSLT16.TED.tst2013.de-en.de - IWSLT16.TED.tst2013.de-en.en - IWSLT16.TED.tst2013.en-ar.ar - IWSLT16.TED.tst2013.en-ar.en - IWSLT16.TED.tst2013.en-cs.cs - IWSLT16.TED.tst2013.en-cs.en - IWSLT16.TED.tst2013.en-de.de - IWSLT16.TED.tst2013.en-de.en - IWSLT16.TED.tst2013.en-fr.en - IWSLT16.TED.tst2013.en-fr.fr - IWSLT16.TED.tst2013.fr-en.en - IWSLT16.TED.tst2013.fr-en.fr - IWSLT16.TED.tst2014.ar-en.ar - IWSLT16.TED.tst2014.ar-en.en - IWSLT16.TED.tst2014.de-en.de - IWSLT16.TED.tst2014.de-en.en - IWSLT16.TED.tst2014.en-ar.ar - IWSLT16.TED.tst2014.en-ar.en - IWSLT16.TED.tst2014.en-de.de - IWSLT16.TED.tst2014.en-de.en - IWSLT16.TED.tst2014.en-fr.en - IWSLT16.TED.tst2014.en-fr.fr - IWSLT16.TED.tst2014.fr-en.en - IWSLT16.TED.tst2014.fr-en.fr - IWSLT16.TEDX.dev2012.de-en.de - IWSLT16.TEDX.dev2012.de-en.en - IWSLT16.TEDX.tst2013.de-en.de - IWSLT16.TEDX.tst2013.de-en.en - IWSLT16.TEDX.tst2014.de-en.de - IWSLT16.TEDX.tst2014.de-en.en - train.ar - train.ar-en.ar - train.ar-en.en - train.cs - train.cs-en.cs - train.cs-en.en - train.de - train.de-en.de - train.de-en.en - train.en - train.en-ar.ar - train.en-ar.en - train.en-cs.cs - train.en-cs.en - train.en-de.de - train.en-de.en - train.en-fr.en - train.en-fr.fr - train.fr - train.fr-en.en - train.fr-en.fr - train.tags.ar-en.ar - train.tags.ar-en.en - train.tags.cs-en.cs - train.tags.cs-en.en - train.tags.de-en.de - train.tags.de-en.en - train.tags.en-ar.ar - train.tags.en-ar.en - train.tags.en-cs.cs - train.tags.en-cs.en - train.tags.en-de.de - train.tags.en-de.en - train.tags.en-fr.en - train.tags.en-fr.fr - train.tags.fr-en.en - train.tags.fr-en.fr - - Examples: - >>> from torchtext.datasets import IWSLT - >>> from torchtext.data.utils import get_tokenizer - >>> src_tokenizer = get_tokenizer("spacy", language='de') - >>> tgt_tokenizer = get_tokenizer("basic_english") - >>> train_dataset, valid_dataset, test_dataset = IWSLT(tokenizer=(src_tokenizer, - tgt_tokenizer)) - >>> src_vocab, tgt_vocab = train_dataset.get_vocab() - >>> src_data, tgt_data = train_dataset[10] - """ - - return _setup_datasets("IWSLT", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - tokenizer=tokenizer, - root=root, - vocab=vocab, - removed_tokens=removed_tokens) - - -def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', - 'train.tok.clean.bpe.32000.en'), - valid_filenames=('newstest2013.tok.bpe.32000.de', - 'newstest2013.tok.bpe.32000.en'), - test_filenames=('newstest2014.tok.bpe.32000.de', - 'newstest2014.tok.bpe.32000.en'), - tokenizer=None, - root='.data', - vocab=(None, None), - data_select=('train', 'valid', 'test'), - removed_tokens=['']): - """ Define translation datasets: WMT14 - Separately returns train/valid/test datasets - The available datasets include: - newstest2016.en - newstest2016.de - newstest2015.en - newstest2015.de - newstest2014.en - newstest2014.de - newstest2013.en - newstest2013.de - newstest2012.en - newstest2012.de - newstest2011.tok.de - newstest2011.en - newstest2011.de - newstest2010.tok.de - newstest2010.en - newstest2010.de - newstest2009.tok.de - newstest2009.en - newstest2009.de - newstest2016.tok.de - newstest2015.tok.de - newstest2014.tok.de - newstest2013.tok.de - newstest2012.tok.de - newstest2010.tok.en - newstest2009.tok.en - newstest2015.tok.en - newstest2014.tok.en - newstest2013.tok.en - newstest2012.tok.en - newstest2011.tok.en - newstest2016.tok.en - newstest2009.tok.bpe.32000.en - newstest2011.tok.bpe.32000.en - newstest2010.tok.bpe.32000.en - newstest2013.tok.bpe.32000.en - newstest2012.tok.bpe.32000.en - newstest2015.tok.bpe.32000.en - newstest2014.tok.bpe.32000.en - newstest2016.tok.bpe.32000.en - train.tok.clean.bpe.32000.en - newstest2009.tok.bpe.32000.de - newstest2010.tok.bpe.32000.de - newstest2011.tok.bpe.32000.de - newstest2013.tok.bpe.32000.de - newstest2012.tok.bpe.32000.de - newstest2014.tok.bpe.32000.de - newstest2016.tok.bpe.32000.de - newstest2015.tok.bpe.32000.de - train.tok.clean.bpe.32000.de - - Arguments: - train_filenames: the source and target filenames for training. - Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') - valid_filenames: the source and target filenames for valid. - Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') - test_filenames: the source and target filenames for test. - Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') - tokenizer: the tokenizer used to preprocess source and target raw text data. - It has to be in a form of tuple. - Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) - root: Directory where the datasets are saved. Default: ".data" - vocab: Source and target Vocabulary objects used for dataset. If None, it - will generate a new vocabulary based on the train data set. It has to be - in a form of tuple. - Default: (None, None) - data_select: a string or tuple for the returned datasets - (Default: ('train', 'valid', 'test')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - removed_tokens: removed tokens from output dataset (Default: '') - - Examples: - >>> from torchtext.datasets import WMT14 - >>> from torchtext.data.utils import get_tokenizer - >>> src_tokenizer = get_tokenizer("spacy", language='de') - >>> tgt_tokenizer = get_tokenizer("basic_english") - >>> train_dataset, valid_dataset, test_dataset = WMT14(tokenizer=(src_tokenizer, - tgt_tokenizer)) - >>> src_vocab, tgt_vocab = train_dataset.get_vocab() - >>> src_data, tgt_data = train_dataset[10] - """ - - return _setup_datasets("WMT14", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - tokenizer=tokenizer, - root=root, - vocab=vocab, - removed_tokens=removed_tokens) - - -DATASETS = {'Multi30k': raw.Multi30k, 'IWSLT': raw.IWSLT, 'WMT14': raw.WMT14} diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py deleted file mode 100644 index f7f53670be..0000000000 --- a/torchtext/experimental/transforms.py +++ /dev/null @@ -1,114 +0,0 @@ -import torch -import torch.nn as nn -from typing import List, Tuple - - -__all__ = [ - 'BasicEnglishNormalize', - 'RegexTokenizer' -] - - -class BasicEnglishNormalize(nn.Module): - r"""Basic normalization for a string sentence. - - Normalization includes - - lowercasing - - complete some basic text normalization for English words as follows: - - add spaces before and after '\'' - - remove '\"', - - add spaces before and after '.' - - replace '
'with single space - - add spaces before and after ',' - - add spaces before and after '(' - - add spaces before and after ')' - - add spaces before and after '!' - - add spaces before and after '?' - - replace ';' with single space - - replace ':' with single space - - replace multiple spaces with single space - - Examples: - >>> import torch - >>> from torchtext.experimental.transforms import BasicEnglishNormalize - >>> test_sample = 'Basic English Normalization for a Line of Text' - >>> basic_english_normalize = BasicEnglishNormalize() - >>> jit_basic_english_normalize = torch.jit.script(basic_english_normalize) - >>> tokens = jit_basic_english_normalize(test_sample) - """ - - regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] - - def __init__(self): - super(BasicEnglishNormalize, self).__init__() - patterns_list = [ - (r'\'', ' \' '), - (r'\"', ''), - (r'\.', ' . '), - (r'
', ' '), - (r',', ' , '), - (r'\(', ' ( '), - (r'\)', ' ) '), - (r'\!', ' ! '), - (r'\?', ' ? '), - (r'\;', ' '), - (r'\:', ' '), - (r'\s+', ' ')] - - regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) - replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) - self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) - - def forward(self, line: str) -> List[str]: - r""" - Args: - line (str): a line of text to tokenize. - Returns: - List[str]: a list of tokens after normalizing and splitting on whitespace. - """ - - line = line.lower() - for regex, replacement_string in self.regex_and_replacement_string_pairs: - line = regex.Sub(line, replacement_string) - return line.split() - - -class RegexTokenizer(nn.Module): - r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. - - Args: - patterns_list (List[Tuple[str, str]]): a list of tuples (ordered pairs) which contain the regex pattern string - as the first element and the replacement string as the second element. - - Examples: - >>> import torch - >>> from torchtext.experimental.transforms import RegexTokenizer - >>> test_sample = 'Basic Regex Tokenization for a Line of Text' - >>> patterns_list = [ - (r'\'', ' \' '), - (r'\"', '')] - >>> regex_tokenizer = RegexTokenizer(patterns_list) - >>> jit_regex_tokenizer = torch.jit.script(regex_tokenizer) - >>> tokens = jit_regex_tokenizer(test_sample) - """ - - regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] - - def __init__(self, patterns_list: List[Tuple[str, str]]): - super(RegexTokenizer, self).__init__() - - regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) - replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) - self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) - - def forward(self, line: str) -> List[str]: - r""" - Args: - line (str): a line of text to tokenize. - Returns: - List[str]: a list of tokens after normalizing and splitting on whitespace. - """ - - for regex, replacement_string in self.regex_and_replacement_string_pairs: - line = regex.Sub(line, replacement_string) - return line.split() diff --git a/torchtext/utils.py b/torchtext/utils.py index b892396a15..41ac14ecbb 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -7,7 +7,6 @@ import re import sys import zipfile -import gzip def reporthook(t): @@ -198,21 +197,6 @@ def extract_archive(from_path, to_path=None, overwrite=False): files = [f for f in files if os.path.isfile(f)] return files - elif from_path.endswith('.gz'): - default_block_size = 65536 - filename = from_path[:-3] - files = [filename] - with gzip.open(from_path, 'rb') as gzfile, \ - open(filename, 'wb') as d_file: - while True: - block = gzfile.read(default_block_size) - if not block: - break - else: - d_file.write(block) - d_file.write(block) - return files - else: raise NotImplementedError( - "We currently only support tar.gz, .tgz, .gz and zip achives.") + "We currently only support tar.gz, .tgz and zip achives.") From 3bdf4148a923f68c009510c7adc482e33db9353c Mon Sep 17 00:00:00 2001 From: Nayef Ahmed Date: Wed, 24 Jun 2020 08:29:44 -0700 Subject: [PATCH 13/68] Import torchtext 2020/06/22 Summary: Import from github torchtext/master Reviewed By: zhangguanheng66, cpuhrsch Differential Revision: D22168183 fbshipit-source-id: 7d96ade64f18942d9bd19437011be2f65f0b2a5e --- README.rst | 2 +- benchmark/mha_block.py | 103 ++++ build_tools/setup_helpers/extension.py | 41 ++ codecov.yml | 14 - docs/source/experimental_datasets.rst | 79 ++- docs/source/experimental_transforms.rst | 22 + docs/source/experimental_vectors.rst | 20 + docs/source/index.rst | 3 + docs/source/modules.rst | 23 + test/asset/vectors_test.csv | 2 + test/common/torchtext_test_case.py | 2 +- test/data/test_builtin_datasets.py | 111 +++- test/data/test_field.py | 9 +- test/data/test_functional.py | 104 +++- test/data/test_jit.py | 28 + test/data/test_metrics.py | 23 +- test/data/test_modules.py | 123 ++++ test/data/test_utils.py | 16 +- test/experimental/test_vectors.py | 137 +++++ test/test_build.py | 55 +- test/test_utils.py | 28 + test/test_vocab.py | 3 +- torchtext/__init__.py | 2 + torchtext/csrc/regex.cpp | 41 ++ torchtext/csrc/vectors.cpp | 84 +++ torchtext/experimental/datasets/__init__.py | 11 +- .../datasets/language_modeling.py | 191 +++--- .../experimental/datasets/question_answer.py | 163 ++++++ .../experimental/datasets/raw/__init__.py | 13 +- .../datasets/raw/language_modeling.py | 184 ++++++ .../datasets/raw/question_answer.py | 93 +++ .../experimental/datasets/raw/translation.py | 544 +++++++++++++++++ .../experimental/datasets/translation.py | 551 ++++++++++++++++++ torchtext/experimental/functional.py | 22 +- torchtext/experimental/transforms.py | 114 ++++ torchtext/experimental/vectors.py | 87 +++ torchtext/modules/__init__.py | 6 + torchtext/modules/multiheadattention.py | 213 +++++++ torchtext/utils.py | 18 +- 39 files changed, 3082 insertions(+), 203 deletions(-) create mode 100644 benchmark/mha_block.py delete mode 100644 codecov.yml create mode 100644 docs/source/experimental_transforms.rst create mode 100644 docs/source/experimental_vectors.rst create mode 100644 docs/source/modules.rst create mode 100644 test/asset/vectors_test.csv create mode 100644 test/data/test_jit.py create mode 100644 test/data/test_modules.py create mode 100644 test/experimental/test_vectors.py create mode 100644 torchtext/csrc/regex.cpp create mode 100644 torchtext/csrc/vectors.cpp create mode 100644 torchtext/experimental/datasets/question_answer.py create mode 100644 torchtext/experimental/datasets/raw/language_modeling.py create mode 100644 torchtext/experimental/datasets/raw/question_answer.py create mode 100644 torchtext/experimental/datasets/raw/translation.py create mode 100644 torchtext/experimental/datasets/translation.py create mode 100644 torchtext/experimental/transforms.py create mode 100644 torchtext/experimental/vectors.py create mode 100644 torchtext/modules/__init__.py create mode 100644 torchtext/modules/multiheadattention.py diff --git a/README.rst b/README.rst index 979d87407c..a69be1e1e1 100644 --- a/README.rst +++ b/README.rst @@ -69,7 +69,7 @@ To build torchtext from source, you need ``git``, ``CMake`` and C++11 compiler s **Note** -When building from souce, make sure that you have the same C++ compiler as the one used to build PyTorch. A simple way is to build PyTorch from source and use the same environment to build torchtext. +When building from source, make sure that you have the same C++ compiler as the one used to build PyTorch. A simple way is to build PyTorch from source and use the same environment to build torchtext. If you are using nightly build of PyTorch, checkout the environment it was built `here (conda) `_ and `here (pip) `_. Documentation diff --git a/benchmark/mha_block.py b/benchmark/mha_block.py new file mode 100644 index 0000000000..eff568f5dd --- /dev/null +++ b/benchmark/mha_block.py @@ -0,0 +1,103 @@ +import torch +from torchtext.modules import InProjContainer, MultiheadAttentionContainer, ScaledDotProduct +from torch.nn.functional import multi_head_attention_forward as mha_forward +import time + + +def benchmark_mha_block(): + + def _run_benchmark(embed_dim, nhead, bsz, device, tgt_len, src_len=None): + # Build torchtext MultiheadAttention module + in_proj_container = InProjContainer(torch.nn.Linear(embed_dim, embed_dim), + torch.nn.Linear(embed_dim, embed_dim), + torch.nn.Linear(embed_dim, embed_dim)) + MHA = MultiheadAttentionContainer(nhead, in_proj_container, + ScaledDotProduct(), + torch.nn.Linear(embed_dim, embed_dim)).to(device) + + query = torch.rand((tgt_len, bsz, embed_dim)).to(device) + if src_len is None: + key = value = query + src_len = tgt_len + else: + key = value = torch.rand((src_len, bsz, embed_dim)).to(device) + attn_mask_2D = torch.randint(0, 2, (tgt_len, src_len)).to(torch.bool).to(device) + attn_mask = torch.stack([attn_mask_2D] * (bsz * nhead)) + bias_k = bias_v = torch.rand((1, 1, embed_dim)).to(device) + print("starting torchtext.modules.MultiheadAttentionContainer") + if device == torch.device("cuda"): + torch.cuda.synchronize() + t0 = time.monotonic() + for _ in range(100): + mha_output, attn_weights = MHA(query, key, value, + attn_mask=attn_mask, + bias_k=bias_k.repeat(1, bsz, 1).reshape(1, bsz * nhead, -1), + bias_v=bias_v.repeat(1, bsz, 1).reshape(1, bsz * nhead, -1)) + if device == torch.device("cuda"): + torch.cuda.synchronize() + print(time.monotonic() - t0) + + # Use torch.nn.functional.multi_head_attention_forward + torch_attn_mask = torch.zeros((tgt_len, src_len)).to(device).masked_fill_(attn_mask_2D, float('-inf')) + print("starting torch.nn.functional.multi_head_attention_forward") + in_proj_weight = torch.cat([MHA.in_proj_container.query_proj.weight, + MHA.in_proj_container.key_proj.weight, + MHA.in_proj_container.value_proj.weight]) + if device == torch.device("cuda"): + torch.cuda.synchronize() + t0 = time.monotonic() + for _ in range(100): + torch_mha_output, torch_mha_weights = mha_forward(query, key, value, + embed_dim, nhead, + in_proj_weight, None, + bias_k, bias_v, + False, 0.0, + MHA.out_proj.weight, + MHA.out_proj.bias, + attn_mask=torch_attn_mask) + if device == torch.device("cuda"): + torch.cuda.synchronize() + print(time.monotonic() - t0) + + # GPU test + device = torch.device("cuda") + for embed_dim in [64, 768]: + for nhead in [2, 16]: + for seq_len in [10, 128, 1000]: + for bsz in [2, 72]: + if seq_len == 1000 and bsz == 72: + continue + print("*" * 80) + print("test case GPU with embed_dim, nhead, seq_len, bsz:", + embed_dim, nhead, seq_len, seq_len, bsz) + _run_benchmark(embed_dim, nhead, bsz, device, seq_len, seq_len) + + # GPU test for self-attention + device = torch.device("cuda") + for embed_dim in [64, 256]: + for nhead in [2, 16]: + for seq_len in [10, 128, 1000]: + for bsz in [2, 72]: + if seq_len == 1000 and bsz == 72: + continue + print("*" * 80) + print("self-attention test case GPU with embed_dim, nhead, seq_len, bsz:", + embed_dim, nhead, seq_len, seq_len, bsz) + _run_benchmark(embed_dim, nhead, bsz, device, seq_len, None) + + # CPU test for self-attention + device = torch.device("cpu") + for embed_dim in [64, 768]: + for nhead in [2, 16]: + for seq_len in [10, 128, 1000]: + for bsz in [2, 72]: + if seq_len == 1000 and bsz == 72: + continue + print("*" * 80) + print("test case CPU with embed_dim, nhead, seq_len, bsz:", + embed_dim, nhead, seq_len, seq_len, bsz) + _run_benchmark(embed_dim, nhead, bsz, device, seq_len, None) + + +if __name__ == "__main__": + benchmark_mha_block() diff --git a/build_tools/setup_helpers/extension.py b/build_tools/setup_helpers/extension.py index 80d515d998..6c70940f22 100644 --- a/build_tools/setup_helpers/extension.py +++ b/build_tools/setup_helpers/extension.py @@ -60,6 +60,7 @@ def _get_include_dirs(): def _get_library_dirs(): return [ str(_TP_INSTALL_DIR / 'lib'), + str(_TP_INSTALL_DIR / 'lib64') ] @@ -78,9 +79,48 @@ def _get_libraries(): return [ 'sentencepiece_train', 'sentencepiece', + 're2' ] +def _build_third_party(debug): + build_dir = _TP_BASE_DIR / 'build' + build_dir.mkdir(exist_ok=True) + build_env = os.environ.copy() + config = 'Debug' if debug else 'Release' + if platform.system() == 'Windows': + extra_args = [ + '-GNinja', + ] + build_env.setdefault('CC', 'cl') + build_env.setdefault('CXX', 'cl') + else: + extra_args = ['-DCMAKE_CXX_FLAGS=-fPIC'] + subprocess.run( + args=[ + 'cmake', + '-DBUILD_SHARED_LIBS=OFF', + '-DRE2_BUILD_TESTING=OFF', + '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON', + f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}', + f'-DCMAKE_BUILD_TYPE={config}', + ] + extra_args + ['..'], + cwd=str(build_dir), + check=True, + env=build_env, + ) + print('*** Command list Thirdparty ***') + with open(build_dir / 'compile_commands.json', 'r') as fileobj: + print(fileobj.read()) + print(f'running cmake --build', flush=True) + subprocess.run( + args=['cmake', '--build', '.', '--target', 'install', '--config', config], + cwd=str(build_dir), + check=True, + env=build_env, + ) + + def _build_sentence_piece(debug): build_dir = _TP_BASE_DIR / 'sentencepiece' / 'build' build_dir.mkdir(exist_ok=True) @@ -108,6 +148,7 @@ def _build_sentence_piece(debug): def _configure_third_party(debug): + _build_third_party(debug) _build_sentence_piece(debug) diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index f3ca2a4807..0000000000 --- a/codecov.yml +++ /dev/null @@ -1,14 +0,0 @@ -coverage: - precision: 0 - round: down - status: - patch: - default: - target: 90 - project: - default: - threshold: 1% - changes: false -comment: false -ignore: - - "test/" diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index d9d59539d0..044b731496 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -1,5 +1,5 @@ torchtext.experimental.datasets -================================ +=============================== .. currentmodule:: torchtext.experimental.datasets @@ -41,13 +41,13 @@ Text Classification ^^^^^^^^^^^^^^^^^^^ TextClassificationDataset -~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: TextClassificationDataset :members: __init__ AG_NEWS -~~~~~~ +~~~~~~~ AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. @@ -55,7 +55,7 @@ AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ SogouNews -~~~~~~~~ +~~~~~~~~~ SogouNews dataset is subclass of ``TextClassificationDataset`` class. @@ -63,7 +63,7 @@ SogouNews dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ DBpedia -~~~~~~ +~~~~~~~ DBpedia dataset is subclass of ``TextClassificationDataset`` class. @@ -71,7 +71,7 @@ DBpedia dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YelpReviewPolarity -~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~ YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. @@ -79,7 +79,7 @@ YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YelpReviewFull -~~~~~~~~~~~~~ +~~~~~~~~~~~~~~ YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. @@ -87,7 +87,7 @@ YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ YahooAnswers -~~~~~~~~~~~ +~~~~~~~~~~~~ YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. @@ -95,7 +95,7 @@ YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ AmazonReviewPolarity -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. @@ -103,7 +103,7 @@ AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. :members: __init__ AmazonReviewFull -~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~ AmazonReviewFull dataset is subclass of ``TextClassificationDataset`` class. @@ -139,3 +139,62 @@ PennTreebank .. autoclass:: PennTreebank :members: __init__ + + +WMTNewsCrawl +~~~~~~~~~~~~ + +.. autoclass:: WMTNewsCrawl + :members: __init__ + + +Machine Translation +^^^^^^^^^^^^^^^^^^^ + +Language modeling datasets are subclasses of ``TranslationDataset`` class. + +.. autoclass:: TranslationDataset + :members: __init__ + + +Multi30k +~~~~~~~~ + +.. autoclass:: Multi30k + :members: __init__ + + +IWSLT +~~~~~ + +.. autoclass:: IWSLT + :members: __init__ + + +WMT14 +~~~~~ + +.. autoclass:: WMT14 + :members: __init__ + +Question Answer +^^^^^^^^^^^^^^^ + +Question answer datasets are subclasses of ``QuestionAnswerDataset`` class. + +.. autoclass:: QuestionAnswerDataset + :members: __init__ + + +SQuAD 1.0 +~~~~~~~~~ + +.. autoclass:: SQuAD1 + :members: __init__ + + +SQuAD 2.0 +~~~~~~~~~ + +.. autoclass:: SQuAD2 + :members: __init__ diff --git a/docs/source/experimental_transforms.rst b/docs/source/experimental_transforms.rst new file mode 100644 index 0000000000..ff00b374ef --- /dev/null +++ b/docs/source/experimental_transforms.rst @@ -0,0 +1,22 @@ +.. role:: hidden + :class: hidden-section + +torchtext.experimental.transforms +================================= + +.. automodule:: torchtext.experimental.transforms +.. currentmodule:: torchtext.experimental.transforms + +:hidden:`BasicEnglishNormalize` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: BasicEnglishNormalize + :members: + :special-members: __init__ + +:hidden:`RegexTokenizer` +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: RegexTokenizer + :members: + :special-members: __init__ \ No newline at end of file diff --git a/docs/source/experimental_vectors.rst b/docs/source/experimental_vectors.rst new file mode 100644 index 0000000000..8d9fe02ce0 --- /dev/null +++ b/docs/source/experimental_vectors.rst @@ -0,0 +1,20 @@ +.. role:: hidden + :class: hidden-section + +torchtext.experimental.vectors +============================== + +.. automodule:: torchtext.experimental.vectors +.. currentmodule:: torchtext.experimental.vectors + +:hidden:`Vector` +~~~~~~~~~~~~~~~~ + +.. autoclass:: Vectors + :members: + :special-members: + +:hidden:`vectors_from_file_object` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: vectors_from_file_object diff --git a/docs/source/index.rst b/docs/source/index.rst index 08fb745c4f..7e965e5abf 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -17,6 +17,9 @@ popular datasets for natural language. torchtext.vocab torchtext.utils experimental_datasets + experimental_functional + experimental_transforms + experimental_vectors examples .. automodule:: torchtext diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 0000000000..ca8b30e8e4 --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,23 @@ +.. role:: hidden + :class: hidden-section + +torchtext.models.multiheadattention +================================== + +.. automodule:: torchtext.models.multiheadattention +.. currentmodule:: torchtext.models.multiheadattention + +:hidden:`MultiheadAttentionContainer` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: MultiheadAttentionContainer + +:hidden:`InProjContainer` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: InProjContainer + +:hidden:`ScaledDotProduct` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: ScaledDotProduct diff --git a/test/asset/vectors_test.csv b/test/asset/vectors_test.csv new file mode 100644 index 0000000000..a1dcfa645c --- /dev/null +++ b/test/asset/vectors_test.csv @@ -0,0 +1,2 @@ +a,1 0 0 +b,0 1 0 \ No newline at end of file diff --git a/test/common/torchtext_test_case.py b/test/common/torchtext_test_case.py index 249e5aa0c9..21ccc4d785 100644 --- a/test/common/torchtext_test_case.py +++ b/test/common/torchtext_test_case.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from unittest import TestCase +from torch.testing._internal.common_utils import TestCase import json import logging import os diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 08c75292c4..aa0fff33a5 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -1,19 +1,20 @@ #!/user/bin/env python3 # Note that all the tests in this module require dataset (either network access or cached) import os +import glob import shutil import torchtext.data as data from torchtext.datasets import AG_NEWS import torch -from torch.testing import assert_allclose from ..common.torchtext_test_case import TorchtextTestCase def conditional_remove(f): - if os.path.isfile(f): - os.remove(f) - elif os.path.isdir(f): - shutil.rmtree(f) + for path in glob.glob(f): + if os.path.isfile(path): + os.remove(path) + elif os.path.isdir(path): + shutil.rmtree(path) class TestDataset(TorchtextTestCase): @@ -78,7 +79,7 @@ def test_penntreebank_legacy(self): def test_penntreebank(self): from torchtext.experimental.datasets import PennTreebank - # smoke test to ensure wikitext2 works properly + # smoke test to ensure penn treebank works properly train_dataset, test_dataset, valid_dataset = PennTreebank() self.assertEqual(len(train_dataset), 924412) self.assertEqual(len(test_dataset), 82114) @@ -97,10 +98,10 @@ def test_text_classification(self): ag_news_train, ag_news_test = AG_NEWS(root=datadir, ngrams=3) self.assertEqual(len(ag_news_train), 120000) self.assertEqual(len(ag_news_test), 7600) - assert_allclose(ag_news_train[-1][1][:10], - torch.tensor([3525, 319, 4053, 34, 5407, 3607, 70, 6798, 10599, 4053]).long()) - assert_allclose(ag_news_test[-1][1][:10], - torch.tensor([2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]).long()) + self.assertEqual(ag_news_train[-1][1][:10], + torch.tensor([3525, 319, 4053, 34, 5407, 3607, 70, 6798, 10599, 4053]).long()) + self.assertEqual(ag_news_test[-1][1][:10], + torch.tensor([2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]).long()) def test_imdb(self): from torchtext.experimental.datasets import IMDB @@ -109,16 +110,90 @@ def test_imdb(self): train_dataset, test_dataset = IMDB() self.assertEqual(len(train_dataset), 25000) self.assertEqual(len(test_dataset), 25000) - assert_allclose(train_dataset[0][1][:10], - torch.tensor([13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]).long()) - assert_allclose(train_dataset[-1][1][:10], - torch.tensor([2, 71, 4555, 194, 3328, 15144, 42, 227, 148, 8]).long()) - assert_allclose(test_dataset[0][1][:10], - torch.tensor([13, 125, 1051, 5, 246, 1652, 8, 277, 66, 20]).long()) - assert_allclose(test_dataset[-1][1][:10], - torch.tensor([13, 1035, 14, 21, 28, 2, 1051, 1275, 1008, 3]).long()) + self.assertEqual(train_dataset[0][1][:10], + torch.tensor([13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]).long()) + self.assertEqual(train_dataset[-1][1][:10], + torch.tensor([2, 71, 4555, 194, 3328, 15144, 42, 227, 148, 8]).long()) + self.assertEqual(test_dataset[0][1][:10], + torch.tensor([13, 125, 1051, 5, 246, 1652, 8, 277, 66, 20]).long()) + self.assertEqual(test_dataset[-1][1][:10], + torch.tensor([13, 1035, 14, 21, 28, 2, 1051, 1275, 1008, 3]).long()) # Test API with a vocab input object old_vocab = train_dataset.get_vocab() new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) new_train_data, new_test_data = IMDB(vocab=new_vocab) + + def test_multi30k(self): + from torchtext.experimental.datasets import Multi30k + # smoke test to ensure multi30k works properly + train_dataset, valid_dataset, test_dataset = Multi30k() + self.assertEqual(len(train_dataset), 29000) + self.assertEqual(len(valid_dataset), 1000) + self.assertEqual(len(test_dataset), 1014) + + de_vocab, en_vocab = train_dataset.get_vocab() + de_tokens_ids = [ + de_vocab[token] for token in + 'Zwei Männer verpacken Donuts in Kunststofffolie'.split() + ] + self.assertEqual(de_tokens_ids, [19, 29, 18703, 4448, 5, 6240]) + + en_tokens_ids = [ + en_vocab[token] for token in + 'Two young White males are outside near many bushes'.split() + ] + self.assertEqual(en_tokens_ids, + [17, 23, 1167, 806, 15, 55, 82, 334, 1337]) + + datafile = os.path.join(self.project_root, ".data", "train*") + conditional_remove(datafile) + datafile = os.path.join(self.project_root, ".data", "val*") + conditional_remove(datafile) + datafile = os.path.join(self.project_root, ".data", "test*") + conditional_remove(datafile) + datafile = os.path.join(self.project_root, ".data", + "multi30k_task*.tar.gz") + conditional_remove(datafile) + + def test_squad1(self): + from torchtext.experimental.datasets import SQuAD1 + from torchtext.vocab import Vocab + # smoke test to ensure imdb works properly + train_dataset, dev_dataset = SQuAD1() + self.assertEqual(len(train_dataset), 87599) + self.assertEqual(len(dev_dataset), 10570) + self.assertEqual(train_dataset[100]['question'], + torch.tensor([7, 24, 86, 52, 2, 373, 887, 18, 12797, 11090, 1356, 2, 1788, 3273, 16]).long()) + self.assertEqual(train_dataset[100]['ans_pos'][0], + torch.tensor([72, 72]).long()) + self.assertEqual(dev_dataset[100]['question'], + torch.tensor([42, 27, 669, 7438, 17, 2, 1950, 3273, 17252, 389, 16]).long()) + self.assertEqual(dev_dataset[100]['ans_pos'][0], + torch.tensor([45, 48]).long()) + + # Test API with a vocab input object + old_vocab = train_dataset.get_vocab() + new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) + new_train_data, new_test_data = SQuAD1(vocab=new_vocab) + + def test_squad2(self): + from torchtext.experimental.datasets import SQuAD2 + from torchtext.vocab import Vocab + # smoke test to ensure imdb works properly + train_dataset, dev_dataset = SQuAD2() + self.assertEqual(len(train_dataset), 130319) + self.assertEqual(len(dev_dataset), 11873) + self.assertEqual(train_dataset[200]['question'], + torch.tensor([84, 50, 1421, 12, 5439, 4569, 17, 30, 2, 15202, 4754, 1421, 16]).long()) + self.assertEqual(train_dataset[200]['ans_pos'][0], + torch.tensor([9, 9]).long()) + self.assertEqual(dev_dataset[200]['question'], + torch.tensor([41, 29, 2, 66, 17016, 30, 0, 1955, 16]).long()) + self.assertEqual(dev_dataset[200]['ans_pos'][0], + torch.tensor([40, 46]).long()) + + # Test API with a vocab input object + old_vocab = train_dataset.get_vocab() + new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) + new_train_data, new_test_data = SQuAD2(vocab=new_vocab) diff --git a/test/data/test_field.py b/test/data/test_field.py index 11b98bde68..aa76c38567 100644 --- a/test/data/test_field.py +++ b/test/data/test_field.py @@ -2,7 +2,6 @@ from collections import Counter import os -from numpy.testing import assert_allclose import torch import torchtext.data as data import pytest @@ -376,9 +375,9 @@ def test_numerical_features_no_vocab(self): test_float_data = ["1.1", "0.1", "3.91", "0.2", "10.2"] numericalized_int = int_field.numericalize(test_int_data) - assert_allclose(numericalized_int.data.numpy(), [1, 0, 1, 3, 19]) + self.assertEqual(numericalized_int.data, [1, 0, 1, 3, 19]) numericalized_float = float_field.numericalize(test_float_data) - assert_allclose(numericalized_float.data.numpy(), [1.1, 0.1, 3.91, 0.2, 10.2]) + self.assertEqual(numericalized_float.data, [1.1, 0.1, 3.91, 0.2, 10.2]) # Test with postprocessing applied int_field = data.Field(sequential=False, use_vocab=False, @@ -396,9 +395,9 @@ def test_numerical_features_no_vocab(self): test_float_data = ["1.1", "0.1", "3.91", "0.2", "10.2"] numericalized_int = int_field.numericalize(test_int_data) - assert_allclose(numericalized_int.data.numpy(), [2, 1, 2, 4, 20]) + self.assertEqual(numericalized_int.data, [2, 1, 2, 4, 20]) numericalized_float = float_field.numericalize(test_float_data) - assert_allclose(numericalized_float.data.numpy(), [0.55, 0.05, 1.955, 0.1, 5.1]) + self.assertEqual(numericalized_float.data, [0.55, 0.05, 1.955, 0.1, 5.1]) def test_errors(self): # Test that passing a non-tuple (of data and length) to numericalize diff --git a/test/data/test_functional.py b/test/data/test_functional.py index ff5b12ab17..9b93580f72 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -1,12 +1,12 @@ import os -import unittest -import sys import uuid import shutil +import unittest import tempfile import sentencepiece as spm import torch +import torchtext.data as data from torchtext.data.functional import ( generate_sp_model, load_sp_model, @@ -15,6 +15,10 @@ custom_replace, simple_space_split, ) +from torchtext.experimental.transforms import ( + BasicEnglishNormalize, + RegexTokenizer +) from ..common.torchtext_test_case import TorchtextTestCase from ..common.assets import get_asset_path @@ -22,7 +26,9 @@ class TestFunctional(TorchtextTestCase): def test_generate_sp_model(self): - """Test the function to train a sentencepiece tokenizer""" + """ + Test the function to train a sentencepiece tokenizer. + """ asset_name = 'text_normalization_ag_news_test.csv' asset_path = get_asset_path(asset_name) @@ -59,7 +65,6 @@ def test_sentencepiece_numericalizer(self): ref_results) def test_sentencepiece_tokenizer(self): - test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' model_path = get_asset_path('spm_example.model') sp_model = load_sp_model(model_path) @@ -74,6 +79,87 @@ def test_sentencepiece_tokenizer(self): self.assertEqual(list(spm_generator([test_sample]))[0], ref_results) + # TODO(Nayef211): uncomment and replace the test below with this once + # https://github.com/pytorch/pytorch/issues/38207 is closed + # def test_BasicEnglishNormalize(self): + # test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' + # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', + # 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] + + # basic_english_normalize = BasicEnglishNormalize() + # experimental_eager_tokens = basic_english_normalize(test_sample) + + # jit_basic_english_normalize = torch.jit.script(basic_english_normalize) + # experimental_jit_tokens = jit_basic_english_normalize(test_sample) + + # basic_english_tokenizer = data.get_tokenizer("basic_english") + # eager_tokens = basic_english_tokenizer(test_sample) + + # self.assertEqual(experimental_jit_tokens, ref_results) + # self.assertEqual(experimental_jit_tokens, eager_tokens) + # self.assertEqual(experimental_jit_tokens, experimental_eager_tokens) + + def test_BasicEnglishNormalize(self): + test_sample = 'Basic English Normalization for a Line of Text' + ref_results = ['basic', 'english', 'normalization', + 'for', 'a', 'line', 'of', 'text'] + + basic_english_normalize = BasicEnglishNormalize() + experimental_eager_tokens = basic_english_normalize(test_sample) + + basic_english_tokenizer = data.get_tokenizer("basic_english") + tokens_eager = basic_english_tokenizer(test_sample) + + self.assertEqual(experimental_eager_tokens, ref_results) + self.assertEqual(experimental_eager_tokens, tokens_eager) + + # TODO(Nayef211): uncomment and replace the test below with this once + # https://github.com/pytorch/pytorch/issues/38207 is closed + # def test_RegexTokenizer(self): + # test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' + # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', + # 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] + # patterns_list = [ + # (r'\'', ' \' '), + # (r'\"', ''), + # (r'\.', ' . '), + # (r'
', ' '), + # (r',', ' , '), + # (r'\(', ' ( '), + # (r'\)', ' ) '), + # (r'\!', ' ! '), + # (r'\?', ' ? '), + # (r'\;', ' '), + # (r'\:', ' '), + # (r'\s+', ' ')] + + # regex_tokenizer = RegexTokenizer(patterns_list) + # eager_tokens = regex_tokenizer(test_sample) + + # jit_regex_tokenizer = torch.jit.script(regex_tokenizer) + # jit_tokens = jit_regex_tokenizer(test_sample) + + # self.assertEqual(jit_tokens, ref_results) + # self.assertEqual(jit_tokens, eager_tokens) + + def test_RegexTokenizer(self): + test_sample = '"Basic Regex Tokenization". For a Line of Text' + ref_results = ['Basic', 'Regex', 'Tokenization', '.', + 'For', 'a', 'Line', 'of', 'Text'] + patterns_list = [ + (r'\"', ''), + (r'\.', ' . '), + (r'\s+', ' ')] + + regex_tokenizer = RegexTokenizer(patterns_list) + eager_tokens = regex_tokenizer(test_sample) + + jit_regex_tokenizer = torch.jit.script(regex_tokenizer) + jit_tokens = jit_regex_tokenizer(test_sample) + + self.assertEqual(jit_tokens, eager_tokens) + self.assertEqual(jit_tokens, ref_results) + def test_custom_replace(self): custom_replace_transform = custom_replace([(r'S', 's'), (r'\s+', ' ')]) test_sample = ['test cuStom replace', 'with uSer instruction'] @@ -109,11 +195,11 @@ def encode_as_pieces(self, input: str): class TestScriptableSP(unittest.TestCase): def setUp(self): model_path = get_asset_path('spm_example.model') - with tempfile.NamedTemporaryFile() as file: - torch.jit.script(ScriptableSP(model_path)).save(file.name) - self.model = torch.jit.load(file.name) + with tempfile.TemporaryDirectory() as dir_name: + jit_model_path = os.path.join(dir_name, 'spm_example.model') + torch.jit.script(ScriptableSP(model_path)).save(jit_model_path) + self.model = torch.jit.load(jit_model_path) - @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ @@ -125,7 +211,6 @@ def test_encode(self): output = self.model.encode(input) self.assertEqual(expected, output) - @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode_as_ids(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ @@ -134,7 +219,6 @@ def test_encode_as_ids(self): output = self.model.encode_as_ids(input) self.assertEqual(expected, output) - @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") def test_encode_as_pieces(self): input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' expected = [ diff --git a/test/data/test_jit.py b/test/data/test_jit.py new file mode 100644 index 0000000000..dff0d26b9a --- /dev/null +++ b/test/data/test_jit.py @@ -0,0 +1,28 @@ +import torch +from torchtext.modules import InProjContainer, MultiheadAttentionContainer, ScaledDotProduct +from torch.testing import assert_allclose +from ..common.torchtext_test_case import TorchtextTestCase + + +class TestJIT(TorchtextTestCase): + + def test_torchscript_multiheadattention(self): + embed_dim, nhead, tgt_len, src_len, bsz = 10, 5, 6, 10, 64 + # Build torchtext MultiheadAttention models + in_proj_container = InProjContainer(torch.nn.Linear(embed_dim, embed_dim, bias=False), + torch.nn.Linear(embed_dim, embed_dim, bias=False), + torch.nn.Linear(embed_dim, embed_dim, bias=False)) + + MHA = MultiheadAttentionContainer(nhead, in_proj_container, + ScaledDotProduct(), + torch.nn.Linear(embed_dim, embed_dim, bias=False)) + query = torch.rand((tgt_len, bsz, embed_dim)) + key = value = torch.rand((src_len, bsz, embed_dim)) + attn_mask = torch.randint(0, 2, (tgt_len, src_len)).to(torch.bool) + attn_mask = torch.stack([attn_mask] * (bsz * nhead)) + mha_output, attn_weights = MHA(query, key, value, attn_mask=attn_mask) + + ts_MHA = torch.jit.script(MHA) + ts_mha_output, ts_attn_weights = ts_MHA(query, key, value, attn_mask=attn_mask) + assert_allclose(mha_output, ts_mha_output) + assert_allclose(attn_weights, ts_attn_weights) diff --git a/test/data/test_metrics.py b/test/data/test_metrics.py index 1d69a20bae..af0ae77273 100644 --- a/test/data/test_metrics.py +++ b/test/data/test_metrics.py @@ -1,5 +1,4 @@ from torchtext.data.metrics import bleu_score -from torch.testing import assert_allclose from ..common.torchtext_test_case import TorchtextTestCase @@ -19,19 +18,19 @@ def test_bleu_score(self): # Partial match candidate = [['My', 'full', 'pytorch', 'test']] refs = [[['My', 'full', 'pytorch', 'test', '!'], ['Different']]] - assert_allclose(bleu_score(candidate, refs), 0.7788007) + self.assertEqual(bleu_score(candidate, refs), 0.7788007) # Bigrams and unigrams only candidate = [['My', 'pytorch', 'test']] refs = [[['My', 'full', 'pytorch', 'test'], ['Different']]] - assert_allclose(bleu_score(candidate, refs, max_n=2, - weights=[0.5, 0.5]), 0.5066641) + self.assertEqual(bleu_score(candidate, refs, max_n=2, + weights=[0.5, 0.5]), 0.5066641) # Multi-sentence corpus candidate = [['My', 'full', 'pytorch', 'test'], ['Another', 'Sentence']] refs = [[['My', 'full', 'pytorch', 'test'], ['Completely', 'Different']], [['No', 'Match']]] - assert_allclose(bleu_score(candidate, refs), 0.8408964) + self.assertEqual(bleu_score(candidate, refs), 0.8408964) # Empty input candidate = [[]] @@ -52,13 +51,13 @@ def test_bleu_score(self): # The comments below give the code used to get each hardcoded bleu score # nltk.translate.bleu_score.corpus_bleu(refs, candidate) - assert_allclose(bleu_score(candidate, refs), 0.4573199) + self.assertEqual(bleu_score(candidate, refs), 0.4573199) # nltk.translate.bleu_score.corpus_bleu(refs, candidate, weights=[0.33]*3) - assert_allclose(bleu_score(candidate, refs, 3, - weights=[0.33, 0.33, 0.33]), 0.4901113) + self.assertEqual(bleu_score(candidate, refs, 3, + weights=[0.33, 0.33, 0.33]), 0.4901113) # nltk.translate.bleu_score.corpus_bleu(refs, candidate, weights=[0.5]*2) - assert_allclose(bleu_score(candidate, refs, 2, - weights=[0.5, 0.5]), 0.5119535) + self.assertEqual(bleu_score(candidate, refs, 2, + weights=[0.5, 0.5]), 0.5119535) # nltk.translate.bleu_score.corpus_bleu(refs, candidate, weights=[1]) - assert_allclose(bleu_score(candidate, refs, 1, - weights=[1]), 0.5515605) + self.assertEqual(bleu_score(candidate, refs, 1, + weights=[1]), 0.5515605) diff --git a/test/data/test_modules.py b/test/data/test_modules.py new file mode 100644 index 0000000000..0de4e93239 --- /dev/null +++ b/test/data/test_modules.py @@ -0,0 +1,123 @@ +import torch +from torchtext.modules import InProjContainer, MultiheadAttentionContainer, ScaledDotProduct +from torch.nn.functional import multi_head_attention_forward as mha_forward +from torch.testing import assert_allclose +from ..common.torchtext_test_case import TorchtextTestCase + + +class TestModels(TorchtextTestCase): + + def test_multiheadattention(self): + embed_dim, nhead, tgt_len, src_len, bsz = 10, 5, 6, 10, 64 + # Build torchtext MultiheadAttention module + in_proj = InProjContainer(torch.nn.Linear(embed_dim, embed_dim, bias=False), + torch.nn.Linear(embed_dim, embed_dim, bias=False), + torch.nn.Linear(embed_dim, embed_dim, bias=False)) + + MHA = MultiheadAttentionContainer(nhead, in_proj, + ScaledDotProduct(), + torch.nn.Linear(embed_dim, embed_dim, bias=False)) + + query = torch.rand((tgt_len, bsz, embed_dim)) + key = value = torch.rand((src_len, bsz, embed_dim)) + attn_mask_2D = torch.randint(0, 2, (tgt_len, src_len)).to(torch.bool) + bias_k = bias_v = torch.rand((1, 1, embed_dim)) + mha_output, attn_weights = MHA(query, key, value, + attn_mask=torch.stack([attn_mask_2D] * (bsz * nhead)), + bias_k=bias_k.repeat(1, bsz, 1).reshape(1, bsz * nhead, -1), + bias_v=bias_v.repeat(1, bsz, 1).reshape(1, bsz * nhead, -1)) + + # Use torch.nn.functional.multi_head_attention_forward + torch_attn_mask = torch.zeros((tgt_len, src_len)).masked_fill_(attn_mask_2D, float('-inf')) + in_proj_weight = torch.cat([MHA.in_proj_container.query_proj.weight, + MHA.in_proj_container.key_proj.weight, + MHA.in_proj_container.value_proj.weight]) + torch_mha_output, torch_mha_weights = mha_forward(query, key, value, + embed_dim, nhead, + in_proj_weight, None, + bias_k, bias_v, + False, 0.0, + MHA.out_proj.weight, None, + attn_mask=torch_attn_mask) + + assert_allclose(mha_output, torch_mha_output) + # With bias_k and bias_v, src_len needs to plus 1 + attn_weights = attn_weights.view(bsz, nhead, tgt_len, src_len + 1).sum(dim=1) / nhead + assert_allclose(attn_weights, torch_mha_weights) + + def test_broadcast_scaled_dot_product(self): + embed_dim, nhead, tgt_len, src_len, bsz = 10, 5, 6, 10, 64 + SDP = ScaledDotProduct() + query = torch.rand((tgt_len, 1, embed_dim)) + key = value = torch.rand((src_len, 1, embed_dim)) + attn_mask_2D = torch.randint(0, 2, (tgt_len, src_len)).to(torch.bool) + + sdp_attn_output_full, sdp_attn_weights_full = SDP(query.expand(tgt_len, bsz * nhead, embed_dim), + key.expand(src_len, bsz * nhead, embed_dim), + value.expand(src_len, bsz * nhead, embed_dim), + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + + # query has a batch size of 1 while key/value have a batch size of bsz * nhead + sdp_attn_output, sdp_attn_weights = SDP(query, key.expand(src_len, bsz * nhead, embed_dim), + value.expand(src_len, bsz * nhead, embed_dim), + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + assert_allclose(sdp_attn_output, sdp_attn_output_full) + assert_allclose(sdp_attn_weights, sdp_attn_weights_full) + + # key/value have a batch size of 1 while query has a batch size of bsz * nhead + sdp_attn_output, sdp_attn_weights = SDP(query.expand(tgt_len, bsz * nhead, embed_dim), + key, value, + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + assert_allclose(sdp_attn_output, sdp_attn_output_full) + assert_allclose(sdp_attn_weights, sdp_attn_weights_full) + + # key/value have a size of (3, 3, src_len, bsz * nhead, embed_dim) + # while query has a size of (tgt_len, 1, embed_dim) + sdp_attn_output, sdp_attn_weights = SDP(query.expand(tgt_len, 1, embed_dim), + key.expand(3, 3, src_len, bsz * nhead, embed_dim), + value.expand(3, 3, src_len, bsz * nhead, embed_dim), + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + assert list(sdp_attn_output.size()) == [3, 3, tgt_len, bsz * nhead, embed_dim] + assert list(sdp_attn_weights.size()) == [3, 3, bsz * nhead, tgt_len, embed_dim] + assert_allclose(sdp_attn_output[2][2], sdp_attn_output_full) + assert_allclose(sdp_attn_weights[2][2], sdp_attn_weights_full) + # dim -2 is not equal to neither key/value's dim -2 or 1 + with self.assertRaises(RuntimeError): + SDP(query.expand(tgt_len, 2, embed_dim), key.expand(3, 3, src_len, bsz * nhead, embed_dim), + value.expand(3, 3, src_len, bsz * nhead, embed_dim), + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + + # key/value have a size of (src_len, 1, embed_dim) + # while query has a size of (1, 2, 3, tgt_len, bsz * nhead, embed_dim) + sdp_attn_output, sdp_attn_weights = SDP(query.expand(1, 2, 3, tgt_len, bsz * nhead, embed_dim), + key.expand(src_len, 1, embed_dim), + value.expand(src_len, 1, embed_dim), + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + assert list(sdp_attn_output.size()) == [1, 2, 3, tgt_len, bsz * nhead, embed_dim] + assert list(sdp_attn_weights.size()) == [1, 2, 3, bsz * nhead, tgt_len, embed_dim] + assert_allclose(sdp_attn_output[0][1][2], sdp_attn_output_full) + assert_allclose(sdp_attn_weights[0][1][2], sdp_attn_weights_full) + # key dim -2 is not equal to value dim -2 + with self.assertRaisesRegex(AssertionError, "Shape of key, value must match"): + SDP(query.expand(1, 2, 3, tgt_len, bsz * nhead, embed_dim), key.expand(src_len, 2, embed_dim), + value.expand(src_len, 1, embed_dim), + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + # key/value dim -2 is not equal to neither query's dim -2 or 1 + with self.assertRaises(RuntimeError): + SDP(query.expand(1, 2, 3, tgt_len, bsz * nhead, embed_dim), key.expand(src_len, 2, embed_dim), + value.expand(src_len, 2, embed_dim), + attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) + + # attn_mask in a size of (1, tgt_len, src_len) + # 2D tensor is not supported for attn_mask + sdp_attn_output, sdp_attn_weights = SDP(query.expand(tgt_len, bsz * nhead, embed_dim), + key.expand(src_len, bsz * nhead, embed_dim), + value.expand(src_len, bsz * nhead, embed_dim), + attn_mask=attn_mask_2D.expand(1, tgt_len, src_len)) + assert_allclose(sdp_attn_output, sdp_attn_output_full) + assert_allclose(sdp_attn_weights, sdp_attn_weights_full) + # attn_mask's dim -3 is not equal to neither batch size or 1 + with self.assertRaisesRegex(RuntimeError, "The size of the attn_mask is not correct."): + SDP(query.expand(tgt_len, bsz * nhead, embed_dim), key.expand(src_len, bsz * nhead, embed_dim), + value.expand(src_len, bsz * nhead, embed_dim), + attn_mask=attn_mask_2D.expand(2, tgt_len, src_len)) diff --git a/test/data/test_utils.py b/test/data/test_utils.py index c64ec09bf8..7772f851c2 100644 --- a/test/data/test_utils.py +++ b/test/data/test_utils.py @@ -2,7 +2,7 @@ import torchtext.data as data from torchtext.utils import unicode_csv_reader - +from torchtext.experimental.functional import ngrams_func from ..common.torchtext_test_case import TorchtextTestCase from ..common.assets import get_asset_path @@ -50,3 +50,17 @@ def test_text_nomalize_function(self): ref_lines.append(line) self.assertEqual(ref_lines, test_lines) + + def test_ngrams_func(self): + func = ngrams_func(1) + assert func(['A', 'string', 'particularly', 'one', 'with', 'slightly']) == \ + ['A', 'string', 'particularly', 'one', 'with', 'slightly'] + func = ngrams_func(2) + assert func(['A', 'string', 'particularly', 'one', 'with', 'slightly']) == \ + ['A', 'string', 'particularly', 'one', 'with', 'slightly', 'A string', 'string particularly', + 'particularly one', 'one with', 'with slightly'] + func = ngrams_func(3) + assert func(['A', 'string', 'particularly', 'one', 'with', 'slightly']) == \ + ['A', 'string', 'particularly', 'one', 'with', 'slightly', 'A string', 'string particularly', + 'particularly one', 'one with', 'with slightly', 'A string particularly', + 'string particularly one', 'particularly one with', 'one with slightly'] diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py new file mode 100644 index 0000000000..6ddbbde8b3 --- /dev/null +++ b/test/experimental/test_vectors.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +import torch +import os + +from test.common.assets import get_asset_path +from test.common.torchtext_test_case import TorchtextTestCase +from torchtext.experimental.vectors import ( + Vectors, + vectors_from_file_object +) + + +class TestVectors(TorchtextTestCase): + + def test_empty_vectors(self): + tokens = [] + vectors = [] + unk_tensor = torch.tensor([0], dtype=torch.float) + + vectors_obj = Vectors(tokens, vectors, unk_tensor) + self.assertEqual(vectors_obj['not_in_it'], unk_tensor) + + def test_empty_unk(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) + + tokens = ['a'] + vectors = [tensorA] + vectors_obj = Vectors(tokens, vectors) + + self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) + + def test_vectors_basic(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1], dtype=torch.float) + + unk_tensor = torch.tensor([0, 0], dtype=torch.float) + tokens = ['a', 'b'] + vectors = [tensorA, tensorB] + vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + + self.assertEqual(vectors_obj['a'], tensorA) + self.assertEqual(vectors_obj['b'], tensorB) + self.assertEqual(vectors_obj['not_in_it'], unk_tensor) + + def test_vectors_jit(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1], dtype=torch.float) + + unk_tensor = torch.tensor([0, 0], dtype=torch.float) + tokens = ['a', 'b'] + vectors = [tensorA, tensorB] + vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + jit_vectors_obj = torch.jit.script(vectors_obj) + + self.assertEqual(vectors_obj['a'], jit_vectors_obj['a']) + self.assertEqual(vectors_obj['b'], jit_vectors_obj['b']) + self.assertEqual(vectors_obj['not_in_it'], jit_vectors_obj['not_in_it']) + + def test_vectors_add_item(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + unk_tensor = torch.tensor([0, 0], dtype=torch.float) + + tokens = ['a'] + vectors = [tensorA] + vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + + tensorB = torch.tensor([0., 1]) + vectors_obj['b'] = tensorB + + self.assertEqual(vectors_obj['a'], tensorA) + self.assertEqual(vectors_obj['b'], tensorB) + self.assertEqual(vectors_obj['not_in_it'], unk_tensor) + + def test_vectors_load_and_save(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) + + tokens = ['a'] + vectors = [tensorA] + vectors_obj = Vectors(tokens, vectors) + + vector_path = os.path.join(self.test_dir, 'vectors.pt') + torch.save(vectors_obj, vector_path) + loaded_vectors_obj = torch.load(vector_path) + + self.assertEqual(loaded_vectors_obj['a'], tensorA) + self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) + + def test_errors(self): + tokens = [] + vectors = [] + + with self.assertRaises(ValueError): + # Test proper error raised when passing in empty tokens and vectors and + # not passing in a user defined unk_tensor + Vectors(tokens, vectors) + + tensorA = torch.tensor([1, 0, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1, 0], dtype=torch.float) + tokens = ['a', 'b', 'c'] + vectors = [tensorA, tensorB] + + with self.assertRaises(RuntimeError): + # Test proper error raised when tokens and vectors have different sizes + Vectors(tokens, vectors) + + tensorC = torch.tensor([0, 0, 1], dtype=torch.float) + tokens = ['a', 'a', 'c'] + vectors = [tensorA, tensorB, tensorC] + + with self.assertRaises(RuntimeError): + # Test proper error raised when tokens have duplicates + # TODO (Nayef211): use self.assertRaisesRegex() to check + # the key of the duplicate token in the error message + Vectors(tokens, vectors) + + tensorC = torch.tensor([0, 0, 1], dtype=torch.int8) + vectors = [tensorA, tensorB, tensorC] + + with self.assertRaises(TypeError): + # Test proper error raised when vectors are not of type torch.float + Vectors(tokens, vectors) + + def test_vectors_from_file(self): + asset_name = 'vectors_test.csv' + asset_path = get_asset_path(asset_name) + f = open(asset_path, 'r') + vectors_obj = vectors_from_file_object(f) + + expected_tensorA = torch.tensor([1, 0, 0], dtype=torch.float) + expected_tensorB = torch.tensor([0, 1, 0], dtype=torch.float) + expected_unk_tensor = torch.tensor([0, 0, 0], dtype=torch.float) + + self.assertEqual(vectors_obj['a'], expected_tensorA) + self.assertEqual(vectors_obj['b'], expected_tensorB) + self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) diff --git a/test/test_build.py b/test/test_build.py index f47d535204..d61e844280 100644 --- a/test/test_build.py +++ b/test/test_build.py @@ -3,7 +3,6 @@ import os from collections import Counter -import numpy as np import torch import torchtext.data @@ -130,16 +129,16 @@ def test_vectors_get_vecs(self): self.assertEqual(vec.vectors.shape[0], len(vec)) tokens = ['chip', 'baby', 'Beautiful'] - token_vecs = vec.get_vecs_by_tokens(tokens).numpy() + token_vecs = vec.get_vecs_by_tokens(tokens) self.assertEqual(token_vecs.shape[0], len(tokens)) self.assertEqual(token_vecs.shape[1], vec.dim) - torch.testing.assert_allclose(vec[tokens[0]].numpy(), token_vecs[0]) - torch.testing.assert_allclose(vec[tokens[1]].numpy(), token_vecs[1]) - torch.testing.assert_allclose(vec[''].numpy(), token_vecs[2]) + self.assertEqual(vec[tokens[0]], token_vecs[0]) + self.assertEqual(vec[tokens[1]], token_vecs[1]) + self.assertEqual(vec[''], token_vecs[2]) - token_one_vec = vec.get_vecs_by_tokens(tokens[0], lower_case_backup=True).numpy() + token_one_vec = vec.get_vecs_by_tokens(tokens[0], lower_case_backup=True) self.assertEqual(token_one_vec.shape[0], vec.dim) - torch.testing.assert_allclose(vec[tokens[0].lower()].numpy(), token_one_vec) + self.assertEqual(vec[tokens[0].lower()], token_one_vec) def test_download_charngram_vectors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) @@ -157,7 +156,7 @@ def test_download_charngram_vectors(self): expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.itos, expected_itos) self.assertEqual(dict(v.stoi), expected_stoi) - vectors = v.vectors.numpy() + vectors = v.vectors # The first 5 entries in each vector. expected_charngram = { @@ -167,11 +166,11 @@ def test_download_charngram_vectors(self): } for word in expected_charngram: - torch.testing.assert_allclose( + self.assertEqual( vectors[v.stoi[word], :5], expected_charngram[word]) - torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(100)) - torch.testing.assert_allclose(vectors[v.stoi['OOV token']], np.zeros(100)) + self.assertEqual(vectors[v.stoi['']], torch.zeros(100)) + self.assertEqual(vectors[v.stoi['OOV token']], torch.zeros(100)) def test_download_custom_vectors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) @@ -187,7 +186,7 @@ def test_download_custom_vectors(self): self.assertEqual(v.itos, ['', '', '', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) - vectors = v.vectors.numpy() + vectors = v.vectors # The first 5 entries in each vector. expected_fasttext_simple_en = { @@ -196,10 +195,10 @@ def test_download_custom_vectors(self): } for word in expected_fasttext_simple_en: - torch.testing.assert_allclose( + self.assertEqual( vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) - torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) + self.assertEqual(vectors[v.stoi['']], torch.zeros(300)) def test_download_fasttext_vectors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) @@ -219,7 +218,7 @@ def test_download_fasttext_vectors(self): expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.itos, expected_itos) self.assertEqual(dict(v.stoi), expected_stoi) - vectors = v.vectors.numpy() + vectors = v.vectors # The first 5 entries in each vector. expected_fasttext_simple_en = { @@ -228,11 +227,11 @@ def test_download_fasttext_vectors(self): } for word in expected_fasttext_simple_en: - torch.testing.assert_allclose( + self.assertEqual( vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) - torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) - torch.testing.assert_allclose(vectors[v.stoi['OOV token']], np.zeros(300)) + self.assertEqual(vectors[v.stoi['']], torch.zeros(300)) + self.assertEqual(vectors[v.stoi['OOV token']], torch.zeros(300)) def test_download_glove_vectors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) @@ -253,7 +252,7 @@ def test_download_glove_vectors(self): self.assertEqual(v.itos, expected_itos) self.assertEqual(dict(v.stoi), expected_stoi) - vectors = v.vectors.numpy() + vectors = v.vectors # The first 5 entries in each vector. expected_twitter = { @@ -262,11 +261,11 @@ def test_download_glove_vectors(self): } for word in expected_twitter: - torch.testing.assert_allclose( + self.assertEqual( vectors[v.stoi[word], :5], expected_twitter[word]) - torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(25)) - torch.testing.assert_allclose(vectors[v.stoi['OOV token']], np.zeros(25)) + self.assertEqual(vectors[v.stoi['']], torch.zeros(25)) + self.assertEqual(vectors[v.stoi['OOV token']], torch.zeros(25)) def test_extend(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) @@ -281,7 +280,7 @@ def test_extend(self): self.assertEqual(v.itos[:6], ['', '', '', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) - vectors = v.vectors.numpy() + vectors = v.vectors # The first 5 entries in each vector. expected_fasttext_simple_en = { @@ -290,10 +289,10 @@ def test_extend(self): } for word in expected_fasttext_simple_en: - torch.testing.assert_allclose( + self.assertEqual( vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) - torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) + self.assertEqual(vectors[v.stoi['']], torch.zeros(300)) def test_vectors_custom_cache(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) @@ -312,7 +311,7 @@ def test_vectors_custom_cache(self): self.assertEqual(v.itos, ['', '', '', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world']) - vectors = v.vectors.numpy() + vectors = v.vectors # The first 5 entries in each vector. expected_fasttext_simple_en = { @@ -321,7 +320,7 @@ def test_vectors_custom_cache(self): } for word in expected_fasttext_simple_en: - torch.testing.assert_allclose( + self.assertEqual( vectors[v.stoi[word], :5], expected_fasttext_simple_en[word]) - torch.testing.assert_allclose(vectors[v.stoi['']], np.zeros(300)) + self.assertEqual(vectors[v.stoi['']], torch.zeros(300)) diff --git a/test/test_utils.py b/test/test_utils.py index 5489f838b2..73ee992de3 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -42,6 +42,34 @@ def test_download_extract_tar(self): conditional_remove(f) conditional_remove(archive_path) + def test_download_extract_gz(self): + # create root directory for downloading data + root = '.data' + if not os.path.exists(root): + os.makedirs(root) + + # ensure archive is not already downloaded, if it is then delete + url = 'https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz' + target_archive_path = os.path.join(root, 'val.5.en.gz') + conditional_remove(target_archive_path) + + # download archive and ensure is in correct location + archive_path = utils.download_from_url(url) + assert target_archive_path == archive_path + + # extract files and ensure they are correct + files = utils.extract_archive(archive_path) + assert files == [os.path.join(root, 'val.5.en')] + + # extract files with overwrite option True + files = utils.extract_archive(archive_path, overwrite=True) + assert files == [os.path.join(root, 'val.5.en')] + + # remove files and archive + for f in files: + conditional_remove(f) + conditional_remove(archive_path) + def test_download_extract_zip(self): # create root directory for downloading data root = '.data' diff --git a/test/test_vocab.py b/test/test_vocab.py index c09bff69f2..c9b863d37a 100644 --- a/test/test_vocab.py +++ b/test/test_vocab.py @@ -5,7 +5,6 @@ import numpy as np -from numpy.testing import assert_allclose import torch from torchtext import vocab @@ -89,7 +88,7 @@ def test_vocab_set_vectors(self): expected_vectors = np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.1, 0.2], [0.5, 0.6], [0.3, 0.4]]) - assert_allclose(v.vectors.numpy(), expected_vectors) + self.assertEqual(v.vectors, expected_vectors) def test_errors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) diff --git a/torchtext/__init__.py b/torchtext/__init__.py index 97191542ec..9ce2ce9c08 100644 --- a/torchtext/__init__.py +++ b/torchtext/__init__.py @@ -1,4 +1,5 @@ from . import data +from . import modules from . import datasets from . import utils from . import vocab @@ -11,6 +12,7 @@ pass __all__ = ['data', + 'modules', 'datasets', 'utils', 'vocab', diff --git a/torchtext/csrc/regex.cpp b/torchtext/csrc/regex.cpp new file mode 100644 index 0000000000..1638c1f8e0 --- /dev/null +++ b/torchtext/csrc/regex.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +namespace torchtext { +namespace { + +struct Regex : torch::CustomClassHolder { +public: + // re_str_ holds the serialized regex string passed at the initialization. + // We need this because we need to be able to serialize the model so that we + // can save the scripted object. pickle will get the + // serialized model from this re_str_ member, thus it needs to be public. + std::string re_str_; + + Regex(const std::string &re_str) : re_str_(re_str) {} + + std::string Sub(const std::string &str, const std::string &repl) const { + std::string mutable_str = str; + RE2::GlobalReplace(&mutable_str, re_str_, repl); + return mutable_str; + } +}; + +// Registers our custom class with torch. +static auto regex = + torch::class_("torchtext", "Regex") + .def(torch::init()) + .def("Sub", &Regex::Sub) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return self->re_str_; + }, + // __setstate__ + [](std::string state) -> c10::intrusive_ptr { + return c10::make_intrusive(std::move(state)); + }); + +} // namespace +} // namespace torchtext diff --git a/torchtext/csrc/vectors.cpp b/torchtext/csrc/vectors.cpp new file mode 100644 index 0000000000..bec20e2264 --- /dev/null +++ b/torchtext/csrc/vectors.cpp @@ -0,0 +1,84 @@ +#include +#include +#include + +namespace torchtext { +namespace { + +struct Vectors : torch::CustomClassHolder { +private: + std::unordered_map stovectors_; + +public: + // tokens_, vectors_, and unk_tensor_ holds the serialized params passed in + // during initialization. We need this because we need to be able to serialize + // the model so that we can save the scripted object. Pickle will get the + // serialized model from these members, thus they needs to be public. + std::vector tokens_; + std::vector vectors_; + torch::Tensor unk_tensor_; + + explicit Vectors(const std::vector &tokens, + const std::vector &vectors, + const torch::Tensor &unk_tensor) + : tokens_(tokens), vectors_(vectors), unk_tensor_(unk_tensor) { + // guarding against size mismatch of vectors and tokens + if (tokens.size() != vectors.size()) { + throw std::runtime_error( + "Mismatching sizes for tokens and vectors. Size of tokens: " + + std::to_string(tokens.size()) + + ", size of vectors: " + std::to_string(vectors.size()) + "."); + } + + stovectors_.reserve(tokens.size()); + for (std::size_t i = 0; i < tokens.size(); i++) { + // tokens should not have any duplicates + if (stovectors_.find(tokens[i]) != stovectors_.end()) { + throw std::runtime_error("Duplicate token found in tokens list: " + + tokens[i]); + } + stovectors_[tokens[i]] = vectors_[i]; + } + } + + torch::Tensor GetItem(const std::string &token) const { + if (stovectors_.find(token) != stovectors_.end()) { + return stovectors_.at(token); + } + return unk_tensor_; + } + + void AddItem(const std::string &token, const torch::Tensor &vector) { + stovectors_[token] = vector; + } +}; + +// Registers our custom class with torch. +static auto vectors = + torch::class_("torchtext", "Vectors") + .def(torch::init, std::vector, + torch::Tensor>()) + .def("GetItem", &Vectors::GetItem) + .def("AddItem", &Vectors::AddItem) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) + -> std::tuple, + std::vector, torch::Tensor> { + std::tuple, std::vector, + torch::Tensor> + states(self->tokens_, self->vectors_, self->unk_tensor_); + return states; + }, + // __setstate__ + [](std::tuple, std::vector, + torch::Tensor> + states) -> c10::intrusive_ptr { + return c10::make_intrusive( + std::move(std::get<0>(states)), + std::move(std::get<1>(states)), + std::move(std::get<2>(states))); + }); + +} // namespace +} // namespace torchtext diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index ac2faa423b..7929f5f733 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -1,12 +1,15 @@ -from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank # NOQA +from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank, WMTNewsCrawl # NOQA from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB +from .translation import Multi30k, IWSLT, WMT14 +from .question_answer import SQuAD1, SQuAD2 __all__ = ['LanguageModelingDataset', 'WikiText2', 'WikiText103', 'PennTreebank', + 'WMTNewsCrawl', 'IMDB', 'AG_NEWS', 'SogouNews', @@ -15,4 +18,8 @@ 'YelpReviewFull', 'YahooAnswers', 'AmazonReviewPolarity', - 'AmazonReviewFull'] + 'AmazonReviewFull', + 'Multi30k', + 'IWSLT', + 'WMT14', + 'SQuAD1', 'SQuAD2'] diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index 6c0ec5799e..f44de4af88 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -1,22 +1,15 @@ import torch -import logging -import io -from torchtext.utils import download_from_url, extract_archive -from torchtext.vocab import build_vocab_from_iterator from torchtext.data.utils import get_tokenizer -from torchtext.vocab import Vocab -from torchtext.data.functional import numericalize_tokens_from_iterator - -URLS = { - 'WikiText2': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip', - 'WikiText103': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip', - 'PennTreebank': - ['https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt'] -} +from torchtext.vocab import build_vocab_from_iterator +from torchtext.experimental.datasets.raw import language_modeling as raw +from torchtext.experimental.functional import vocab_func, totensor, sequential_transforms + + +def build_vocab(data, transforms): + tok_list = [] + for txt in data: + tok_list.append(transforms(txt)) + return build_vocab_from_iterator(tok_list) class LanguageModelingDataset(torch.utils.data.Dataset): @@ -26,10 +19,11 @@ class LanguageModelingDataset(torch.utils.data.Dataset): - WikiText2 - WikiText103 - PennTreebank + - WMTNewsCrawl """ - def __init__(self, data, vocab): + def __init__(self, data, vocab, transforms, single_line): """Initiate language modeling dataset. Arguments: @@ -37,22 +31,24 @@ def __init__(self, data, vocab): numericalizing the string tokens. torch.tensor([token_id_1, token_id_2, token_id_3, token_id1]).long() vocab: Vocabulary object used for dataset. - - Examples: - >>> from torchtext.vocab import build_vocab_from_iterator - >>> data = torch.tensor([token_id_1, token_id_2, - token_id_3, token_id_1]).long() - >>> vocab = build_vocab_from_iterator([['language', 'modeling']]) - >>> dataset = LanguageModelingDataset(data, vocab) + transforms: Text string transforms. """ super(LanguageModelingDataset, self).__init__() - self.data = data self.vocab = vocab + self.transforms = transforms + self.single_line = single_line + if single_line: + self.data = torch.cat(tuple(transforms(row) for row in data), axis=0) + else: + self.data = data def __getitem__(self, i): - return self.data[i] + if self.single_line: + return self.data[i] + else: + return self.transforms(self.data[i]) def __len__(self): return len(self.data) @@ -65,63 +61,45 @@ def get_vocab(self): return self.vocab -def _get_datafile_path(key, extracted_files): - for fname in extracted_files: - if key in fname: - return fname - - -def _setup_datasets(dataset_name, tokenizer=get_tokenizer("basic_english"), - root='.data', vocab=None, removed_tokens=[], - data_select=('train', 'test', 'valid')): +def _setup_datasets(dataset_name, tokenizer=None, root='.data', vocab=None, + data_select=('train', 'test', 'valid'), single_line=True): + if tokenizer is None: + tokenizer = get_tokenizer('basic_english') + text_transform = sequential_transforms(tokenizer) if isinstance(data_select, str): data_select = [data_select] - if not set(data_select).issubset(set(('train', 'test', 'valid'))): - raise TypeError('data_select is not supported!') - - if dataset_name == 'PennTreebank': - extracted_files = [] - select_to_index = {'train': 0, 'test': 1, 'valid': 2} - extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], - root=root) for key in data_select] + if not set(data_select).issubset(set(('train', 'valid', 'test'))): + raise TypeError('Given data selection {} is not supported!'.format(data_select)) + + if not single_line and dataset_name != 'WikiText103': + raise TypeError('single_line must be True except for WikiText103') + if dataset_name == 'WMTNewsCrawl': + train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) + if single_line: + raw_data = {'train': [" ".join([txt for txt in train]), ]} + else: + raw_data = {'train': [txt for txt in train]} else: - dataset_tar = download_from_url(URLS[dataset_name], root=root) - extracted_files = extract_archive(dataset_tar) - - _path = {} - for item in data_select: - _path[item] = _get_datafile_path(item, extracted_files) + train, test, valid = raw.DATASETS[dataset_name](root=root, data_select=('train', 'test', 'valid')) + # Cache raw text iterable dataset + if single_line: + raw_data = {'train': [" ".join([txt for txt in train]), ], + 'valid': [" ".join(txt for txt in valid), ], + 'test': [" ".join(txt for txt in test), ]} + else: + raw_data = {'train': [txt for txt in train], + 'valid': [txt for txt in valid], + 'test': [txt for txt in test]} if vocab is None: - if 'train' not in _path.keys(): + if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - logging.info('Building Vocab based on {}'.format(_path['train'])) - txt_iter = iter(tokenizer(row) for row in io.open(_path['train'], - encoding="utf8")) - vocab = build_vocab_from_iterator(txt_iter) - logging.info('Vocab has {} entries'.format(len(vocab))) - else: - if not isinstance(vocab, Vocab): - raise TypeError("Passed vocabulary is not of type Vocab") - - data = {} - for item in _path.keys(): - data[item] = [] - logging.info('Creating {} data'.format(item)) - txt_iter = iter(tokenizer(row) for row in io.open(_path[item], - encoding="utf8")) - _iter = numericalize_tokens_from_iterator( - vocab, txt_iter, removed_tokens) - for tokens in _iter: - data[item] += [token_id for token_id in tokens] - - for key in data_select: - if data[key] == []: - raise TypeError('Dataset {} is empty!'.format(key)) - - return tuple(LanguageModelingDataset(torch.tensor(data[d]).long(), vocab) - for d in data_select) + vocab = build_vocab(raw_data['train'], text_transform) + text_transform = sequential_transforms(text_transform, vocab_func(vocab), + totensor(dtype=torch.long)) + return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform, single_line) + for item in data_select) def WikiText2(*args, **kwargs): @@ -138,7 +116,6 @@ def WikiText2(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -146,6 +123,10 @@ def WikiText2(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText2 @@ -175,12 +156,6 @@ def WikiText103(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: the returned datasets (Default: ('train', 'test','valid')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test'). - If 'train' is not in the tuple, an vocab object should be provided which will - be used to process valid and/or test data. - removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -188,6 +163,10 @@ def WikiText103(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText103 @@ -217,7 +196,6 @@ def PennTreebank(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - removed_tokens: removed tokens from output dataset (Default: []) data_select: a string or tupel for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets (train, test, valid) are generated. Users @@ -225,6 +203,10 @@ def PennTreebank(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import PennTreebank @@ -238,3 +220,42 @@ def PennTreebank(*args, **kwargs): """ return _setup_datasets(*(("PennTreebank",) + args), **kwargs) + + +def WMTNewsCrawl(*args, **kwargs): + """ Defines WMTNewsCrawl datasets. + + Create language modeling dataset: WMTNewsCrawl + returns the train set + + Arguments: + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well (see example below). A custom tokenizer is callable + function with input of a string and output of a token list. + root: Directory where the datasets are saved. Default: ".data" + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + data_select: a string or tupel for the returned datasets + (Default: ('train',)) + single_line: whether to return all tokens in a single line. + (Default: True) + By default, all lines in raw text file are concatenated into a single line. + Use `single_line = False` if one wants to get data line by line. + Examples: + >>> from torchtext.experimental.datasets import WMTNewsCrawl + >>> from torchtext.data.utils import get_tokenizer + >>> tokenizer = get_tokenizer("spacy") + >>> train_dataset, = WMTNewsCrawl(tokenizer=tokenizer, data_select='train') + + """ + + return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) + + +DATASETS = { + 'WikiText2': WikiText2, + 'WikiText103': WikiText103, + 'PennTreebank': PennTreebank, + 'WMTNewsCrawl': WMTNewsCrawl +} diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py new file mode 100644 index 0000000000..094a252bfc --- /dev/null +++ b/torchtext/experimental/datasets/question_answer.py @@ -0,0 +1,163 @@ +import torch +from torchtext.data.utils import get_tokenizer +from torchtext.vocab import build_vocab_from_iterator +from torchtext.experimental.datasets.raw import question_answer as raw +from torchtext.experimental.functional import ( + totensor, + vocab_func, + sequential_transforms, +) + + +class QuestionAnswerDataset(torch.utils.data.Dataset): + """Defines an abstract question answer datasets. + Currently, we only support the following datasets: + - SQuAD1 + - SQuAD2 + """ + + def __init__(self, data, vocab, transforms): + """Initiate question answer dataset. + + Arguments: + data: a dictionary of data. + For example {'context': context_data, 'answers': answers_data, + 'question': question_data, 'ans_pos': ans_pos_data} + vocab: Vocabulary object used for dataset. + transforms: a dictionary of transforms. + For example {'context': context_transform, 'answers': answers_transform, + 'question': question_transform, 'ans_pos': ans_pos_transform} + """ + + super(QuestionAnswerDataset, self).__init__() + self.data = data + self.vocab = vocab + self.transforms = transforms + + def __getitem__(self, i): + _data = {'context': self.transforms['context'](self.data[i]['context']), + 'question': self.transforms['question'](self.data[i]['question']), + 'answers': [], 'ans_pos': []} + for idx in range(len(self.data[i]['answer_start'])): + _data['answers'].append(self.transforms['answers'](self.data[i]['answers'][idx])) + ans_start_idx = self.data[i]['answer_start'][idx] + if ans_start_idx == -1: # No answer for this sample + _data['ans_pos'].append(self.transforms['ans_pos']([-1, -1])) + else: + ans_start_token_idx = len(self.transforms['context'](self.data[i]['context'][:ans_start_idx])) + ans_end_token_idx = ans_start_token_idx + \ + len(self.transforms['answers'](self.data[i]['answers'][idx])) - 1 + _data['ans_pos'].append(self.transforms['ans_pos']([ans_start_token_idx, ans_end_token_idx])) + return _data + + def __len__(self): + return len(self.data) + + def get_vocab(self): + return self.vocab + + +def _setup_datasets(dataset_name, + root='.data', + vocab=None, + tokenizer=None, + data_select=('train', 'dev')): + text_transform = [] + if tokenizer is None: + tokenizer = get_tokenizer('basic_english') + text_transform = sequential_transforms(tokenizer) + if isinstance(data_select, str): + data_select = [data_select] + if not set(data_select).issubset(set(('train', 'dev'))): + raise TypeError('Given data selection {} is not supported!'.format(data_select)) + train, dev = raw.DATASETS[dataset_name](root=root) + raw_data = {'train': [item for item in train], + 'dev': [item for item in dev]} + if vocab is None: + if 'train' not in data_select: + raise TypeError("Must pass a vocab if train is not selected.") + tok_list = [] + for raw_dict in raw_data['train']: + tok_ans = [] + for item in raw_dict['answers']: + tok_ans += text_transform(item) + tok_list.append(text_transform(raw_dict['context']) + + text_transform(raw_dict['question']) + tok_ans) + vocab = build_vocab_from_iterator(tok_list) + text_transform = sequential_transforms(text_transform, vocab_func(vocab), totensor(dtype=torch.long)) + transforms = {'context': text_transform, 'question': text_transform, + 'answers': text_transform, 'ans_pos': totensor(dtype=torch.long)} + return tuple(QuestionAnswerDataset(raw_data[item], vocab, transforms) for item in data_select) + + +def SQuAD1(*args, **kwargs): + """ Defines SQuAD1 datasets. + + Create question answer dataset: SQuAD1 + + Separately returns the train and dev dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'dev')) + By default, all the two datasets (train, dev) are generated. Users + could also choose any one of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import SQuAD1 + >>> from torchtext.data.utils import get_tokenizer + >>> train, dev = SQuAD1() + >>> tokenizer = get_tokenizer("spacy") + >>> train, dev = SQuAD1(tokenizer=tokenizer) + """ + + return _setup_datasets(*(('SQuAD1',) + args), **kwargs) + + +def SQuAD2(*args, **kwargs): + """ Defines SQuAD2 datasets. + + Create question answer dataset: SQuAD2 + + Separately returns the train and dev dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + vocab: Vocabulary used for dataset. If None, it will generate a new + vocabulary based on the train data set. + tokenizer: the tokenizer used to preprocess raw text data. + The default one is basic_english tokenizer in fastText. spacy tokenizer + is supported as well. A custom tokenizer is callable + function with input of a string and output of a token list. + data_select: a string or tuple for the returned datasets + (Default: ('train', 'dev')) + By default, all the two datasets (train, dev) are generated. Users + could also choose any one of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets import SQuAD2 + >>> from torchtext.data.utils import get_tokenizer + >>> train, dev = SQuAD2() + >>> tokenizer = get_tokenizer("spacy") + >>> train, dev = SQuAD2(tokenizer=tokenizer) + """ + return _setup_datasets(*(('SQuAD2',) + args), **kwargs) + + +DATASETS = { + 'SQuAD1': SQuAD1, + 'SQuAD2': SQuAD2 +} diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py index 61accbe2a1..ad100429b0 100644 --- a/torchtext/experimental/datasets/raw/__init__.py +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -1,6 +1,9 @@ from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB +from .translation import Multi30k, IWSLT, WMT14 +from .language_modeling import WikiText2, WikiText103, PennTreebank, WMTNewsCrawl +from .question_answer import SQuAD1, SQuAD2 __all__ = ['IMDB', 'AG_NEWS', @@ -10,4 +13,12 @@ 'YelpReviewFull', 'YahooAnswers', 'AmazonReviewPolarity', - 'AmazonReviewFull'] + 'AmazonReviewFull', + 'Multi30k', + 'IWSLT', + 'WMT14', + 'WikiText2', + 'WikiText103', + 'PennTreebank', + 'WMTNewsCrawl', + 'SQuAD1', 'SQuAD2'] diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py new file mode 100644 index 0000000000..a867108978 --- /dev/null +++ b/torchtext/experimental/datasets/raw/language_modeling.py @@ -0,0 +1,184 @@ +import torch +import logging +import io +from torchtext.utils import download_from_url, extract_archive + +URLS = { + 'WikiText2': + 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip', + 'WikiText103': + 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip', + 'PennTreebank': + ['https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt', + 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt', + 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt'], + 'WMTNewsCrawl': 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' +} + + +class RawTextIterableDataset(torch.utils.data.IterableDataset): + """Defines an abstraction for raw text iterable datasets. + """ + + def __init__(self, iterator, start=0, num_lines=None): + """Initiate language modeling dataset. + """ + super(RawTextIterableDataset, self).__init__() + self._iterator = iterator + self.has_setup = False + self.start = start + self.num_lines = num_lines + + def setup_iter(self, start=0, num_lines=None): + self.start = start + self.num_lines = num_lines + self.has_setup = True + + def __iter__(self): + if not self.has_setup: + self.setup_iter() + for i, item in enumerate(self._iterator): + if i >= self.start: + yield item + if (self.num_lines is not None) and (i == (self.start + self.num_lines)): + break + + def get_iterator(self): + return self._iterator + + +def _setup_datasets(dataset_name, root='.data', data_select=('train', 'test', 'valid'), **kwargs): + if isinstance(data_select, str): + data_select = [data_select] + if not set(data_select).issubset(set(('train', 'test', 'valid'))): + raise TypeError('data_select is not supported!') + + if dataset_name == 'PennTreebank': + extracted_files = [] + select_to_index = {'train': 0, 'test': 1, 'valid': 2} + extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], + root=root) for key in data_select] + elif dataset_name == 'WMTNewsCrawl': + if not (data_select == ['train'] or set(data_select).issubset(set(('train',)))): + raise ValueError("WMTNewsCrawl only creates a training dataset. " + "data_select should be 'train' " + "or ('train',), got {}.".format(data_select)) + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files = extract_archive(dataset_tar) + year = kwargs.get('year', 2010) + language = kwargs.get('language', 'en') + file_name = 'news.{}.{}.shuffled'.format(year, language) + extracted_files = [f for f in extracted_files if file_name in f] + else: + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files = extract_archive(dataset_tar) + + _path = {} + for item in data_select: + for fname in extracted_files: + if item in fname: + _path[item] = fname + + data = {} + for item in _path.keys(): + logging.info('Creating {} data'.format(item)) + data[item] = iter(io.open(_path[item], encoding="utf8")) + + return tuple(RawTextIterableDataset(data[item]) for item in data_select) + + +def WikiText2(*args, **kwargs): + """ Defines WikiText2 datasets. + + Create language modeling dataset: WikiText2 + Separately returns the train/test/valid set + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tupel for the returned datasets + (Default: ('train', 'test','valid')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.raw.datasets import WikiText2 + >>> train_dataset, test_dataset, valid_dataset = WikiText2() + >>> valid_dataset, = WikiText2(data_select='valid') + + """ + + return _setup_datasets(*(("WikiText2",) + args), **kwargs) + + +def WikiText103(*args, **kwargs): + """ Defines WikiText103 datasets. + + Create language modeling dataset: WikiText103 + Separately returns the train/test/valid set + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: the returned datasets (Default: ('train', 'test','valid')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test'). + If 'train' is not in the tuple, an vocab object should be provided which will + be used to process valid and/or test data. + + Examples: + >>> from torchtext.experimental.datasets.raw import WikiText103 + >>> train_dataset, test_dataset, valid_dataset = WikiText103() + >>> valid_dataset, = WikiText103(data_select='valid') + """ + + return _setup_datasets(*(("WikiText103",) + args), **kwargs) + + +def PennTreebank(*args, **kwargs): + """ Defines PennTreebank datasets. + + Create language modeling dataset: PennTreebank + Separately returns the train/test/valid set + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets + (Default: ('train', 'test','valid')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.experimental.datasets.raw import PennTreebank + >>> train_dataset, test_dataset, valid_dataset = PennTreebank() + >>> valid_dataset, = PennTreebank(data_select='valid') + + """ + + return _setup_datasets(*(("PennTreebank",) + args), **kwargs) + + +def WMTNewsCrawl(*args, **kwargs): + """ Defines WMT News Crawl. + + Create language modeling dataset: WMTNewsCrawl + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. + (Default: 'train') + """ + + return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) + + +DATASETS = { + 'WikiText2': WikiText2, + 'WikiText103': WikiText103, + 'PennTreebank': PennTreebank, + 'WMTNewsCrawl': WMTNewsCrawl +} diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py new file mode 100644 index 0000000000..528e3e9930 --- /dev/null +++ b/torchtext/experimental/datasets/raw/question_answer.py @@ -0,0 +1,93 @@ +import torch +from torchtext.utils import download_from_url +import json + +URLS = { + 'SQuAD1': + ['https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json', + 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json'], + 'SQuAD2': + ['https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json', + 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json'] +} + + +def _create_data_from_json(data_path): + with open(data_path) as json_file: + raw_json_data = json.load(json_file)['data'] + for layer1 in raw_json_data: + for layer2 in layer1['paragraphs']: + for layer3 in layer2['qas']: + processed = {'context': layer2['context'], 'question': layer3['question'], + 'answers': [item['text'] for item in layer3['answers']], + 'answer_start': [item['answer_start'] for item in layer3['answers']]} + if len(processed['answers']) == 0: + processed['answers'] = [""] + processed['answer_start'] = [-1] + yield processed + + +class RawQuestionAnswerDataset(torch.utils.data.IterableDataset): + """Defines an abstraction for raw question answer iterable datasets. + """ + + def __init__(self, iterator): + """Initiate text-classification dataset. + """ + super(RawQuestionAnswerDataset, self).__init__() + self._iterator = iterator + self.has_setup = False + self.start = 0 + self.num_lines = None + + def setup_iter(self, start=0, num_lines=None): + self.start = start + self.num_lines = num_lines + self.has_setup = True + + def __iter__(self): + if not self.has_setup: + self.setup_iter() + + for i, item in enumerate(self._iterator): + if i >= self.start: + yield item + if self.num_lines is not None and i == (self.start + self.num_lines): + break + + +def _setup_datasets(dataset_name, root='.data'): + extracted_files = [] + select_to_index = {'train': 0, 'dev': 1} + extracted_files = [download_from_url(URLS[dataset_name][select_to_index[key]], + root=root) for key in select_to_index.keys()] + train_iter = _create_data_from_json(extracted_files[0]) + dev_iter = _create_data_from_json(extracted_files[1]) + return (RawQuestionAnswerDataset(train_iter), + RawQuestionAnswerDataset(dev_iter)) + + +def SQuAD1(*args, **kwargs): + """ Defines SQuAD1 datasets. + + Examples: + >>> train, dev = torchtext.experimental.datasets.raw.SQuAD1() + """ + + return _setup_datasets(*(("SQuAD1",) + args), **kwargs) + + +def SQuAD2(*args, **kwargs): + """ Defines SQuAD2 datasets. + + Examples: + >>> train, dev = torchtext.experimental.datasets.raw.SQuAD2() + """ + + return _setup_datasets(*(("SQuAD2",) + args), **kwargs) + + +DATASETS = { + 'SQuAD1': SQuAD1, + 'SQuAD2': SQuAD2 +} diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py new file mode 100644 index 0000000000..19f5275d41 --- /dev/null +++ b/torchtext/experimental/datasets/raw/translation.py @@ -0,0 +1,544 @@ +import torch +import os +import io +import codecs +import xml.etree.ElementTree as ET +from collections import defaultdict + +from torchtext.utils import (download_from_url, extract_archive, + unicode_csv_reader) + +URLS = { + 'Multi30k': [ + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", + "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz" + ], + 'WMT14': + 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8', + 'IWSLT': + 'https://wit3.fbk.eu/archive/2016-01//texts/{}/{}/{}.tgz' +} + + +def _read_text_iterator(path): + with io.open(path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield " ".join(row) + + +def _clean_xml_file(f_xml): + f_txt = os.path.splitext(f_xml)[0] + with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: + root = ET.parse(f_xml).getroot()[0] + for doc in root.findall('doc'): + for e in doc.findall('seg'): + fd_txt.write(e.text.strip() + '\n') + + +def _clean_tags_file(f_orig): + xml_tags = [ + '= self.start: + yield item + if (self.num_lines is not None) and (i == (self.start + + self.num_lines)): + break + + def get_iterator(self): + return (self._src_iterator, self._tgt_iterator) + + +def Multi30k(train_filenames=("train.de", "train.en"), + valid_filenames=("val.de", "val.en"), + test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), + root='.data'): + """ Define translation datasets: Multi30k + Separately returns train/valid/test datasets as a tuple + The available dataset include: + test_2016_flickr.cs + test_2016_flickr.de + test_2016_flickr.en + test_2016_flickr.fr + test_2017_flickr.de + test_2017_flickr.en + test_2017_flickr.fr + test_2017_mscoco.de + test_2017_mscoco.en + test_2017_mscoco.fr + test_2018_flickr.en + train.cs + train.de + train.en + train.fr + val.cs + val.de + val.en + val.fr + test_2016.1.de + test_2016.1.en + test_2016.2.de + test_2016.2.en + test_2016.3.de + test_2016.3.en + test_2016.4.de + test_2016.4.en + test_2016.5.de + test_2016.5.en + train.1.de + train.1.en + train.2.de + train.2.en + train.3.de + train.3.en + train.4.de + train.4.en + train.5.de + train.5.en + val.1.de + val.1.en + val.2.de + val.2.en + val.3.de + val.3.en + val.4.de + val.4.en + val.5.de + val.5.en + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de', 'train.en') + valid_filenames: the source and target filenames for valid. + Default: ('val.de', 'val.en') + test_filenames: the source and target filenames for test. + Default: ('test2016.de', 'test2016.en') + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets import Multi30k + >>> train_dataset, valid_dataset, test_dataset = Multi30k() + """ + return _setup_datasets("Multi30k", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root) + + +def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), + valid_filenames=('IWSLT16.TED.tst2013.de-en.de', + 'IWSLT16.TED.tst2013.de-en.en'), + test_filenames=('IWSLT16.TED.tst2014.de-en.de', + 'IWSLT16.TED.tst2014.de-en.en'), + root='.data'): + """ Define translation datasets: IWSLT + Separately returns train/valid/test datasets + The available datasets include: + IWSLT16.TED.dev2010.ar-en.ar + IWSLT16.TED.dev2010.ar-en.en + IWSLT16.TED.dev2010.cs-en.cs + IWSLT16.TED.dev2010.cs-en.en + IWSLT16.TED.dev2010.de-en.de + IWSLT16.TED.dev2010.de-en.en + IWSLT16.TED.dev2010.en-ar.ar + IWSLT16.TED.dev2010.en-ar.en + IWSLT16.TED.dev2010.en-cs.cs + IWSLT16.TED.dev2010.en-cs.en + IWSLT16.TED.dev2010.en-de.de + IWSLT16.TED.dev2010.en-de.en + IWSLT16.TED.dev2010.en-fr.en + IWSLT16.TED.dev2010.en-fr.fr + IWSLT16.TED.dev2010.fr-en.en + IWSLT16.TED.dev2010.fr-en.fr + IWSLT16.TED.tst2010.ar-en.ar + IWSLT16.TED.tst2010.ar-en.en + IWSLT16.TED.tst2010.cs-en.cs + IWSLT16.TED.tst2010.cs-en.en + IWSLT16.TED.tst2010.de-en.de + IWSLT16.TED.tst2010.de-en.en + IWSLT16.TED.tst2010.en-ar.ar + IWSLT16.TED.tst2010.en-ar.en + IWSLT16.TED.tst2010.en-cs.cs + IWSLT16.TED.tst2010.en-cs.en + IWSLT16.TED.tst2010.en-de.de + IWSLT16.TED.tst2010.en-de.en + IWSLT16.TED.tst2010.en-fr.en + IWSLT16.TED.tst2010.en-fr.fr + IWSLT16.TED.tst2010.fr-en.en + IWSLT16.TED.tst2010.fr-en.fr + IWSLT16.TED.tst2011.ar-en.ar + IWSLT16.TED.tst2011.ar-en.en + IWSLT16.TED.tst2011.cs-en.cs + IWSLT16.TED.tst2011.cs-en.en + IWSLT16.TED.tst2011.de-en.de + IWSLT16.TED.tst2011.de-en.en + IWSLT16.TED.tst2011.en-ar.ar + IWSLT16.TED.tst2011.en-ar.en + IWSLT16.TED.tst2011.en-cs.cs + IWSLT16.TED.tst2011.en-cs.en + IWSLT16.TED.tst2011.en-de.de + IWSLT16.TED.tst2011.en-de.en + IWSLT16.TED.tst2011.en-fr.en + IWSLT16.TED.tst2011.en-fr.fr + IWSLT16.TED.tst2011.fr-en.en + IWSLT16.TED.tst2011.fr-en.fr + IWSLT16.TED.tst2012.ar-en.ar + IWSLT16.TED.tst2012.ar-en.en + IWSLT16.TED.tst2012.cs-en.cs + IWSLT16.TED.tst2012.cs-en.en + IWSLT16.TED.tst2012.de-en.de + IWSLT16.TED.tst2012.de-en.en + IWSLT16.TED.tst2012.en-ar.ar + IWSLT16.TED.tst2012.en-ar.en + IWSLT16.TED.tst2012.en-cs.cs + IWSLT16.TED.tst2012.en-cs.en + IWSLT16.TED.tst2012.en-de.de + IWSLT16.TED.tst2012.en-de.en + IWSLT16.TED.tst2012.en-fr.en + IWSLT16.TED.tst2012.en-fr.fr + IWSLT16.TED.tst2012.fr-en.en + IWSLT16.TED.tst2012.fr-en.fr + IWSLT16.TED.tst2013.ar-en.ar + IWSLT16.TED.tst2013.ar-en.en + IWSLT16.TED.tst2013.cs-en.cs + IWSLT16.TED.tst2013.cs-en.en + IWSLT16.TED.tst2013.de-en.de + IWSLT16.TED.tst2013.de-en.en + IWSLT16.TED.tst2013.en-ar.ar + IWSLT16.TED.tst2013.en-ar.en + IWSLT16.TED.tst2013.en-cs.cs + IWSLT16.TED.tst2013.en-cs.en + IWSLT16.TED.tst2013.en-de.de + IWSLT16.TED.tst2013.en-de.en + IWSLT16.TED.tst2013.en-fr.en + IWSLT16.TED.tst2013.en-fr.fr + IWSLT16.TED.tst2013.fr-en.en + IWSLT16.TED.tst2013.fr-en.fr + IWSLT16.TED.tst2014.ar-en.ar + IWSLT16.TED.tst2014.ar-en.en + IWSLT16.TED.tst2014.de-en.de + IWSLT16.TED.tst2014.de-en.en + IWSLT16.TED.tst2014.en-ar.ar + IWSLT16.TED.tst2014.en-ar.en + IWSLT16.TED.tst2014.en-de.de + IWSLT16.TED.tst2014.en-de.en + IWSLT16.TED.tst2014.en-fr.en + IWSLT16.TED.tst2014.en-fr.fr + IWSLT16.TED.tst2014.fr-en.en + IWSLT16.TED.tst2014.fr-en.fr + IWSLT16.TEDX.dev2012.de-en.de + IWSLT16.TEDX.dev2012.de-en.en + IWSLT16.TEDX.tst2013.de-en.de + IWSLT16.TEDX.tst2013.de-en.en + IWSLT16.TEDX.tst2014.de-en.de + IWSLT16.TEDX.tst2014.de-en.en + train.ar + train.ar-en.ar + train.ar-en.en + train.cs + train.cs-en.cs + train.cs-en.en + train.de + train.de-en.de + train.de-en.en + train.en + train.en-ar.ar + train.en-ar.en + train.en-cs.cs + train.en-cs.en + train.en-de.de + train.en-de.en + train.en-fr.en + train.en-fr.fr + train.fr + train.fr-en.en + train.fr-en.fr + train.tags.ar-en.ar + train.tags.ar-en.en + train.tags.cs-en.cs + train.tags.cs-en.en + train.tags.de-en.de + train.tags.de-en.en + train.tags.en-ar.ar + train.tags.en-ar.en + train.tags.en-cs.cs + train.tags.en-cs.en + train.tags.en-de.de + train.tags.en-de.en + train.tags.en-fr.en + train.tags.en-fr.fr + train.tags.fr-en.en + train.tags.fr-en.fr + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de-en.de', 'train.de-en.en') + valid_filenames: the source and target filenames for valid. + Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') + test_filenames: the source and target filenames for test. + Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets.raw import IWSLT + >>> train_dataset, valid_dataset, test_dataset = IWSLT() + """ + src_language = train_filenames[0].split(".")[-1] + tgt_language = train_filenames[1].split(".")[-1] + languages = "-".join([src_language, tgt_language]) + URLS["IWSLT"] = URLS["IWSLT"].format(src_language, tgt_language, languages) + + return _setup_datasets( + "IWSLT", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root, + ) + + +def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', + 'train.tok.clean.bpe.32000.en'), + valid_filenames=('newstest2013.tok.bpe.32000.de', + 'newstest2013.tok.bpe.32000.en'), + test_filenames=('newstest2014.tok.bpe.32000.de', + 'newstest2014.tok.bpe.32000.en'), + root='.data'): + """ Define translation datasets: WMT14 + Separately returns train/valid/test datasets + The available datasets include: + newstest2016.en + newstest2016.de + newstest2015.en + newstest2015.de + newstest2014.en + newstest2014.de + newstest2013.en + newstest2013.de + newstest2012.en + newstest2012.de + newstest2011.tok.de + newstest2011.en + newstest2011.de + newstest2010.tok.de + newstest2010.en + newstest2010.de + newstest2009.tok.de + newstest2009.en + newstest2009.de + newstest2016.tok.de + newstest2015.tok.de + newstest2014.tok.de + newstest2013.tok.de + newstest2012.tok.de + newstest2010.tok.en + newstest2009.tok.en + newstest2015.tok.en + newstest2014.tok.en + newstest2013.tok.en + newstest2012.tok.en + newstest2011.tok.en + newstest2016.tok.en + newstest2009.tok.bpe.32000.en + newstest2011.tok.bpe.32000.en + newstest2010.tok.bpe.32000.en + newstest2013.tok.bpe.32000.en + newstest2012.tok.bpe.32000.en + newstest2015.tok.bpe.32000.en + newstest2014.tok.bpe.32000.en + newstest2016.tok.bpe.32000.en + train.tok.clean.bpe.32000.en + newstest2009.tok.bpe.32000.de + newstest2010.tok.bpe.32000.de + newstest2011.tok.bpe.32000.de + newstest2013.tok.bpe.32000.de + newstest2012.tok.bpe.32000.de + newstest2014.tok.bpe.32000.de + newstest2016.tok.bpe.32000.de + newstest2015.tok.bpe.32000.de + train.tok.clean.bpe.32000.de + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') + valid_filenames: the source and target filenames for valid. + Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') + test_filenames: the source and target filenames for test. + Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets import WMT14 + >>> train_dataset, valid_dataset, test_dataset = WMT14() + """ + + return _setup_datasets("WMT14", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root) + + +DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py new file mode 100644 index 0000000000..5fad51135d --- /dev/null +++ b/torchtext/experimental/datasets/translation.py @@ -0,0 +1,551 @@ +import torch +import logging + +from torchtext.experimental.datasets import raw +from torchtext.vocab import build_vocab_from_iterator +from torchtext.data.utils import get_tokenizer +from ..functional import vocab_func, totensor, sequential_transforms + + +def build_vocab(data, transforms, index): + tok_list = [] + for line in data: + tok_list.append(transforms(line[index])) + return build_vocab_from_iterator(tok_list) + + +def _setup_datasets(dataset_name, + train_filenames, + valid_filenames, + test_filenames, + data_select=('train', 'test', 'valid'), + root='.data', + vocab=(None, None), + tokenizer=None, + removed_tokens=['']): + src_vocab, tgt_vocab = vocab + if tokenizer is None: + src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') + tgt_tokenizer = get_tokenizer("spacy", language='en_core_web_sm') + elif isinstance(tokenizer, tuple): + if len(tokenizer) == 2: + src_tokenizer, tgt_tokenizer = tokenizer + else: + raise ValueError("tokenizer must have length of two for" + "source and target") + else: + raise ValueError( + "tokenizer must be an instance of tuple with length two" + "or None") + train, val, test = DATASETS[dataset_name](train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root) + raw_data = { + "train": [line for line in train], + "valid": [line for line in val], + "test": [line for line in test] + } + src_text_vocab_transform = sequential_transforms(src_tokenizer) + tgt_text_vocab_transform = sequential_transforms(tgt_tokenizer) + + if src_vocab is None: + if 'train' not in data_select: + raise TypeError("Must pass a vocab if train is not selected.") + logging.info('Building src Vocab based on train data') + src_vocab = build_vocab(raw_data["train"], + src_text_vocab_transform, + index=0) + else: + if not isinstance(src_vocab, Vocab): + raise TypeError("Passed src vocabulary is not of type Vocab") + logging.info('src Vocab has {} entries'.format(len(src_vocab))) + + if tgt_vocab is None: + if 'train' not in data_select: + raise TypeError("Must pass a vocab if train is not selected.") + logging.info('Building tgt Vocab based on train data') + tgt_vocab = build_vocab(raw_data["train"], + tgt_text_vocab_transform, + index=1) + else: + if not isinstance(tgt_vocab, Vocab): + raise TypeError("Passed tgt vocabulary is not of type Vocab") + logging.info('tgt Vocab has {} entries'.format(len(tgt_vocab))) + + logging.info('Building datasets for {}'.format(data_select)) + datasets = [] + for key in data_select: + src_text_transform = sequential_transforms(src_text_vocab_transform, + vocab_func(src_vocab), + totensor(dtype=torch.long)) + tgt_text_transform = sequential_transforms(tgt_text_vocab_transform, + vocab_func(tgt_vocab), + totensor(dtype=torch.long)) + datasets.append( + TranslationDataset(raw_data[key], (src_vocab, tgt_vocab), + (src_text_transform, tgt_text_transform))) + + return tuple(datasets) + + +class TranslationDataset(torch.utils.data.Dataset): + """Defines a dataset for translation. + Currently, we only support the following datasets: + - Multi30k + - WMT14 + - IWSLT + """ + def __init__(self, data, vocab, transforms): + """Initiate translation dataset. + + Arguments: + data: a tuple of source and target tensors, which include token ids + numericalizing the string tokens. + [(src_tensor0, tgt_tensor0), (src_tensor1, tgt_tensor1)] + vocab: source and target Vocabulary object used for dataset. + (src_vocab, tgt_vocab) + transforms: a tuple of source and target string transforms. + + Examples: + >>> from torchtext.vocab import build_vocab_from_iterator + >>> src_data = torch.Tensor([token_id_s1, token_id_s2, + token_id_s3, token_id_s1]).long() + >>> tgt_data = torch.Tensor([token_id_t1, token_id_t2, + token_id_t3, token_id_t1]).long() + >>> src_vocab = build_vocab_from_iterator([['Übersetzungsdatensatz']]) + >>> tgt_vocab = build_vocab_from_iterator([['translation', 'dataset']]) + >>> dataset = TranslationDataset([(src_data, tgt_data)], + (src_vocab, tgt_vocab)) + """ + + super(TranslationDataset, self).__init__() + self.data = data + self.vocab = vocab + self.transforms = transforms + + def __getitem__(self, i): + source = self.transforms[0](self.data[i][0]) + target = self.transforms[1](self.data[i][1]) + return (source, target) + + def __len__(self): + return len(self.data) + + def get_vocab(self): + return self.vocab + + +def Multi30k(train_filenames=("train.de", "train.en"), + valid_filenames=("val.de", "val.en"), + test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), + tokenizer=None, + root='.data', + vocab=(None, None), + data_select=('train', 'valid', 'test'), + removed_tokens=['']): + """ Define translation datasets: Multi30k + Separately returns train/valid/test datasets as a tuple + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de', 'train.en') + valid_filenames: the source and target filenames for valid. + Default: ('val.de', 'val.en') + test_filenames: the source and target filenames for test. + Default: ('test2016.de', 'test2016.en') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + root: Directory where the datasets are saved. Default: ".data" + vocab: Source and target Vocabulary objects used for dataset. If None, it + will generate a new vocabulary based on the train data set. It has to be + in a form of tuple. + Default: (None, None) + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + removed_tokens: removed tokens from output dataset (Default: '') + The available dataset include: + test_2016_flickr.cs + test_2016_flickr.de + test_2016_flickr.en + test_2016_flickr.fr + test_2017_flickr.de + test_2017_flickr.en + test_2017_flickr.fr + test_2017_mscoco.de + test_2017_mscoco.en + test_2017_mscoco.fr + test_2018_flickr.en + train.cs + train.de + train.en + train.fr + val.cs + val.de + val.en + val.fr + test_2016.1.de + test_2016.1.en + test_2016.2.de + test_2016.2.en + test_2016.3.de + test_2016.3.en + test_2016.4.de + test_2016.4.en + test_2016.5.de + test_2016.5.en + train.1.de + train.1.en + train.2.de + train.2.en + train.3.de + train.3.en + train.4.de + train.4.en + train.5.de + train.5.en + val.1.de + val.1.en + val.2.de + val.2.en + val.3.de + val.3.en + val.4.de + val.4.en + val.5.de + val.5.en + + Examples: + >>> from torchtext.datasets import Multi30k + >>> from torchtext.data.utils import get_tokenizer + >>> tokenizer = (get_tokenizer("spacy", language='de'), + get_tokenizer("basic_english")) + >>> train_dataset, valid_dataset, test_dataset = Multi30k(tokenizer=tokenizer) + >>> src_vocab, tgt_vocab = train_dataset.get_vocab() + >>> src_data, tgt_data = train_dataset[10] + """ + return _setup_datasets("Multi30k", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + tokenizer=tokenizer, + root=root, + vocab=vocab, + removed_tokens=removed_tokens) + + +def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), + valid_filenames=('IWSLT16.TED.tst2013.de-en.de', + 'IWSLT16.TED.tst2013.de-en.en'), + test_filenames=('IWSLT16.TED.tst2014.de-en.de', + 'IWSLT16.TED.tst2014.de-en.en'), + tokenizer=None, + root='.data', + vocab=(None, None), + data_select=('train', 'valid', 'test'), + removed_tokens=['']): + """ Define translation datasets: IWSLT + Separately returns train/valid/test datasets + The available datasets include: + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.de-en.de', 'train.de-en.en') + valid_filenames: the source and target filenames for valid. + Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') + test_filenames: the source and target filenames for test. + Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + root: Directory where the datasets are saved. Default: ".data" + vocab: Source and target Vocabulary objects used for dataset. If None, it + will generate a new vocabulary based on the train data set. It has to be + in a form of tuple. + Default: (None, None) + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + removed_tokens: removed tokens from output dataset (Default: '') + The available datasets include: + IWSLT16.TED.dev2010.ar-en.ar + IWSLT16.TED.dev2010.ar-en.en + IWSLT16.TED.dev2010.cs-en.cs + IWSLT16.TED.dev2010.cs-en.en + IWSLT16.TED.dev2010.de-en.de + IWSLT16.TED.dev2010.de-en.en + IWSLT16.TED.dev2010.en-ar.ar + IWSLT16.TED.dev2010.en-ar.en + IWSLT16.TED.dev2010.en-cs.cs + IWSLT16.TED.dev2010.en-cs.en + IWSLT16.TED.dev2010.en-de.de + IWSLT16.TED.dev2010.en-de.en + IWSLT16.TED.dev2010.en-fr.en + IWSLT16.TED.dev2010.en-fr.fr + IWSLT16.TED.dev2010.fr-en.en + IWSLT16.TED.dev2010.fr-en.fr + IWSLT16.TED.tst2010.ar-en.ar + IWSLT16.TED.tst2010.ar-en.en + IWSLT16.TED.tst2010.cs-en.cs + IWSLT16.TED.tst2010.cs-en.en + IWSLT16.TED.tst2010.de-en.de + IWSLT16.TED.tst2010.de-en.en + IWSLT16.TED.tst2010.en-ar.ar + IWSLT16.TED.tst2010.en-ar.en + IWSLT16.TED.tst2010.en-cs.cs + IWSLT16.TED.tst2010.en-cs.en + IWSLT16.TED.tst2010.en-de.de + IWSLT16.TED.tst2010.en-de.en + IWSLT16.TED.tst2010.en-fr.en + IWSLT16.TED.tst2010.en-fr.fr + IWSLT16.TED.tst2010.fr-en.en + IWSLT16.TED.tst2010.fr-en.fr + IWSLT16.TED.tst2011.ar-en.ar + IWSLT16.TED.tst2011.ar-en.en + IWSLT16.TED.tst2011.cs-en.cs + IWSLT16.TED.tst2011.cs-en.en + IWSLT16.TED.tst2011.de-en.de + IWSLT16.TED.tst2011.de-en.en + IWSLT16.TED.tst2011.en-ar.ar + IWSLT16.TED.tst2011.en-ar.en + IWSLT16.TED.tst2011.en-cs.cs + IWSLT16.TED.tst2011.en-cs.en + IWSLT16.TED.tst2011.en-de.de + IWSLT16.TED.tst2011.en-de.en + IWSLT16.TED.tst2011.en-fr.en + IWSLT16.TED.tst2011.en-fr.fr + IWSLT16.TED.tst2011.fr-en.en + IWSLT16.TED.tst2011.fr-en.fr + IWSLT16.TED.tst2012.ar-en.ar + IWSLT16.TED.tst2012.ar-en.en + IWSLT16.TED.tst2012.cs-en.cs + IWSLT16.TED.tst2012.cs-en.en + IWSLT16.TED.tst2012.de-en.de + IWSLT16.TED.tst2012.de-en.en + IWSLT16.TED.tst2012.en-ar.ar + IWSLT16.TED.tst2012.en-ar.en + IWSLT16.TED.tst2012.en-cs.cs + IWSLT16.TED.tst2012.en-cs.en + IWSLT16.TED.tst2012.en-de.de + IWSLT16.TED.tst2012.en-de.en + IWSLT16.TED.tst2012.en-fr.en + IWSLT16.TED.tst2012.en-fr.fr + IWSLT16.TED.tst2012.fr-en.en + IWSLT16.TED.tst2012.fr-en.fr + IWSLT16.TED.tst2013.ar-en.ar + IWSLT16.TED.tst2013.ar-en.en + IWSLT16.TED.tst2013.cs-en.cs + IWSLT16.TED.tst2013.cs-en.en + IWSLT16.TED.tst2013.de-en.de + IWSLT16.TED.tst2013.de-en.en + IWSLT16.TED.tst2013.en-ar.ar + IWSLT16.TED.tst2013.en-ar.en + IWSLT16.TED.tst2013.en-cs.cs + IWSLT16.TED.tst2013.en-cs.en + IWSLT16.TED.tst2013.en-de.de + IWSLT16.TED.tst2013.en-de.en + IWSLT16.TED.tst2013.en-fr.en + IWSLT16.TED.tst2013.en-fr.fr + IWSLT16.TED.tst2013.fr-en.en + IWSLT16.TED.tst2013.fr-en.fr + IWSLT16.TED.tst2014.ar-en.ar + IWSLT16.TED.tst2014.ar-en.en + IWSLT16.TED.tst2014.de-en.de + IWSLT16.TED.tst2014.de-en.en + IWSLT16.TED.tst2014.en-ar.ar + IWSLT16.TED.tst2014.en-ar.en + IWSLT16.TED.tst2014.en-de.de + IWSLT16.TED.tst2014.en-de.en + IWSLT16.TED.tst2014.en-fr.en + IWSLT16.TED.tst2014.en-fr.fr + IWSLT16.TED.tst2014.fr-en.en + IWSLT16.TED.tst2014.fr-en.fr + IWSLT16.TEDX.dev2012.de-en.de + IWSLT16.TEDX.dev2012.de-en.en + IWSLT16.TEDX.tst2013.de-en.de + IWSLT16.TEDX.tst2013.de-en.en + IWSLT16.TEDX.tst2014.de-en.de + IWSLT16.TEDX.tst2014.de-en.en + train.ar + train.ar-en.ar + train.ar-en.en + train.cs + train.cs-en.cs + train.cs-en.en + train.de + train.de-en.de + train.de-en.en + train.en + train.en-ar.ar + train.en-ar.en + train.en-cs.cs + train.en-cs.en + train.en-de.de + train.en-de.en + train.en-fr.en + train.en-fr.fr + train.fr + train.fr-en.en + train.fr-en.fr + train.tags.ar-en.ar + train.tags.ar-en.en + train.tags.cs-en.cs + train.tags.cs-en.en + train.tags.de-en.de + train.tags.de-en.en + train.tags.en-ar.ar + train.tags.en-ar.en + train.tags.en-cs.cs + train.tags.en-cs.en + train.tags.en-de.de + train.tags.en-de.en + train.tags.en-fr.en + train.tags.en-fr.fr + train.tags.fr-en.en + train.tags.fr-en.fr + + Examples: + >>> from torchtext.datasets import IWSLT + >>> from torchtext.data.utils import get_tokenizer + >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> tgt_tokenizer = get_tokenizer("basic_english") + >>> train_dataset, valid_dataset, test_dataset = IWSLT(tokenizer=(src_tokenizer, + tgt_tokenizer)) + >>> src_vocab, tgt_vocab = train_dataset.get_vocab() + >>> src_data, tgt_data = train_dataset[10] + """ + + return _setup_datasets("IWSLT", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + tokenizer=tokenizer, + root=root, + vocab=vocab, + removed_tokens=removed_tokens) + + +def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', + 'train.tok.clean.bpe.32000.en'), + valid_filenames=('newstest2013.tok.bpe.32000.de', + 'newstest2013.tok.bpe.32000.en'), + test_filenames=('newstest2014.tok.bpe.32000.de', + 'newstest2014.tok.bpe.32000.en'), + tokenizer=None, + root='.data', + vocab=(None, None), + data_select=('train', 'valid', 'test'), + removed_tokens=['']): + """ Define translation datasets: WMT14 + Separately returns train/valid/test datasets + The available datasets include: + newstest2016.en + newstest2016.de + newstest2015.en + newstest2015.de + newstest2014.en + newstest2014.de + newstest2013.en + newstest2013.de + newstest2012.en + newstest2012.de + newstest2011.tok.de + newstest2011.en + newstest2011.de + newstest2010.tok.de + newstest2010.en + newstest2010.de + newstest2009.tok.de + newstest2009.en + newstest2009.de + newstest2016.tok.de + newstest2015.tok.de + newstest2014.tok.de + newstest2013.tok.de + newstest2012.tok.de + newstest2010.tok.en + newstest2009.tok.en + newstest2015.tok.en + newstest2014.tok.en + newstest2013.tok.en + newstest2012.tok.en + newstest2011.tok.en + newstest2016.tok.en + newstest2009.tok.bpe.32000.en + newstest2011.tok.bpe.32000.en + newstest2010.tok.bpe.32000.en + newstest2013.tok.bpe.32000.en + newstest2012.tok.bpe.32000.en + newstest2015.tok.bpe.32000.en + newstest2014.tok.bpe.32000.en + newstest2016.tok.bpe.32000.en + train.tok.clean.bpe.32000.en + newstest2009.tok.bpe.32000.de + newstest2010.tok.bpe.32000.de + newstest2011.tok.bpe.32000.de + newstest2013.tok.bpe.32000.de + newstest2012.tok.bpe.32000.de + newstest2014.tok.bpe.32000.de + newstest2016.tok.bpe.32000.de + newstest2015.tok.bpe.32000.de + train.tok.clean.bpe.32000.de + + Arguments: + train_filenames: the source and target filenames for training. + Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') + valid_filenames: the source and target filenames for valid. + Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') + test_filenames: the source and target filenames for test. + Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + root: Directory where the datasets are saved. Default: ".data" + vocab: Source and target Vocabulary objects used for dataset. If None, it + will generate a new vocabulary based on the train data set. It has to be + in a form of tuple. + Default: (None, None) + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + removed_tokens: removed tokens from output dataset (Default: '') + + Examples: + >>> from torchtext.datasets import WMT14 + >>> from torchtext.data.utils import get_tokenizer + >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> tgt_tokenizer = get_tokenizer("basic_english") + >>> train_dataset, valid_dataset, test_dataset = WMT14(tokenizer=(src_tokenizer, + tgt_tokenizer)) + >>> src_vocab, tgt_vocab = train_dataset.get_vocab() + >>> src_data, tgt_data = train_dataset[10] + """ + + return _setup_datasets("WMT14", + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + tokenizer=tokenizer, + root=root, + vocab=vocab, + removed_tokens=removed_tokens) + + +DATASETS = {'Multi30k': raw.Multi30k, 'IWSLT': raw.IWSLT, 'WMT14': raw.WMT14} diff --git a/torchtext/experimental/functional.py b/torchtext/experimental/functional.py index 2c9ac60541..26f277fd3a 100644 --- a/torchtext/experimental/functional.py +++ b/torchtext/experimental/functional.py @@ -1,34 +1,32 @@ import torch +from torchtext.data.utils import ngrams_iterator def vocab_func(vocab): - def _forward(tok_iter): + def func(tok_iter): return [vocab[tok] for tok in tok_iter] - return _forward + return func def totensor(dtype): - def _forward(ids_list): + def func(ids_list): return torch.tensor(ids_list).to(dtype) - return _forward + return func def ngrams_func(ngrams): - def _forward(token_list): - _token_list = [] - for _i in range(ngrams + 1): - _token_list += zip(*[token_list[i:] for i in range(_i)]) - return [" ".join(x) for x in _token_list] + def func(token_list): + return list(ngrams_iterator(token_list, ngrams)) - return _forward + return func def sequential_transforms(*transforms): - def _forward(txt_input): + def func(txt_input): for transform in transforms: txt_input = transform(txt_input) return txt_input - return _forward + return func diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py new file mode 100644 index 0000000000..f7f53670be --- /dev/null +++ b/torchtext/experimental/transforms.py @@ -0,0 +1,114 @@ +import torch +import torch.nn as nn +from typing import List, Tuple + + +__all__ = [ + 'BasicEnglishNormalize', + 'RegexTokenizer' +] + + +class BasicEnglishNormalize(nn.Module): + r"""Basic normalization for a string sentence. + + Normalization includes + - lowercasing + - complete some basic text normalization for English words as follows: + - add spaces before and after '\'' + - remove '\"', + - add spaces before and after '.' + - replace '
'with single space + - add spaces before and after ',' + - add spaces before and after '(' + - add spaces before and after ')' + - add spaces before and after '!' + - add spaces before and after '?' + - replace ';' with single space + - replace ':' with single space + - replace multiple spaces with single space + + Examples: + >>> import torch + >>> from torchtext.experimental.transforms import BasicEnglishNormalize + >>> test_sample = 'Basic English Normalization for a Line of Text' + >>> basic_english_normalize = BasicEnglishNormalize() + >>> jit_basic_english_normalize = torch.jit.script(basic_english_normalize) + >>> tokens = jit_basic_english_normalize(test_sample) + """ + + regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] + + def __init__(self): + super(BasicEnglishNormalize, self).__init__() + patterns_list = [ + (r'\'', ' \' '), + (r'\"', ''), + (r'\.', ' . '), + (r'
', ' '), + (r',', ' , '), + (r'\(', ' ( '), + (r'\)', ' ) '), + (r'\!', ' ! '), + (r'\?', ' ? '), + (r'\;', ' '), + (r'\:', ' '), + (r'\s+', ' ')] + + regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) + replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) + self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) + + def forward(self, line: str) -> List[str]: + r""" + Args: + line (str): a line of text to tokenize. + Returns: + List[str]: a list of tokens after normalizing and splitting on whitespace. + """ + + line = line.lower() + for regex, replacement_string in self.regex_and_replacement_string_pairs: + line = regex.Sub(line, replacement_string) + return line.split() + + +class RegexTokenizer(nn.Module): + r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. + + Args: + patterns_list (List[Tuple[str, str]]): a list of tuples (ordered pairs) which contain the regex pattern string + as the first element and the replacement string as the second element. + + Examples: + >>> import torch + >>> from torchtext.experimental.transforms import RegexTokenizer + >>> test_sample = 'Basic Regex Tokenization for a Line of Text' + >>> patterns_list = [ + (r'\'', ' \' '), + (r'\"', '')] + >>> regex_tokenizer = RegexTokenizer(patterns_list) + >>> jit_regex_tokenizer = torch.jit.script(regex_tokenizer) + >>> tokens = jit_regex_tokenizer(test_sample) + """ + + regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] + + def __init__(self, patterns_list: List[Tuple[str, str]]): + super(RegexTokenizer, self).__init__() + + regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) + replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) + self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) + + def forward(self, line: str) -> List[str]: + r""" + Args: + line (str): a line of text to tokenize. + Returns: + List[str]: a list of tokens after normalizing and splitting on whitespace. + """ + + for regex, replacement_string in self.regex_and_replacement_string_pairs: + line = regex.Sub(line, replacement_string) + return line.split() diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py new file mode 100644 index 0000000000..a0f2dfeeec --- /dev/null +++ b/torchtext/experimental/vectors.py @@ -0,0 +1,87 @@ +import csv +import torch +from torch import Tensor +import torch.nn as nn + + +def vectors_from_file_object(file_like_object, unk_tensor=None): + r"""Create a Vectors object from a csv file like object. + + Note that the tensor corresponding to each vector is of type `torch.float`. + + Format for csv file: + token1,num1 num2 num3 + token2,num4 num5 num6 + ... + token_n,num_m num_j num_k + + Args: + file_like_object (FileObject): a file like object to read data from. + unk_tensor (int): a 1d tensors representing the vector associated with an unknown token + + Returns: + Vectors: a Vectors object. + + """ + readCSV = csv.reader(file_like_object, delimiter=',') + + tokens = [] + vectors = [] + for row in readCSV: + tokens.append(row[0]) + vectors.append(torch.tensor([float(c) for c in row[1].split()], dtype=torch.float)) + + return Vectors(tokens, vectors, unk_tensor=unk_tensor) + + +class Vectors(nn.Module): + r"""Creates a vectors object which maps tokens to vectors. + + Arguments: + tokens (List[str]): a list of tokens. + vectors (List[torch.Tensor]): a list of 1d tensors representing the vector associated with each token. + unk_tensor (torch.Tensor): a 1d tensors representing the vector associated with an unknown token. + + Raises: + ValueError: if `vectors` is empty and a default `unk_tensor` isn't provided. + RuntimeError: if `tokens` and `vectors` have different sizes or `tokens` has duplicates. + TypeError: if all tensors within`vectors` are not of data type `torch.float`. + """ + + def __init__(self, tokens, vectors, unk_tensor=None): + super(Vectors, self).__init__() + + if unk_tensor is None and not vectors: + raise ValueError("The vectors list is empty and a default unk_tensor wasn't provided.") + + if not all(vector.dtype == torch.float for vector in vectors): + raise TypeError("All tensors within `vectors` should be of data type `torch.float`.") + + unk_tensor = unk_tensor if unk_tensor is not None else torch.zeros(vectors[0].size(), dtype=torch.float) + + self.vectors = torch.classes.torchtext.Vectors(tokens, vectors, unk_tensor) + + @torch.jit.export + def __getitem__(self, token: str) -> Tensor: + r""" + Args: + token (str): the token used to lookup the corresponding vector. + Returns: + vector (Tensor): a tensor (the vector) corresponding to the associated token. + """ + return self.vectors.GetItem(token) + + @torch.jit.export + def __setitem__(self, token: str, vector: Tensor): + r""" + Args: + token (str): the token used to lookup the corresponding vector. + vector (Tensor): a 1d tensor representing a vector associated with the token. + + Raises: + TypeError: if `vector` is not of data type `torch.float`. + """ + if vector.dtype != torch.float: + raise TypeError("`vector` should be of data type `torch.float` but it's of type " + vector.dtype) + + self.vectors.AddItem(token, vector.float()) diff --git a/torchtext/modules/__init__.py b/torchtext/modules/__init__.py new file mode 100644 index 0000000000..a55ced48fb --- /dev/null +++ b/torchtext/modules/__init__.py @@ -0,0 +1,6 @@ +from .multiheadattention import InProjContainer, \ + MultiheadAttentionContainer, ScaledDotProduct + +__all__ = ['InProjContainer', + 'MultiheadAttentionContainer', + 'ScaledDotProduct'] diff --git a/torchtext/modules/multiheadattention.py b/torchtext/modules/multiheadattention.py new file mode 100644 index 0000000000..f6d8e7675d --- /dev/null +++ b/torchtext/modules/multiheadattention.py @@ -0,0 +1,213 @@ +import torch +from typing import Tuple, Optional + + +class MultiheadAttentionContainer(torch.nn.Module): + def __init__(self, nhead, in_proj_container, attention_layer, out_proj): + r""" A multi-head attention container + + Args: + nhead: the number of heads in the multiheadattention model + in_proj_container: A container of multi-head in-projection linear layers (a.k.a nn.Linear). + attention_layer: The attention layer. + out_proj: The multi-head out-projection layer (a.k.a nn.Linear). + + Examples:: + >>> import torch + >>> embed_dim, num_heads, bsz = 10, 5, 64 + >>> in_proj_container = InProjContainer(torch.nn.Linear(embed_dim, embed_dim), + torch.nn.Linear(embed_dim, embed_dim), + torch.nn.Linear(embed_dim, embed_dim)) + >>> MHA = MultiheadAttentionContainer(num_heads, + in_proj_container, + ScaledDotProduct(), + torch.nn.Linear(embed_dim, embed_dim)) + >>> query = torch.rand((21, bsz, embed_dim)) + >>> key = value = torch.rand((16, bsz, embed_dim)) + >>> attn_output, attn_weights = MHA(query, key, value) + >>> print(attn_output.shape) + >>> torch.Size([21, 64, 10]) + """ + super(MultiheadAttentionContainer, self).__init__() + self.nhead = nhead + self.in_proj_container = in_proj_container + self.attention_layer = attention_layer + self.out_proj = out_proj + + def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, + attn_mask: Optional[torch.Tensor] = None, + bias_k: Optional[torch.Tensor] = None, + bias_v: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor, torch.Tensor]: + r""" + + Args: + query, key, value (Tensor): map a query and a set of key-value pairs to an output. + See "Attention Is All You Need" for more details. + attn_mask, bias_k and bias_v (Tensor, optional): keyword arguments passed to the attention layer. + See the definitions in the attention. + + Shape: + - Inputs: + - query: :math:`(L, N, E)` + - key: :math:`(S, N, E)` + - value: :math:`(S, N, E)` + - attn_mask, bias_k and bias_v: same with the shape of the corresponding args in attention layer. + + - Outputs: + - attn_output: :math:`(L, N, E)` + - attn_output_weights: :math:`(N * H, L, S)` + + where where L is the target length, S is the sequence length, H is the number of attention heads, + N is the batch size, and E is the embedding dimension. + """ + tgt_len, src_len, bsz, embed_dim = query.size(-3), key.size(-3), query.size(-2), query.size(-1) + q, k, v = self.in_proj_container(query, key, value) + assert q.size(-1) % self.nhead == 0, "query's embed_dim must be divisible by the number of heads" + head_dim = q.size(-1) // self.nhead + q = q.reshape(tgt_len, bsz * self.nhead, head_dim) + + assert k.size(-1) % self.nhead == 0, "key's embed_dim must be divisible by the number of heads" + head_dim = k.size(-1) // self.nhead + k = k.reshape(src_len, bsz * self.nhead, head_dim) + + assert v.size(-1) % self.nhead == 0, "value's embed_dim must be divisible by the number of heads" + head_dim = v.size(-1) // self.nhead + v = v.reshape(src_len, bsz * self.nhead, head_dim) + + attn_output, attn_output_weights = self.attention_layer(q, k, v, attn_mask=attn_mask, + bias_k=bias_k, bias_v=bias_v) + attn_output = attn_output.reshape(tgt_len, bsz, embed_dim) + attn_output = self.out_proj(attn_output) + return attn_output, attn_output_weights + + +class ScaledDotProduct(torch.nn.Module): + + def __init__(self, dropout=0.0): + r"""Processes a projected query and key-value pair to apply + scaled dot product attention. + + Args: + dropout (float): probability of dropping an attention weight. + + Examples:: + >>> SDP = torchtext.models.ScaledDotProduct(0.1) + >>> q = torch.randn(256, 21, 3) + >>> k = v = torch.randn(256, 21, 3) + >>> attn_output, attn_weights = SDP(q, k, v) + >>> print(attn_output.shape, attn_weights.shape) + torch.Size([256, 21, 3]) torch.Size([256, 21, 21]) + """ + super(ScaledDotProduct, self).__init__() + self.dropout = dropout + + def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, + attn_mask: Optional[torch.Tensor] = None, + bias_k: Optional[torch.Tensor] = None, + bias_v: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor, torch.Tensor]: + r"""Uses a scaled dot product with the projected key-value pair to update + the projected query. + + Args: + query (Tensor): Projected query + key (Tensor): Projected key + value (Tensor): Projected value + attn_mask (BoolTensor, optional): 3D mask that prevents attention to certain positions. + bias_k and bias_v: (Tensor, optional): one more key and value sequence to be added at + sequence dim (dim=-3). Those are used for incremental decoding. Users should provide + non-None to both arguments in order to activate them. + + Shape: + - query: :math:`(L, N * H, E / H)` + - key: :math:`(S, N * H, E / H)` + - value: :math:`(S, N * H, E / H)` + - attn_mask: :math:`(N * H, L, S)`, positions with ``True`` are not allowed to attend + while ``False`` values will be unchanged. + - bias_k and bias_v:bias: :math:`(1, N * H, E / H)` + + - Output: :math:`(L, N * H, E / H)`, :math:`(N * H, L, S)` + + where L is the target length, S is the source length, H is the number + of attention heads, N is the batch size, and E is the embedding dimension. + """ + if bias_k is not None and bias_v is not None: + assert key.size(-1) == bias_k.size(-1) and key.size(-2) == bias_k.size(-2) and bias_k.size(-3) == 1, \ + "Shape of bias_k is not supported" + assert value.size(-1) == bias_v.size(-1) and value.size(-2) == bias_v.size(-2) and bias_v.size(-3) == 1, \ + "Shape of bias_v is not supported" + key = torch.cat([key, bias_k]) + value = torch.cat([value, bias_v]) + if attn_mask is not None: + _attn_mask = attn_mask + attn_mask = torch.nn.functional.pad(_attn_mask, (0, 1)) + + tgt_len, head_dim = query.size(-3), query.size(-1) + assert query.size(-1) == key.size(-1) == value.size(-1), "The feature dim of query, key, value must be equal." + assert key.size() == value.size(), "Shape of key, value must match" + src_len = key.size(-3) + batch_heads = max(query.size(-2), key.size(-2)) + + # Scale query + query, key, value = query.transpose(-2, -3), key.transpose(-2, -3), value.transpose(-2, -3) + query = query * (float(head_dim) ** -0.5) + if attn_mask is not None: + if attn_mask.dim() != 3: + raise RuntimeError('attn_mask must be a 3D tensor.') + if (attn_mask.size(-1) != src_len) or (attn_mask.size(-2) != tgt_len) or \ + (attn_mask.size(-3) != 1 and attn_mask.size(-3) != batch_heads): + raise RuntimeError('The size of the attn_mask is not correct.') + if attn_mask.dtype != torch.bool: + raise RuntimeError('Only bool tensor is supported for attn_mask') + + # Dot product of q, k + attn_output_weights = torch.matmul(query, key.transpose(-2, -1)) + if attn_mask is not None: + attn_output_weights.masked_fill_(attn_mask, -1e8,) + attn_output_weights = torch.nn.functional.softmax(attn_output_weights, dim=-1) + attn_output_weights = torch.nn.functional.dropout(attn_output_weights, p=self.dropout, training=self.training) + attn_output = torch.matmul(attn_output_weights, value) + return attn_output.transpose(-2, -3), attn_output_weights + + +class InProjContainer(torch.nn.Module): + def __init__(self, query_proj, key_proj, value_proj): + r"""A in-proj container to process inputs. + + Args: + query_proj: a proj layer for query. + key_proj: a proj layer for key. + value_proj: a proj layer for value. + """ + + super(InProjContainer, self).__init__() + self.query_proj = query_proj + self.key_proj = key_proj + self.value_proj = value_proj + + def forward(self, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + r"""Projects the input sequences using in-proj layers. + + Args: + query, key, value (Tensors): sequence to be projected + + Shape: + - query, key, value: :math:`(S, N, E)` + - Output: :math:`(S, N, E)` + where S is the sequence length, N is the batch size, and E is the embedding dimension. + """ + return self.query_proj(query), self.key_proj(key), self.value_proj(value) + + +def generate_square_subsequent_mask(nbatch, sz): + r"""Generate a square mask for the sequence. The masked positions are filled with True. + Unmasked positions are filled with False. + + Args: + nbatch: the number of batch size + sz: the size of square mask + """ + mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1).repeat(nbatch, 1, 1) + return mask diff --git a/torchtext/utils.py b/torchtext/utils.py index 41ac14ecbb..b892396a15 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -7,6 +7,7 @@ import re import sys import zipfile +import gzip def reporthook(t): @@ -197,6 +198,21 @@ def extract_archive(from_path, to_path=None, overwrite=False): files = [f for f in files if os.path.isfile(f)] return files + elif from_path.endswith('.gz'): + default_block_size = 65536 + filename = from_path[:-3] + files = [filename] + with gzip.open(from_path, 'rb') as gzfile, \ + open(filename, 'wb') as d_file: + while True: + block = gzfile.read(default_block_size) + if not block: + break + else: + d_file.write(block) + d_file.write(block) + return files + else: raise NotImplementedError( - "We currently only support tar.gz, .tgz and zip achives.") + "We currently only support tar.gz, .tgz, .gz and zip achives.") From 3088591da6e371e0c73cc51a34766fa69dff20b2 Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Tue, 30 Jun 2020 17:08:37 -0700 Subject: [PATCH 14/68] Fix torch.testing._internal module not found Reviewed By: Nayef211 Differential Revision: D22315715 fbshipit-source-id: 6b8b8544b0aa458cf5e7e9ca380d0dc85c98189f --- test/common/torchtext_test_case.py | 1 + tox.ini | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 tox.ini diff --git a/test/common/torchtext_test_case.py b/test/common/torchtext_test_case.py index 21ccc4d785..7bcfc881e7 100644 --- a/test/common/torchtext_test_case.py +++ b/test/common/torchtext_test_case.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import torch from torch.testing._internal.common_utils import TestCase import json import logging diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000000..283f8176f7 --- /dev/null +++ b/tox.ini @@ -0,0 +1,4 @@ +[flake8] +ignore = E401,E402,E722,W503,W504,F821,B006,B007,B008 +max-line-length = 120 +exclude = docs/source From 8233815c960c2fda84df137fcee940fb6dd0af0c Mon Sep 17 00:00:00 2001 From: Nayef Ahmed Date: Tue, 7 Jul 2020 18:23:52 -0700 Subject: [PATCH 15/68] Import torchtext 2020/07/07 Summary: Import from github torchtext/master Reviewed By: cpuhrsch Differential Revision: D22420576 fbshipit-source-id: 4d2c19d7f1db8f698894ca406c1c44b2ad8e0506 --- benchmark/experimental_vectors.py | 47 ++ benchmark/experimental_vocab.py | 55 ++ docs/source/experimental_datasets.rst | 47 +- docs/source/experimental_vectors.rst | 10 + packaging/build_conda.sh | 2 +- packaging/build_wheel.sh | 2 +- setup.py | 2 +- test/asset/wiki.en.vec | 100 +++ test/common/torchtext_test_case.py | 1 - test/data/test_builtin_datasets.py | 102 +++ test/experimental/test_vectors.py | 132 +++- test/experimental/test_vocab.py | 209 ++++++ torchtext/csrc/vectors.cpp | 68 +- torchtext/csrc/vocab.cpp | 142 ++++ torchtext/experimental/asset/get_checksum.sh | 5 + .../asset/get_checksums_fast_text.py | 58 ++ torchtext/experimental/datasets/__init__.py | 3 + .../experimental/datasets/raw/__init__.py | 3 + .../datasets/raw/sequence_tagging.py | 136 ++++ .../experimental/datasets/sequence_tagging.py | 169 +++++ .../experimental/datasets/translation.py | 2 +- torchtext/experimental/vectors.py | 623 +++++++++++++++++- torchtext/experimental/vocab.py | 155 +++++ torchtext/utils.py | 61 +- tox.ini | 4 - 25 files changed, 2044 insertions(+), 94 deletions(-) create mode 100644 benchmark/experimental_vectors.py create mode 100644 benchmark/experimental_vocab.py create mode 100644 test/asset/wiki.en.vec create mode 100644 test/experimental/test_vocab.py create mode 100644 torchtext/csrc/vocab.cpp create mode 100755 torchtext/experimental/asset/get_checksum.sh create mode 100644 torchtext/experimental/asset/get_checksums_fast_text.py create mode 100644 torchtext/experimental/datasets/raw/sequence_tagging.py create mode 100644 torchtext/experimental/datasets/sequence_tagging.py create mode 100644 torchtext/experimental/vocab.py delete mode 100644 tox.ini diff --git a/benchmark/experimental_vectors.py b/benchmark/experimental_vectors.py new file mode 100644 index 0000000000..172b451db8 --- /dev/null +++ b/benchmark/experimental_vectors.py @@ -0,0 +1,47 @@ +import time + +import torch +from torchtext.experimental.datasets import AG_NEWS +from torchtext.experimental.vectors import FastText as FastTextExperimental +from torchtext.vocab import FastText + + +def benchmark_experimental_vectors(): + def _run_benchmark_lookup(tokens, vector): + t0 = time.monotonic() + for token in tokens: + vector[token] + print("Lookup time:", time.monotonic() - t0) + + train, = AG_NEWS(data_select='train') + vocab = train.get_vocab() + tokens = [] + for (_label, text) in train: + for id in text.tolist(): + tokens.append(vocab.itos[id]) + + # existing FastText construction + print("Existing FastText - Not Jit Mode") + t0 = time.monotonic() + fast_text = FastText() + print("Construction time:", time.monotonic() - t0) + _run_benchmark_lookup(tokens, fast_text) + + # experimental FastText construction + print("FastText Experimental") + t0 = time.monotonic() + fast_text_experimental = FastTextExperimental(validate_file=False) + print("Construction time:", time.monotonic() - t0) + + # not jit lookup + print("FastText Experimental - Not Jit Mode") + _run_benchmark_lookup(tokens, fast_text_experimental) + + # jit lookup + print("FastText Experimental - Jit Mode") + jit_fast_text_experimental = torch.jit.script(fast_text_experimental) + _run_benchmark_lookup(tokens, jit_fast_text_experimental) + + +if __name__ == "__main__": + benchmark_experimental_vectors() diff --git a/benchmark/experimental_vocab.py b/benchmark/experimental_vocab.py new file mode 100644 index 0000000000..622be541ad --- /dev/null +++ b/benchmark/experimental_vocab.py @@ -0,0 +1,55 @@ +from collections import (Counter, OrderedDict) +import time + +import torch +from torchtext.experimental.datasets import AG_NEWS +from torchtext.experimental.vocab import Vocab as VocabExperimental +from torchtext.vocab import Vocab + + +def benchmark_experimental_vocab(): + def _run_benchmark_lookup(tokens, vocab): + t0 = time.monotonic() + for token in tokens: + vocab[token] + print("Lookup time:", time.monotonic() - t0) + + train, = AG_NEWS(data_select='train') + vocab = train.get_vocab() + tokens = [] + for (_label, text) in train: + for id in text.tolist(): + tokens.append(vocab.itos[id]) + + counter = Counter(tokens) + sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) + ordered_dict = OrderedDict(sorted_by_freq_tuples) + + # existing Vocab construction + print("Vocab") + t0 = time.monotonic() + v_existing = Vocab(counter) + print("Construction time:", time.monotonic() - t0) + + # experimental Vocab construction + print("Vocab Experimental") + t0 = time.monotonic() + v_experimental = VocabExperimental(ordered_dict) + print("Construction time:", time.monotonic() - t0) + jit_v_experimental = torch.jit.script(v_experimental) + + # existing Vocab not jit lookup + print("Vocab - Not Jit Mode") + _run_benchmark_lookup(tokens, v_existing) + + # experimental Vocab not jit lookup + print("Vocab Experimental - Not Jit Mode") + _run_benchmark_lookup(tokens, v_experimental) + + # experimental Vocab jit lookup + print("Vocab Experimental - Jit Mode") + _run_benchmark_lookup(tokens, jit_v_experimental) + + +if __name__ == "__main__": + benchmark_experimental_vocab() diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index 044b731496..20cde70f2e 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -34,9 +34,9 @@ IMDb ~~~~ .. autoclass:: IMDB - :members: __init__ - - + :members: __init__ + + Text Classification ^^^^^^^^^^^^^^^^^^^ @@ -109,8 +109,8 @@ AmazonReviewFull dataset is subclass of ``TextClassificationDataset`` class. .. autoclass:: AmazonReviewFull :members: __init__ - - + + Language Modeling ^^^^^^^^^^^^^^^^^ @@ -124,28 +124,28 @@ WikiText-2 ~~~~~~~~~~ .. autoclass:: WikiText2 - :members: __init__ + :members: __init__ WikiText103 ~~~~~~~~~~~ .. autoclass:: WikiText103 - :members: __init__ + :members: __init__ PennTreebank ~~~~~~~~~~~~ .. autoclass:: PennTreebank - :members: __init__ + :members: __init__ WMTNewsCrawl ~~~~~~~~~~~~ -.. autoclass:: WMTNewsCrawl - :members: __init__ +.. autoclass:: WMTNewsCrawl + :members: __init__ Machine Translation @@ -177,12 +177,33 @@ WMT14 .. autoclass:: WMT14 :members: __init__ + +Sequence Tagging +^^^^^^^^^^^^^^^^ + +Language modeling datasets are subclasses of ``SequenceTaggingDataset`` class. + +.. autoclass:: SequenceTaggingDataset + :members: __init__ + +UDPOS +~~~~~ + +.. autoclass:: UDPOS + :members: __init__ + +CoNLL2000Chunking +~~~~~ + +.. autoclass:: CoNLL2000Chunking + :members: __init__ + Question Answer ^^^^^^^^^^^^^^^ Question answer datasets are subclasses of ``QuestionAnswerDataset`` class. -.. autoclass:: QuestionAnswerDataset +.. autoclass:: QuestionAnswerDataset :members: __init__ @@ -190,11 +211,11 @@ SQuAD 1.0 ~~~~~~~~~ .. autoclass:: SQuAD1 - :members: __init__ + :members: __init__ SQuAD 2.0 ~~~~~~~~~ .. autoclass:: SQuAD2 - :members: __init__ + :members: __init__ diff --git a/docs/source/experimental_vectors.rst b/docs/source/experimental_vectors.rst index 8d9fe02ce0..b901abac80 100644 --- a/docs/source/experimental_vectors.rst +++ b/docs/source/experimental_vectors.rst @@ -18,3 +18,13 @@ torchtext.experimental.vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autofunction:: vectors_from_file_object + +:hidden:`FastText` +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: FastText + +:hidden:`GloVe` +~~~~~~~~~~~~~~~~ + +.. autofunction:: GloVe diff --git a/packaging/build_conda.sh b/packaging/build_conda.sh index 50c94d6204..f7df266a15 100755 --- a/packaging/build_conda.sh +++ b/packaging/build_conda.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="conda" export NO_CUDA_PACKAGE=1 -setup_env 0.6.0 +setup_env 0.8.0 export SOURCE_ROOT_DIR="$PWD" setup_conda_pytorch_constraint setup_visual_studio_constraint diff --git a/packaging/build_wheel.sh b/packaging/build_wheel.sh index 064622c801..fb9c190789 100755 --- a/packaging/build_wheel.sh +++ b/packaging/build_wheel.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="wheel" export NO_CUDA_PACKAGE=1 -setup_env 0.6.0 +setup_env 0.8.0 setup_wheel_python pip_install numpy future setup_pip_pytorch_version diff --git a/setup.py b/setup.py index e93583c5b5..7efa31dbc4 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ def read(*names, **kwargs): def _get_version(): - version = '0.6.0a0' + version = '0.8.0a0' sha = None try: diff --git a/test/asset/wiki.en.vec b/test/asset/wiki.en.vec new file mode 100644 index 0000000000..71ffef1c4d --- /dev/null +++ b/test/asset/wiki.en.vec @@ -0,0 +1,100 @@ +2519370 300 +, -0.023167 -0.0042483 -0.10572 0.042783 -0.14316 -0.078954 0.078187 -0.19454 0.022303 0.31207 0.057462 -0.11589 0.096633 -0.093229 -0.034229 -0.14652 -0.11094 -0.11102 0.067728 0.10023 -0.067413 0.23761 -0.13105 -0.0083979 -0.10593 0.24526 0.065903 -0.2374 -0.10758 0.0057082 -0.081413 0.26264 -0.052461 0.20306 0.05062 -0.18866 -0.11494 -0.25752 0.046799 -0.050525 0.06265 0.15433 -0.056289 -0.048437 -0.099688 -0.035332 -0.091647 -0.081151 -0.0010844 -0.08414 -0.13026 0.01498 -0.086276 -0.053041 -0.10644 -0.042314 0.086469 0.22614 -0.16078 0.18845 0.053098 -0.21475 0.16699 -0.14442 -0.1593 0.0062456 -0.07663 -0.091568 -0.28984 0.027078 0.021275 0.023939 0.14903 -0.33062 -0.097811 -0.033814 0.070587 0.023294 0.065382 0.18716 -0.13444 0.14431 -0.0268 -0.022903 0.097554 -0.032909 -0.027827 -0.068771 0.17053 -0.05946 0.020424 -0.077589 0.1216 -0.077437 0.10665 0.051087 0.0076379 -0.064936 0.09031 0.059447 0.0048881 0.078309 -0.012163 0.062155 -0.072664 0.17857 -0.22874 0.066397 -0.039295 -0.027717 0.061571 0.072824 -0.092512 -0.087984 -0.12753 -0.0018705 0.18689 0.0051173 -0.0013532 0.043246 0.10867 -0.12209 -0.0091676 0.23938 -0.059501 -0.0010456 0.086584 0.020238 0.21686 0.16495 0.037256 0.12343 0.17706 0.075777 0.031022 -0.12948 0.030936 0.096897 -0.10793 0.12644 -0.056489 0.082232 0.20679 0.11679 0.13965 0.26362 0.037603 -0.003105 -0.089501 -0.0076969 -0.11654 -0.28567 0.046616 -0.0082062 0.15621 -0.14641 0.064561 -0.1133 0.27129 0.14532 -0.021773 0.23305 -0.1617 0.15705 0.13845 0.022417 -0.10982 -0.049431 0.076855 -0.0453 -0.19029 0.011183 -0.010393 0.0016916 0.089407 -0.051022 -0.086066 0.083933 -0.0081962 -0.0077321 0.033991 -0.20092 0.03328 0.062224 0.016121 0.27143 -0.19754 -0.15222 -0.015345 -0.063907 -0.098597 -0.20162 0.14004 -1.1533e-05 -0.18928 0.12253 -0.0070378 0.0864 -0.30255 -0.03908 0.045517 -0.16449 -0.23548 0.052781 0.13847 -0.20022 -0.015974 0.027137 0.18287 -0.02389 0.22072 -0.04271 -0.075939 -0.087386 -0.049337 0.047824 -0.059078 -0.15181 -0.21229 -0.054944 -0.011453 -0.11996 -0.15307 -0.054828 -0.053217 -0.048546 0.028856 -0.094537 0.27144 0.054638 0.059727 0.061772 0.009259 -0.12032 -0.16646 -0.029087 0.0028752 -0.16076 -0.1371 -0.18988 0.022857 0.18455 -0.018236 -0.0060562 0.14302 0.032535 0.14333 -0.030871 -0.15218 0.092813 0.066358 0.018316 -0.24143 0.0054391 -0.064479 -0.08596 0.030446 0.082157 0.026093 0.058985 0.0051085 0.089127 -0.018164 -0.077821 0.0034232 0.13892 0.046106 -0.05417 0.0084399 -0.15362 -0.14735 0.065191 -0.022883 -0.14498 -0.16917 -0.19215 0.10611 0.001678 -0.16331 -0.07307 0.11576 0.083567 -0.060317 -0.064714 0.15305 -0.11949 0.16684 0.14109 0.046036 -0.060393 0.046595 -0.11558 0.044184 -0.023124 0.02586 -0.11653 0.010936 0.089398 -0.0159 0.14866 +. -0.11112 -0.0013859 -0.1778 0.064508 -0.24037 0.031087 -0.030144 -0.36883 -0.043855 0.24831 0.078633 -0.16072 0.10528 -0.09622 -0.077742 -0.28262 -0.13013 0.0056083 0.19406 0.19287 -0.10955 0.23008 -0.19911 0.18836 -0.21861 0.0017505 -0.093017 -0.25064 0.034323 0.17047 -0.094408 0.1442 -0.18533 0.1685 -0.16582 -0.061712 -0.010346 -0.078817 0.20596 -0.12286 -0.064035 -0.040983 -0.21272 0.097636 -0.058569 -0.044869 0.028206 -0.12619 0.012063 -0.19177 -0.044824 -0.081765 -0.073723 0.037251 -0.075625 0.0085609 0.062612 0.22144 -0.10765 0.1617 0.065163 -0.38164 0.40246 -0.40637 -0.15695 -0.026063 0.08266 -0.21487 -0.19077 0.015702 0.0019313 0.028565 -0.11221 -0.32311 -0.11034 -0.0036508 0.098677 0.044877 -0.037888 0.055357 -0.083052 0.1388 -0.014431 0.03675 0.024439 -0.23493 -0.027343 0.079749 0.033782 -0.14431 -0.12995 0.0013884 0.12936 -0.025757 0.14235 -0.039069 0.04441 -0.10727 0.010207 -0.25722 0.0108 0.13833 -0.12007 0.1007 -0.032493 0.039002 -0.22527 -0.0082154 0.089996 0.12834 -0.042059 0.034393 -0.062866 -0.17397 -0.12022 0.10377 0.23975 0.0168 0.013164 0.1788 0.15969 -0.09956 -0.00033453 0.14833 0.0023907 0.012985 0.018713 -0.013954 0.017909 0.18023 -0.061768 0.13785 0.11028 0.06795 -0.093466 0.065266 0.081291 0.074469 -0.14988 0.27212 -0.24042 0.10926 0.18611 0.25639 0.26599 -0.033769 0.035854 0.046225 -0.096937 -0.022181 -0.0093109 -0.17216 -0.0052176 -0.087209 0.16378 -0.1748 0.10675 -0.11914 0.11579 0.28104 0.031467 0.089572 -0.076408 0.091939 0.10972 0.10825 0.044846 -0.10262 0.011195 0.12233 -0.21444 -0.0085801 -0.20019 0.076398 0.069234 -0.00027189 -0.14671 0.0020823 0.10946 -0.026161 -0.03566 -0.20662 -0.017169 0.14491 -0.018133 0.26558 -0.071692 -0.32038 0.090198 0.038957 -0.13264 -0.082944 0.28167 0.095751 -0.21677 0.036769 0.002427 0.073605 -0.34857 -0.023093 -0.082191 -0.10558 0.029198 0.092549 0.26644 -0.1304 -0.14764 0.2099 0.17682 -0.078109 0.15883 -0.12386 -0.036651 -0.035916 -0.080906 -0.052342 -0.043183 -0.15264 -0.12676 0.13355 0.04599 -0.063914 0.12744 -0.1052 -0.12274 0.08151 0.055437 -0.1856 0.10727 0.098527 0.06622 0.22512 -0.19452 -0.058842 0.060798 0.08935 -0.050251 -0.075885 -0.13478 -0.19397 0.00089476 0.24309 -0.042496 0.016901 0.15118 0.037475 0.13201 0.052854 -0.15011 0.025235 0.02491 0.04034 -0.40257 0.03001 0.014418 -0.0089364 0.036583 0.022269 -0.074602 0.10987 0.018079 0.19326 0.038292 0.080146 0.053901 0.13042 0.004338 -0.15412 0.092865 -0.059374 -0.033619 0.044073 0.066178 -0.16668 -0.062453 -0.2339 -0.026025 -0.028359 -0.25575 -0.10586 0.099423 0.15685 -0.12659 -0.22975 0.15002 -0.16253 0.095208 0.30722 0.052365 -0.10963 0.095332 -0.21914 -0.04276 -0.13685 0.09747 -0.21818 -0.058233 0.063374 -0.12161 0.039339 +the -0.065334 -0.093031 -0.017571 0.20007 0.029521 -0.03992 -0.16328 -0.072946 0.089604 0.080907 -0.040032 -0.23624 0.1825 -0.061241 -0.064386 -0.075258 -0.050076 -0.020001 0.003496 0.14487 -0.16791 0.076852 -0.22977 -0.057937 -0.13408 -0.073586 -0.0012575 0.019708 0.056866 0.0625 -0.15555 0.15207 -0.10629 0.2467 -0.027853 -0.17703 0.0072058 -0.11941 0.083843 -0.11843 0.053612 -0.0023144 -0.084279 0.02842 0.078184 -0.12017 -0.040866 0.089438 0.050845 -0.06372 0.070864 -0.063962 -0.095329 0.069848 -0.050254 0.058265 0.085877 0.043966 -0.051179 0.097819 -0.050705 -0.18195 0.32365 -0.076363 0.046492 -0.19886 -0.24429 -0.18651 -0.22465 0.069392 -0.37377 -0.082351 0.061531 -0.13149 -0.075824 -0.060647 0.072747 0.24397 0.021046 -0.071253 0.11115 0.073137 -0.086065 0.11181 -0.0062127 -0.16714 -0.065522 0.083572 -0.092857 -0.12377 -0.082908 0.012025 0.33836 -0.27124 0.054494 -0.088206 0.073294 0.024418 0.0036174 -0.027804 -0.12583 -0.032364 -0.0017323 -0.075066 -0.20324 -0.11735 0.0076592 0.021895 -0.013652 0.064288 -0.0086384 -0.08287 -0.10197 -0.13569 0.085786 -0.0061483 0.15858 0.18609 0.11262 0.090442 0.27457 0.22795 -0.076096 0.21347 0.026208 0.070195 0.12838 0.20542 0.092349 0.12774 -0.17516 0.089942 -0.024982 0.033565 -0.12136 0.059703 -0.060016 0.13908 -0.05639 0.15073 0.095501 0.055378 0.051278 0.037113 0.017116 0.22476 0.046822 0.035514 0.065785 0.094907 0.13325 -0.071157 -0.07789 -0.067566 -0.0713 -0.070124 0.03169 -0.059157 0.14293 0.060211 -0.12124 0.14737 -0.069322 0.084458 0.15567 0.024013 -0.11073 0.075851 0.16277 -0.085473 -0.19668 -0.077685 -0.067194 -0.07725 -0.10461 0.12912 0.0099595 0.24678 -0.0021382 -0.026336 0.045182 0.027762 -0.048843 0.10953 -0.032948 0.24045 0.18437 -0.15205 0.11378 0.04739 -0.0017306 -0.16477 0.19182 0.17582 -0.043354 0.048313 -0.054663 0.026949 -0.17522 0.1202 -0.014748 -0.046279 -0.044321 0.1132 -0.013909 -0.16025 -0.023832 0.011909 0.044407 0.10252 0.2366 0.1022 -0.0089182 -0.053413 0.066031 -0.10562 0.099354 -0.2636 -0.13579 0.029793 -0.0049288 -0.032903 -0.04859 0.14609 -0.033257 0.074076 -0.18396 0.039731 0.00357 -0.029935 0.13167 0.18358 -0.12839 -0.027227 -0.055763 -0.015632 0.018481 -0.096078 0.010891 -0.030878 -0.082804 -0.035578 0.17599 0.044577 0.20949 0.20219 0.11987 -0.12282 0.13082 -0.047396 0.05179 0.24328 0.025997 -0.017327 -0.17035 0.22185 -0.068049 -0.11139 0.033333 -0.12122 0.025779 0.15938 -0.036345 0.0091971 -0.11033 -0.079248 -0.10993 0.085555 0.009754 -0.23608 -0.18619 -0.071835 -0.024813 0.074658 -0.028669 0.031546 0.088931 0.23872 0.168 -0.058967 0.063124 -0.057813 0.019214 0.016109 0.11406 -0.074514 0.051821 0.20783 -0.086803 0.10953 0.064944 -0.21673 -0.037683 0.08186 -0.039891 -0.051334 -0.10165 0.16642 -0.13079 0.035397 + 0.050258 -0.073228 0.43581 0.17483 -0.18546 -0.39921 -0.50767 -0.5066 -0.15557 0.031451 -0.23794 -0.44625 -0.26341 -0.26413 -0.26935 -0.62865 -0.13574 0.0697 0.26568 0.51541 0.15814 0.079607 -0.3292 -0.49749 -0.57232 -0.33162 0.014227 -0.68094 0.19999 0.30894 -0.14691 0.75068 -0.26486 -0.16091 -0.28034 -0.20183 -0.11985 0.22705 -0.045547 -0.15134 -0.011689 -0.27698 -0.2437 -0.15531 0.24802 0.4509 0.28325 0.014937 0.09297 -0.1092 -0.0086647 -0.6663 0.045632 -0.67015 -0.35459 0.32214 0.12842 -0.24621 0.045134 0.16213 -0.42758 0.047525 0.22376 -0.076248 -0.33242 0.32999 0.22151 -0.07364 -0.30562 -0.075884 -0.30567 -0.075288 0.47872 -0.0016653 -0.38415 -0.15147 0.032541 0.10061 -0.22427 -0.089372 -0.09919 0.038547 -0.10372 0.11169 0.097768 -0.12516 0.34805 0.041478 -0.09772 0.12842 0.21191 0.35702 0.016588 0.097898 0.053985 0.10617 0.28678 0.0080181 -0.39085 0.11191 -0.065404 0.25064 0.22351 -0.25068 0.33498 0.14085 0.18437 -0.24563 0.11691 -0.061179 0.13982 -0.061849 -0.63793 0.25816 -0.45235 -0.22747 0.11045 -0.19549 -0.38292 0.12213 0.20989 -0.023781 -0.029434 0.67661 -0.13742 -0.017769 -0.22432 0.036397 -0.30378 0.26628 -0.33948 -0.29191 -0.12385 0.57559 0.44472 0.062263 -0.045536 -0.62385 0.36338 0.41903 -0.3859 -0.081036 0.3288 0.084426 -0.0037573 -0.11293 0.16085 -0.40933 0.2173 0.25528 -0.065366 -0.17348 -0.083693 0.25174 0.75242 -0.53454 0.16996 0.094621 0.12053 0.22422 0.0011159 0.16707 0.51839 -0.1744 0.025452 0.21807 0.45783 -0.46315 0.30251 0.25376 0.02066 -0.27437 -0.23975 0.33155 -0.13735 0.43456 -0.13665 -0.35264 -0.25314 -0.92955 0.11719 -0.14386 0.21486 0.037592 -0.50122 0.41659 -0.057749 -0.2434 0.23677 -0.0018475 0.34872 -0.61496 0.022873 0.32567 -0.83872 -0.16147 -0.17395 0.21363 -0.43727 0.14279 0.26738 -0.046942 0.1363 0.2106 0.50295 -0.014423 0.092695 -0.02267 0.39947 -0.10061 -0.13776 0.20739 0.12981 0.26965 0.14809 -0.22363 -0.028562 -0.35537 0.028521 0.0053468 0.2309 0.16529 -0.062287 0.17005 -0.37884 -0.3614 0.27422 -0.30957 0.52594 -0.42936 0.05008 -0.097497 -0.026312 -0.14241 -0.097804 0.013366 0.13045 -0.24812 -0.035794 -0.058777 -0.064151 0.40489 0.051363 -0.20573 0.10242 -0.075556 -0.18351 0.17996 -0.24141 -0.30461 -0.29783 -0.20861 -0.4629 0.019042 0.23051 -0.1673 0.14045 -0.41304 0.27465 0.11554 0.1011 -0.16508 -0.045205 0.33258 -0.61465 -0.35526 0.057278 -0.18852 -0.15476 0.39045 -0.1298 -0.15306 0.32079 0.30198 0.0018952 -0.11331 -0.52281 0.19551 0.16529 -0.18258 -0.084573 0.13313 0.37051 -0.21161 -0.039851 0.46209 0.073142 -0.06693 -0.021576 0.3622 -0.096853 -0.47723 -0.027511 0.25964 -0.010468 -0.29815 -0.23609 0.20525 0.75183 0.097156 +of 0.048804 -0.28528 0.018557 0.20577 0.060704 0.085446 -0.036267 -0.068373 0.14507 0.17852 0.14579 -0.1363 0.23348 0.029758 -0.22001 -0.0045515 -0.11197 -0.041367 0.084231 0.076673 -0.24461 0.053593 -0.10939 -0.12468 -0.2029 0.074565 0.1066 0.054339 0.088268 0.22557 -0.029081 0.298 -0.16129 0.36419 0.073978 -0.089561 -0.041104 -0.24277 -0.005801 -0.062838 0.061766 -0.06338 0.064886 0.076681 0.054731 -0.12146 -0.10907 -0.092789 0.033569 -0.18984 0.0891 0.013016 -0.051571 0.02804 0.12697 -0.077554 0.15722 0.077476 -0.16343 0.16547 -0.26099 -0.29122 0.30182 -0.16759 -0.056519 -0.12898 -0.19702 -0.15118 -0.13374 -0.15003 -0.23525 -0.15915 0.13042 -0.027344 -0.12427 -0.043631 0.12414 0.34889 0.049437 -0.010112 0.20247 0.082294 -0.15157 -0.22737 0.12064 -0.061304 -0.077713 0.1096 -0.096096 -0.20338 -0.02294 0.15945 0.23325 -0.23107 0.052684 -0.096946 0.057373 0.14143 0.076547 0.018265 0.064091 0.044858 0.088128 -0.11694 -0.2496 -0.13049 -0.083017 -0.060082 0.024055 -0.020748 0.039135 0.043567 -0.10208 -0.15464 0.12892 -0.02419 0.04537 0.12778 0.13212 0.19208 0.24737 0.12406 -0.20246 0.13762 -0.023151 0.041736 -0.013967 0.18194 0.1621 0.062586 -0.079981 0.13184 -0.077388 0.020313 -0.041488 0.020524 -0.1131 0.14639 0.080113 0.03685 0.1364 -0.0097955 0.11779 0.13547 0.2289 0.21231 -0.079779 0.13831 -0.076114 0.028563 0.11441 -0.15455 -0.083267 -0.057167 -0.099352 -0.17063 -0.071757 -0.051497 0.26568 0.018799 -0.2722 0.1268 -0.021045 0.058831 0.30213 -0.035255 -0.095952 -0.039082 0.20369 -0.17869 -0.26188 -0.11006 -0.15694 -0.028803 -0.23872 0.15594 0.0087185 0.24053 0.12139 0.13728 0.015927 -0.013386 -0.069045 0.10303 -0.072071 0.27962 0.19157 -0.1381 0.071393 -0.031548 -0.035299 -0.074609 0.20415 0.07185 -0.068672 -0.041217 -0.087057 -0.11665 -0.20257 0.073188 -0.073497 -0.27951 -0.17393 0.064005 -0.050394 -0.044426 0.0084868 0.065147 0.075381 0.11124 0.24971 0.16696 0.040472 -0.14533 0.016763 -0.11273 0.017435 -0.19177 -0.044961 0.085638 0.079341 -0.046213 -0.20255 0.26274 -0.091053 0.077721 -0.15454 0.042321 0.11742 -0.086041 0.087611 0.21365 -0.13597 -0.029987 -0.021053 0.026222 -0.063741 -0.083649 0.016566 0.043541 -0.039012 -0.0099747 0.13427 0.063209 0.22825 0.14844 0.032926 -0.19012 0.19838 -0.22369 0.00018847 0.17405 -0.037903 0.020661 -0.084053 0.18419 0.028517 -0.098006 0.19939 0.07981 0.1241 0.09525 -0.035341 0.08413 -0.082303 -0.075792 0.16535 0.11581 0.013019 -0.080894 -0.0104 -0.078736 -0.11122 0.028996 -0.06331 -0.03393 0.020572 0.26452 0.0017304 0.019002 0.14132 -0.07911 0.15356 0.072873 0.087168 -0.005553 -0.020073 0.15022 -0.015351 0.16743 0.16956 -0.33677 -0.060286 0.086097 -0.065001 0.0048331 -0.10096 0.1391 -0.13714 -0.039705 +- -0.12278 -0.036748 0.20728 -0.018277 -0.0016348 0.023735 -0.03712 -0.28608 -0.19088 -0.068688 0.061755 -0.052416 0.16867 -0.1108 -0.11308 -0.27392 -0.30827 0.18204 0.096594 0.29725 -0.050727 0.023406 -0.33813 -0.10599 -0.11249 0.066722 0.14842 -0.31099 -0.09372 0.0027705 -0.16806 0.20955 -0.23591 0.070785 -0.25399 -0.1121 -0.12584 -0.11348 -0.13821 -0.37261 0.1712 0.091039 0.12721 0.033067 -0.033074 0.03804 -0.18015 0.043457 0.099211 0.037043 -0.0035936 -0.35885 -0.1046 -0.24532 0.12304 0.11229 0.0019709 0.16426 0.051579 0.081311 -0.0034787 -0.17466 0.30059 -0.23183 -0.017487 0.28647 0.39977 0.10196 -0.31603 -0.080053 0.1363 -0.27921 -0.070414 -0.42057 0.22811 -0.0048721 0.28294 0.13337 -0.13565 0.36156 -0.21077 0.0951 -0.078161 -0.19526 0.12015 -0.34326 0.091878 -0.1481 0.15075 -0.032191 -0.084192 0.012534 -0.27388 -0.03702 0.057868 -0.077148 0.089935 -0.0085872 -0.17457 -0.019762 0.053098 0.17929 0.095319 0.01531 0.30705 -0.10108 -0.32163 -0.030811 -0.12402 0.097465 0.17987 0.14868 -0.15284 -0.09303 0.0088417 -0.19254 -0.01618 -0.23722 -0.012689 0.080786 0.1699 -0.32962 0.21784 0.22417 -0.11523 -0.1468 0.16493 -0.013706 0.061769 0.24206 -0.0030724 0.13193 0.33641 0.082406 -0.090267 -0.062518 0.20536 -0.0067834 0.23309 0.42543 0.12784 0.043186 0.31441 0.29966 0.3764 0.11003 0.078855 0.070249 -0.1237 -0.16134 0.096781 -0.26828 -0.34072 -0.2443 0.23486 0.0035705 0.022555 -0.11751 0.21934 0.1186 -0.19583 -0.013163 -0.1533 0.059138 0.36918 -0.066211 -0.12353 -0.18454 0.075356 0.054704 -0.21953 0.053431 -0.024889 0.26166 0.23565 -0.041392 0.067851 -0.096325 0.37606 -0.057649 0.02432 0.056076 -0.23126 0.23585 0.16382 0.53816 -0.13254 -0.59859 0.045303 0.18787 -0.055629 -0.263 0.21436 -0.16295 -0.10764 -0.059118 0.016773 0.014789 -0.13096 -0.10807 -0.096707 0.13387 -0.18756 -0.014248 0.095107 -0.10209 -0.16448 -0.094758 0.14591 0.16369 0.20648 -0.073274 -0.056667 -0.053844 -0.16913 0.015068 0.19947 -0.17929 -0.52126 0.2772 -0.23779 0.19949 -0.20515 -0.19561 -0.30977 -0.066952 0.067665 0.11951 0.15856 0.18632 0.1467 0.1089 -0.086139 -0.036918 0.034145 0.11727 -0.0038274 -0.019283 -0.13522 -0.17907 0.12257 0.010163 -0.070272 -0.019652 0.35313 -0.028667 0.25019 0.24459 -0.24002 0.15758 -0.0019125 0.005391 -0.21876 0.17596 -0.079358 -0.081188 0.020766 0.08006 -0.020661 0.092431 -0.033553 0.23134 0.0011203 0.17548 -0.3203 0.14953 -0.082272 -0.16887 0.2853 -0.27014 -0.34351 0.14424 0.16748 -0.31432 -0.31462 -0.05592 0.053108 -0.0015233 -0.067186 -0.088541 0.021988 0.29623 -0.17202 -0.13207 0.10663 0.13491 0.29138 0.15629 -0.08598 0.090109 0.14234 -0.16496 0.35746 0.10796 0.03212 0.012067 0.018267 -0.06944 0.28509 0.06188 +in 0.12367 -0.13965 0.044877 0.18919 -0.10997 -0.0064458 0.050499 -0.20439 -0.015761 0.15049 0.13774 -0.068241 0.17078 -0.13529 -0.18324 -0.00035567 -0.099566 -0.14549 0.067183 0.028273 -0.10084 0.10498 -0.24613 0.008831 -0.18437 0.050011 -0.032839 -0.069129 0.0043659 0.11011 -0.32272 0.26625 -0.12465 0.32157 0.067982 -0.22671 0.081843 0.11435 0.062067 -0.072973 -0.013415 -0.048493 -0.11426 0.069743 -0.070937 -0.062886 -0.015692 -0.033663 0.10441 0.0050113 -0.0017716 0.01172 -0.086168 0.012221 -0.14817 0.035373 0.039869 0.29904 0.02467 0.18096 0.070858 -0.3536 0.090518 -0.12905 -0.010443 -0.18697 -0.21258 -0.044644 -0.25333 0.10031 -0.17369 -0.037354 -0.030931 -0.091972 -0.068233 0.022366 0.12569 0.13749 -0.079547 0.0071489 -0.15117 0.27538 0.13964 0.0088001 -0.0032892 -0.21313 -0.060543 -0.12321 -0.14875 -0.22362 -0.21024 -0.088803 0.29222 -0.25967 0.22331 -0.045337 -0.03181 0.20282 -0.072763 0.08423 -0.13619 -0.065391 0.045686 0.13292 -0.16045 0.068327 -0.085854 0.1138 -0.037301 0.1485 0.11429 0.075152 -0.082689 -0.1272 -0.025567 0.0070075 0.26045 -0.065811 0.032715 0.19796 0.16154 0.04616 -0.1811 0.2221 -0.097602 -0.16946 0.14142 0.099035 0.15536 0.19277 -0.077073 0.1304 0.078304 0.073262 -0.14858 0.154 -0.10688 0.055093 0.0086387 0.19326 -0.026862 0.26057 0.052728 -0.11463 0.17869 0.39083 0.25172 0.1414 -0.066381 0.09811 -0.12604 -0.053404 -0.12783 0.015113 -0.15912 -0.19647 0.17831 0.01199 0.079011 0.038148 -0.1492 0.37324 -0.26121 0.12813 0.12836 0.053578 -0.076507 0.076671 0.13526 -0.0133 -0.16123 -0.10848 -0.025315 -0.17731 0.076161 -0.060174 0.14036 0.23606 0.013044 -0.0038421 0.18789 -0.088722 0.032518 0.22781 -0.023559 0.084643 0.12242 0.0088557 0.076508 -0.0050585 -0.099194 -0.067806 0.059907 0.035404 0.018719 -0.026816 -0.0043838 0.082026 -0.11986 -0.20797 0.1857 -0.093772 -0.016299 0.16044 0.033307 -0.15447 -0.1299 0.12446 0.10375 0.15186 0.17916 -0.0392 -0.17544 0.011754 -0.083566 -0.0018136 0.12672 -0.20117 -0.16977 -0.14783 0.044156 -0.17907 -0.046772 -0.0019811 -0.037412 0.001387 -0.10561 -0.15427 0.14016 0.041157 0.19222 0.012073 -0.066753 -0.025257 -0.15648 0.024427 -0.018674 -0.16705 -0.05062 -0.075287 0.043062 0.0061818 0.10573 -0.0029119 0.071643 0.13324 0.24889 -0.012998 -0.077142 0.1755 0.16971 -0.034875 0.084939 -0.19587 -0.26115 -0.052924 -0.23034 -0.13479 0.13933 0.041106 0.045816 0.11113 -0.0703 0.012925 0.13977 -0.063616 0.043891 0.027855 -0.03961 -0.095799 -0.12588 -0.084711 -0.0042531 -0.059085 -0.093324 -0.33958 0.063525 0.082276 0.062395 -0.099955 0.014326 0.042645 0.080227 0.089646 0.1758 0.034153 0.00055167 0.11687 -0.089006 -0.0084893 0.025115 -0.31804 0.12533 -0.081507 -0.1114 0.017582 -0.037359 0.06474 -0.14581 0.16175 +and -0.031533 0.046278 -0.12534 0.19165 -0.1266 -0.012853 0.10342 -0.0098085 0.15189 0.27582 0.13695 0.0088799 0.14132 -0.12 -0.063439 -0.15178 0.09809 -0.1201 -0.069086 0.014666 -0.023041 0.03043 -0.12664 -0.063282 -0.082246 0.036718 0.22698 -0.096025 -0.011699 0.066158 -0.18542 0.19223 -0.061685 0.27049 0.075116 -0.054928 -0.086027 -0.19387 0.14677 -0.06013 0.068269 0.071613 -0.094414 0.036158 0.002782 -0.081711 -0.013369 -0.053017 0.052227 -0.079682 -0.00031768 0.030397 -0.16847 0.021828 -0.19577 -0.050109 -0.0096879 0.085536 -0.28135 0.17001 -0.049194 -0.16721 0.19018 -0.0474 -0.00036412 0.026316 -0.22135 -0.061583 -0.21854 -0.021669 -0.2963 -0.071949 0.010638 -0.19055 -0.11292 -0.099072 0.19357 0.14115 0.068346 -0.00045947 0.072621 -0.021192 -0.1242 -0.041933 -0.028386 0.049083 -0.073574 0.073525 0.088135 -0.032184 0.029903 -0.070025 0.15323 -0.17236 0.073502 0.13232 0.090191 0.0079023 -0.027887 -0.046971 0.039198 -0.12567 0.19803 -0.075995 -0.21353 0.031964 -0.17346 0.055884 -0.055404 -0.0083924 -0.024104 0.0023894 -0.1057 -0.10604 -0.061323 -0.041473 0.0060497 0.055896 -0.071338 0.1375 0.094781 0.048121 -0.071236 0.26263 0.07257 -0.00020344 0.1864 0.066703 0.055229 0.11258 0.047647 0.085482 -0.14489 0.0098078 0.082585 0.039254 -0.10044 0.16532 -0.030841 0.10315 -0.046584 0.11211 0.15416 -0.050309 0.14853 0.2287 -0.056036 -0.072966 0.0018167 -0.015694 -0.06022 -0.19044 -0.075073 -0.0032815 -0.079256 -0.078324 -0.11073 -0.093705 0.26284 0.01034 -0.095 0.17295 -0.053949 0.15056 0.22815 -0.16589 -0.080074 -0.076248 0.13423 -0.093626 -0.065384 -0.014181 -0.067937 -0.038283 -0.084514 0.11082 0.068804 0.19402 -0.069373 -0.043398 0.15402 -0.10172 0.049785 -0.010005 -0.03371 0.29018 0.025405 -0.094919 0.093876 -0.055423 -0.059419 -0.082542 0.094048 0.059422 -0.032564 -0.0062017 -0.0095274 0.092439 -0.16995 0.00038904 0.19187 -0.025048 -0.11844 0.027879 -0.034024 -0.046866 -0.09009 -0.034417 0.25534 0.096778 0.20841 0.029693 -0.015943 -0.035779 0.0021559 0.080246 -0.031355 -0.22676 -0.11579 -0.059579 -0.07442 -0.12871 -0.10199 0.064969 -0.070388 -0.040131 -0.1474 -0.098839 0.11614 0.15871 0.0693 0.031897 -0.028738 -0.084634 -0.14864 0.11398 0.072688 -0.065752 -0.013296 0.085164 0.025053 0.016867 -0.045257 -0.042925 0.12329 0.13012 -0.01532 -0.13943 0.089764 0.082172 -0.081918 -0.011688 -0.11742 0.029242 -0.065814 0.029959 -0.010941 -0.0183 0.05718 0.068436 0.0072271 0.0057584 0.071466 -0.083164 -0.01501 -0.07806 0.0033293 0.099132 0.061188 -0.097815 -0.14008 -0.0026304 0.0022269 0.083496 -0.14334 -0.037447 0.061564 0.21536 -0.036836 0.038629 0.13031 0.045944 0.027701 0.061679 0.062921 0.068453 -0.026292 0.17342 -0.14421 -0.013124 0.15494 -0.10786 0.18314 0.13881 0.02757 -0.035073 -0.017829 0.11163 -0.058231 0.011977 +' -0.17489 -0.13695 0.13345 -0.07282 0.038794 0.13294 0.0015304 -0.071056 -0.20026 -0.045437 -0.0019054 -0.17913 0.18241 -0.058909 -0.0088248 0.060522 0.1872 0.2255 -0.11638 0.080349 -0.33614 -0.035788 -0.21518 -0.062891 -0.1322 -0.09628 0.065516 0.16418 -0.014492 0.11139 -0.25025 0.25303 -0.20538 -0.027447 -0.18057 -0.13118 -0.36836 0.055097 0.23968 -0.17034 0.26393 0.30392 -0.18615 0.13712 -0.012511 0.11977 0.00017869 0.059385 -0.05704 -0.046391 0.012484 -0.067036 0.20004 -0.34513 -0.16117 -0.082885 -0.043013 0.031685 -0.01498 0.11803 0.068215 -0.18596 0.11503 -0.020593 -0.15533 0.031101 0.1294 0.038285 -0.075081 -0.095411 0.13559 -0.13448 -0.092657 -0.39257 -0.1617 -0.06562 0.069601 0.26207 -0.039711 0.39187 0.16218 0.053275 -0.066056 0.10139 -0.076679 -0.059841 -0.069376 0.21551 -0.029553 -0.123 0.011586 0.16999 0.17508 0.090918 0.10799 0.085566 -0.0042548 0.097031 0.18012 -0.24137 -0.1599 0.018539 -0.1056 -0.052341 -0.034019 -0.13327 -0.15889 0.033714 0.079085 -0.01673 0.062222 0.16459 -0.021192 0.014571 -0.017858 0.17836 0.13005 0.27747 0.056348 0.13513 0.4205 0.024011 0.18547 0.030009 0.119 -0.058 -0.092228 0.025134 0.003047 -0.024764 0.11025 0.21792 0.12071 0.26308 0.13265 0.058854 -0.36855 -0.04149 0.10599 0.25175 -0.028787 -0.043812 -0.036435 0.0089733 0.066932 0.1702 0.1665 0.094226 -0.14053 -0.18362 -0.035076 0.11685 -0.08793 -0.17653 -0.24763 0.12285 0.0053936 -0.048667 0.23958 0.17958 -0.21611 0.08723 -0.17605 0.17473 0.14182 0.081131 -0.087419 0.071543 0.21449 -0.061005 -0.07196 -0.23685 -0.11879 -0.0071595 -0.071583 0.049396 -0.02676 0.068993 0.0073673 -0.038216 0.16864 0.16553 0.01517 0.15875 -0.1054 0.05747 0.13809 -0.019921 0.36033 0.21684 0.063086 -0.11092 0.35303 0.30894 0.12569 -0.008461 0.25211 -0.073476 -0.442 0.022188 -0.0423 -0.018912 -0.15181 0.19475 0.043222 -0.23028 -0.25009 0.011266 0.14797 0.22005 0.40872 -0.13427 -0.18417 0.011872 -0.1966 -0.18597 0.13815 -0.22767 -0.17908 0.10512 -0.057826 0.071071 -0.23812 -0.0067891 0.036996 -0.029889 -0.17022 0.14456 0.040532 -0.029142 -0.012301 0.2311 -0.14316 -0.22666 -0.19614 0.15429 -0.023078 0.015926 -0.077029 0.065054 -0.30557 0.13245 0.068753 0.11286 0.14658 0.2298 0.18136 0.22165 0.1076 0.0045102 0.1825 0.10714 0.027691 0.13585 0.07148 0.033098 0.030476 -0.13848 0.23759 -0.26323 0.095756 0.15745 0.099187 0.013283 -0.030978 0.10267 0.030753 0.22487 -0.014633 -0.16486 -0.30891 0.0551 -0.15767 -0.11141 0.034447 -0.054475 0.33544 -0.0042994 0.27241 -0.15068 0.096341 0.14226 0.097858 0.00082821 -0.0092396 0.10388 0.18306 0.39652 0.21525 -0.01238 -0.040262 -0.1476 -0.0018151 -0.040134 -0.17208 -0.225 -0.18652 0.13567 0.20318 0.10497 +) -0.2126 -0.1625 0.19291 -0.025168 -0.053647 -0.060966 0.045574 -0.21204 -0.12945 0.16739 -0.091312 -0.18321 0.24384 -0.18695 0.1443 0.059095 -0.14303 -0.037694 -0.035785 0.11922 -0.011128 0.21314 -0.27044 0.077567 -0.018137 0.1594 -0.043637 -0.25154 0.069122 0.023117 -0.30039 0.28047 -0.20755 0.1845 0.02708 -0.011796 -0.19094 -0.22944 0.15557 -0.28047 0.033552 0.13621 -0.16158 0.020503 -0.10356 -0.21584 -0.1115 -0.056023 0.10392 -0.023046 0.033985 -0.26918 -0.03143 -0.26883 -0.098116 -0.17722 0.080194 -0.044145 -0.064201 0.21535 0.16698 -0.25132 0.21311 -0.16862 0.084063 -0.066586 0.16939 -0.27313 -0.2829 0.027755 0.051774 0.056767 0.023735 -0.19652 0.12754 -0.015561 0.26425 0.27562 0.086458 0.38182 -0.14553 0.20525 -0.024237 0.054286 0.25675 -0.17819 0.074283 0.044713 0.088217 -0.033261 0.19087 -0.19817 0.034355 -0.085662 -0.0048418 -0.056916 -0.1033 0.006265 0.17492 0.027866 0.084206 0.0674 -0.21523 0.041361 0.17755 -0.022406 -0.1821 -0.011688 0.15014 -0.16614 0.077185 -0.016522 -0.19297 -0.13536 -0.062133 0.07223 0.059149 0.0010406 -0.16859 0.078426 0.34513 -0.12174 -0.1464 0.28904 0.010986 0.096763 -0.048568 0.2518 0.12331 0.06257 0.15267 0.17711 0.25384 0.3384 0.092287 0.00019422 0.093004 -0.1721 0.10527 0.19721 0.070042 0.10979 0.14692 0.093588 0.13641 0.22856 0.22282 0.089212 -0.069749 0.080828 -0.1607 0.063175 -0.1026 -0.14976 0.064174 -0.0093489 0.22512 0.17281 0.19723 0.19006 0.058608 0.13837 -0.27155 0.12318 0.014049 -0.10999 0.08605 0.063453 -0.014096 0.073693 -0.19318 0.073913 -0.14857 0.075652 -0.034264 0.063866 0.029645 -0.1415 -0.064215 -0.064351 0.082878 -0.21816 0.15486 0.22435 -0.10632 0.35149 0.020847 -0.11029 0.085623 0.013362 -0.013515 -0.25033 0.30575 0.12325 -0.24006 -0.22024 0.1085 0.15251 -0.46239 -0.023871 -0.0187 -0.27595 -0.22326 0.063294 0.066861 0.0054138 -0.21897 0.12192 0.25844 -0.11957 0.30079 -0.086595 0.07059 -0.02802 -0.2091 -0.11872 0.13817 -0.10185 -0.35833 -0.22782 0.0063531 -0.039577 -0.051306 0.015049 -0.0093668 -0.045136 0.0060684 0.076519 0.24035 0.070766 -0.026567 0.16117 -0.010365 -0.21722 -0.15059 0.030043 -0.061588 -0.18267 -0.054825 -0.12734 -0.070047 0.36237 0.054465 0.041087 0.092893 0.015996 0.16168 0.16533 0.03856 0.14239 0.13336 -0.18878 -0.12308 0.1819 -0.050355 -0.13599 0.01481 0.10454 -0.10483 -0.16066 0.16406 0.0059985 -0.045827 0.097182 -0.012632 0.26425 -0.01622 -0.11908 -0.085307 0.037455 -0.1698 0.0064602 0.064675 -0.069502 -0.13218 -0.047747 0.14874 -0.040672 -0.016932 -0.15343 0.058897 0.17917 -0.098042 -0.022264 0.133 0.034409 0.39194 0.078925 0.33269 0.18809 -0.19698 -0.15207 0.11303 0.095242 -0.012663 -0.16269 -0.007411 0.13281 0.13515 0.27486 +( -0.23309 -0.15296 0.18574 -0.052825 -0.024827 -0.05597 0.051828 -0.21042 -0.10736 0.1481 -0.073067 -0.18498 0.24592 -0.16441 0.12237 0.046963 -0.10949 -0.022478 -0.0447 0.13849 -0.053463 0.20186 -0.2108 0.10247 0.017499 0.17167 -0.002015 -0.26022 0.038803 0.014472 -0.27706 0.31515 -0.21957 0.20444 0.030268 -0.045881 -0.2279 -0.21473 0.23163 -0.2868 0.030923 0.14941 -0.14564 0.022334 -0.12018 -0.22059 -0.10883 -0.062123 0.11207 -0.035432 0.03905 -0.30039 -0.024871 -0.29661 -0.071842 -0.17986 0.083709 -0.047429 -0.10833 0.21972 0.15335 -0.29379 0.16957 -0.16255 0.045921 -0.07833 0.18348 -0.24966 -0.29057 0.011203 0.010288 0.052393 0.0096249 -0.18478 0.13012 -0.011579 0.25199 0.2378 0.09148 0.40134 -0.14071 0.20658 -0.061358 0.069975 0.2856 -0.19824 0.0567 0.021811 0.058719 -0.022546 0.14477 -0.15554 0.053924 -0.072887 0.016839 -0.074752 -0.11665 -0.037688 0.19177 -0.020931 0.071214 0.060542 -0.23209 0.0155 0.18033 -0.044522 -0.17467 -0.0012956 0.17471 -0.16881 0.062072 -0.036062 -0.18079 -0.14591 -0.011288 0.13394 0.021847 -0.0023774 -0.17014 0.065934 0.35347 -0.10659 -0.13757 0.2813 0.017342 0.14848 -0.070759 0.28449 0.1472 0.035648 0.14415 0.14304 0.23559 0.32984 0.1171 -0.044802 0.045307 -0.11628 0.088198 0.18592 0.024245 0.13704 0.11964 0.13648 0.13993 0.22819 0.20639 0.12183 -0.10479 0.040495 -0.20939 0.062136 -0.075468 -0.14227 0.069215 0.0011967 0.18513 0.13571 0.18718 0.17761 0.045758 0.095972 -0.27707 0.068867 -0.020278 -0.094161 0.062102 0.069499 -0.072098 0.063163 -0.21225 0.085972 -0.15251 0.05548 -0.027419 0.10628 0.01283 -0.14169 -0.057287 -0.073863 0.056337 -0.21388 0.17499 0.17013 -0.093788 0.32699 0.046617 -0.11163 0.13034 0.043024 -0.0059465 -0.2548 0.28502 0.12449 -0.21813 -0.20569 0.10454 0.1004 -0.42906 -0.007037 -0.018476 -0.31813 -0.21764 0.047122 0.027254 0.0017014 -0.23509 0.14708 0.29648 -0.10767 0.33138 -0.078287 0.089908 -0.088922 -0.21133 -0.094596 0.13933 -0.089867 -0.34324 -0.19651 0.0059196 -0.025083 -0.090159 0.023366 -0.018513 -0.071158 -0.0064573 0.083286 0.21143 0.035236 -0.037667 0.17583 0.010726 -0.25549 -0.14307 0.013955 -0.071004 -0.15664 -0.098823 -0.11756 -0.046788 0.3264 0.050847 0.041035 0.098737 0.049633 0.17132 0.13964 0.067877 0.14413 0.16669 -0.14594 -0.1377 0.1902 -0.050886 -0.14369 0.0096079 0.098092 -0.098844 -0.1428 0.1805 0.026372 -0.029204 0.085949 -0.036377 0.26778 -0.025757 -0.10396 -0.047153 0.020454 -0.19168 -0.014001 0.062676 -0.091414 -0.095178 -0.06614 0.13276 -0.014844 -0.0089356 -0.1552 0.063869 0.1804 -0.099814 0.033382 0.18021 0.072454 0.37026 0.056646 0.33106 0.19567 -0.19433 -0.16877 0.11429 0.10103 -0.0087225 -0.16495 0.016876 0.099402 0.18834 0.26413 +to -0.21341 0.15353 0.05288 -0.10995 -0.075249 -0.0040931 0.037307 -0.12307 -0.16539 0.18948 0.018882 -0.037826 -0.032465 -0.00097399 0.10223 -0.090187 -0.15477 0.092984 -0.034548 0.11354 0.10526 0.23558 -0.18151 -0.057149 -0.33498 -0.09525 -0.043807 -0.11598 0.093461 0.14055 -0.23846 0.22991 -0.43074 0.17527 -0.095848 -0.16689 -0.12666 -0.33239 -0.029917 -0.044658 0.068506 -0.14732 -0.19448 0.081522 0.095537 0.13374 0.22849 0.071417 0.075921 -0.012085 0.11477 -0.24506 0.088227 -0.12577 -0.28356 0.23966 0.1349 -0.043612 -0.058942 -0.14964 0.048619 -0.25521 0.35135 -0.010485 -0.012291 -0.228 -0.24907 0.17066 -0.22779 0.12321 -0.23268 0.068668 0.062476 -0.28448 -0.058069 -0.02294 0.32555 0.14967 0.039717 0.12684 0.062978 -0.01068 -0.11597 -0.16 0.075278 0.0643 -0.019621 0.1161 -0.045974 -0.13481 -0.040836 -0.052048 0.26106 -0.41484 -0.011617 0.079744 0.026266 0.00090593 -0.017469 -0.14069 0.18253 -0.085152 0.082151 -0.14794 0.031756 -0.043832 -0.089463 -0.025928 0.064068 0.1158 0.063466 -0.10519 0.030217 -0.12547 -0.18348 -0.18148 0.16018 -0.066333 -0.056771 0.068108 -0.045265 0.021353 -0.082332 0.29351 0.22133 -0.14231 0.068658 0.060024 -0.079182 0.27073 -0.036687 -0.0074472 0.028575 -0.002216 0.012085 0.26404 0.020489 0.038974 -0.19869 0.065939 -0.11451 0.15766 0.15876 -0.10153 0.15162 0.26821 0.23388 -0.11493 0.098095 0.053563 -0.10113 0.05531 -0.20974 -0.035791 -0.14873 -0.20049 -0.022756 0.057507 0.20447 -0.18627 -0.21503 -0.0044905 -0.28856 0.031048 0.16272 0.067949 -0.15246 -0.019164 0.31189 -0.010774 -0.25956 0.016564 -0.035822 0.077274 -0.10028 0.31529 0.032038 0.25298 -0.1769 -0.14586 0.090035 -0.059671 0.1124 0.3027 -0.079148 0.21147 -0.0021538 -0.023762 0.24101 -0.022107 -0.14914 -0.17478 0.19457 0.11478 -0.056655 0.16902 -0.10203 0.092118 -0.029558 0.053092 0.095661 -0.11535 0.025039 0.11723 -0.12198 -0.13359 -0.20374 0.056916 0.019352 -0.00010443 0.13141 -0.11953 0.032819 0.14745 0.048164 -0.13463 0.10255 -0.090965 0.12527 0.10708 -0.1684 -0.12506 0.14798 0.047775 0.027096 -0.022445 0.064138 -0.17978 -0.19269 -0.017962 0.33083 0.12766 0.10295 0.13917 -0.24834 0.14435 -0.12073 0.11765 -0.086994 -0.0035333 0.1392 0.12856 0.062702 -0.046897 0.0059045 0.23477 0.10548 0.017885 -0.041222 0.078198 0.1512 -0.071557 0.064352 0.02891 -0.010313 -0.21598 -0.18317 -0.0098099 -0.094472 -0.20104 0.039202 0.094147 0.046894 -0.036062 -0.072277 -0.11157 -0.1067 0.1109 -0.022301 -0.070209 -0.070016 -0.25438 0.10335 0.056638 0.024858 0.012796 0.077072 0.10816 -0.051854 -0.056149 -0.0028173 0.0060163 -0.11311 -0.060675 0.13326 -0.015193 -0.031639 0.13717 -0.055809 0.060995 0.027739 0.020689 0.0078359 0.18155 0.29327 -0.2153 -0.24152 -0.025937 -0.072507 0.14989 +a 0.11559 0.30192 -0.11465 0.01001 -0.032187 -0.10755 0.060674 -0.10477 0.17488 0.0081116 -0.02263 0.065401 0.1133 0.054737 -0.06209 -0.029822 -0.16608 0.12224 0.045251 0.2134 0.027965 -0.031319 -0.25392 -0.20146 -0.19688 -0.015251 -0.27038 0.10511 0.074226 0.01554 -0.014038 0.16516 -0.17375 -0.016743 0.013919 0.01119 -0.12599 -0.11975 0.079578 -0.037088 -0.071665 -0.085153 -0.1117 0.020142 -0.161 0.0019132 0.13843 0.15445 -0.026397 -0.014582 0.00060368 -0.19382 0.11267 0.035035 -0.014103 0.11427 -0.093813 -0.048103 -0.0057412 0.18635 -0.13767 -0.25908 0.21259 -0.18934 -0.0666 -0.36531 -0.3073 -0.05415 -0.017772 0.053708 -0.2085 0.043945 0.011802 -0.043432 0.056697 -0.087127 0.049667 -0.0098114 0.098693 0.044723 0.090933 -0.088065 0.057724 -0.19914 0.12831 -0.07628 -0.11602 -0.043127 -0.27085 -0.0964 0.046104 -0.057634 0.12419 -0.094156 0.088391 0.015803 0.057685 0.1791 -0.16668 -0.0055587 -0.28134 -0.012136 0.13262 0.15771 0.023281 0.049928 -0.1379 0.17804 0.032105 -0.0090514 -0.15264 -0.058656 -0.087721 0.028901 -0.041666 -0.30451 0.2219 -0.00363 0.077197 0.12785 0.12945 0.073578 -0.027118 0.36309 0.026545 -0.060575 0.016652 0.052824 -0.039201 0.10092 -0.060684 0.13919 0.075804 0.042375 -0.13606 -0.093351 -0.070637 -0.071629 0.15919 0.12709 -0.053596 0.10054 0.14635 -0.028849 0.12329 0.31595 -0.074747 -0.013792 -0.081995 -0.08413 -0.098656 0.040794 -0.14104 -0.19548 -0.12146 0.017467 0.21902 0.031789 0.16661 0.033612 -0.26427 0.2818 -0.21657 0.071942 0.31303 -0.043565 0.081923 0.027802 0.12997 -0.22937 -0.25916 -0.028432 -0.074796 -0.20992 -0.073081 0.025689 0.10352 0.16966 -0.052541 -0.049782 0.10966 0.20609 -0.033784 0.21358 -0.096748 0.17156 0.16477 -0.14704 0.030289 0.055128 -0.044506 -0.39971 0.39786 0.35765 0.050157 -0.165 0.15778 -0.029775 -0.16378 -0.074734 0.13908 0.078804 -0.07814 0.1788 -0.20376 -0.26927 -0.16764 0.13233 0.07399 -0.022863 0.19895 0.036038 -0.090789 -0.0098625 0.051642 -0.23021 -0.10299 -0.25354 -0.25051 -0.075135 -0.17881 -0.0019653 -0.080002 0.21553 0.15182 -0.020711 -0.12492 0.11649 0.01981 0.073403 0.15539 0.026995 -0.11933 -0.030677 -0.16556 0.092261 0.0049417 -0.073793 -0.055393 -0.082741 -0.13011 0.013525 0.018191 -0.0055438 0.058809 0.16387 0.15175 0.0069439 0.038183 -0.061297 0.045698 -0.025712 0.0091615 0.021573 -0.060742 0.10785 -0.088319 -0.12451 0.17643 -0.069255 -0.055677 0.2055 0.15244 0.016753 -0.15624 0.039461 0.078458 0.089246 0.023802 -0.25402 -0.22407 0.079226 -0.1489 -0.0013105 -0.2294 -0.12029 0.17867 0.071291 0.12154 -0.11576 0.13246 0.014544 0.043274 -0.076181 0.044143 -0.14924 0.10415 0.21987 -0.089499 -0.0071804 -0.020257 -0.18694 -0.065594 -0.20223 -0.12218 -0.29798 0.034272 0.11048 0.13074 0.041164 +is 0.035927 0.14517 0.11926 0.078836 -0.047748 0.10096 0.090815 -0.22176 -0.095085 -0.02261 0.0076501 0.04377 0.051051 -0.097378 -0.037446 0.045309 0.00087634 -0.12497 0.029659 0.069825 -0.16091 0.1742 -0.32899 -0.1829 -0.0065372 0.058934 0.019552 0.19681 -0.14456 0.085745 -0.071958 0.37732 -0.34039 0.027648 0.012375 -0.15959 -0.14646 0.16194 0.092523 -0.087637 -0.059375 -0.010355 -0.074173 0.056924 -0.10949 0.28542 0.19264 0.010483 -0.05483 -0.030501 0.068125 -0.049188 0.11643 -0.1018 0.10541 0.096377 0.30352 0.098904 0.16109 0.15746 0.085867 -0.1266 0.086606 -0.012517 -0.060086 0.058047 -0.19545 0.029768 0.1353 -0.054936 -0.09761 0.041602 0.19329 -0.071273 -0.4064 -0.075163 0.037473 0.24462 0.068334 -0.082493 -0.046809 0.12907 0.085082 -0.26625 -0.089977 -0.18727 -0.19797 0.12161 -0.12957 -0.074638 0.26606 0.21286 0.13707 -0.22089 0.061054 -0.25247 0.12172 0.17021 0.14249 -0.059753 -0.22905 0.069484 0.075391 0.054459 0.025777 -0.079382 -0.23297 -0.056315 0.085659 -0.13863 0.010848 0.11964 -0.29033 0.056997 0.10546 -0.09129 0.15602 0.16682 0.19723 0.068381 0.25218 0.12906 -0.11976 0.36511 0.04613 0.14922 0.11582 0.15174 0.066293 0.041363 -0.11032 0.034476 0.087089 0.067598 0.020334 -0.0807 0.11125 0.079644 0.1182 0.14276 -0.16239 0.048049 0.20329 -0.1865 0.068342 0.11872 -0.21844 0.080969 0.11576 -0.086196 0.016645 -0.07335 -0.017962 -0.036097 -0.013199 -0.079475 0.11069 -0.045565 0.53583 -0.011069 0.081706 0.17232 -0.2441 -0.040374 0.32503 -0.0045183 -0.023625 -0.13361 0.11442 0.13294 -0.13098 -0.2013 -0.084633 0.055785 0.024583 -0.031059 0.17107 0.016382 -0.007079 -0.038921 -0.041218 0.13561 0.045142 0.39547 0.084596 0.1296 0.074092 0.050129 0.13505 -0.069099 0.0042038 -0.19653 0.052232 0.21959 0.076529 -0.13691 -0.090079 0.039593 -0.19713 0.088612 0.052963 -0.15249 -0.34548 0.074472 -0.27969 -0.074521 -0.21438 0.14577 0.18846 -0.12055 0.19297 0.089923 0.11085 0.23914 -0.058177 -0.15256 -0.049997 -0.29806 -0.16428 -0.053028 0.057367 -0.12154 -0.2741 -0.12438 0.30366 0.0038798 -0.11727 0.30079 -0.014037 0.0051858 0.014408 0.056017 -0.24088 0.03485 -0.1719 -0.042362 -0.17468 -0.23828 -0.018515 -0.015014 -0.21179 0.16822 0.12561 -0.11843 0.29393 0.30496 0.36829 -0.0016441 0.13448 -0.17843 -0.041137 0.29053 -0.033821 -0.049843 -0.10897 0.057659 -0.0051955 -0.12193 0.18452 -0.043497 0.1309 0.32408 0.049279 -0.12412 -0.23473 -0.065103 -0.1325 0.36398 0.022735 -0.15708 -0.058168 0.11844 -0.011848 0.043694 0.039633 -0.26053 0.32672 0.17928 0.1103 -0.045212 0.22146 0.15149 0.061161 -0.055577 -0.075315 -0.10055 0.11615 0.19411 -0.10141 0.21326 0.040324 -0.2741 -0.11633 -0.089418 -0.072754 -0.26043 0.084246 -0.0016082 0.1708 -0.035512 +was -0.11286 -0.0066148 -0.11885 0.20306 -0.064513 0.072322 -0.093811 -0.15525 -0.036189 0.34825 0.23176 0.059976 -0.092592 0.092237 0.0147 -0.21753 -0.076763 -0.15456 -0.18715 0.26336 -0.00073416 0.20193 -0.15488 -0.17919 -0.23805 0.071975 -0.12965 0.069309 0.20514 0.20612 -0.1414 0.099385 -0.19516 0.10549 0.050975 -0.15156 -0.13718 -0.010712 0.34531 -0.037236 -0.03744 -0.11631 -0.22042 0.14635 -0.089514 -0.18981 0.074337 0.21624 -0.05004 0.079577 0.02683 0.0079568 -0.15662 0.028236 -0.00059906 0.0042458 0.16613 0.29875 0.17 0.12054 0.22972 -0.049533 -0.029605 0.087271 0.12155 0.0099681 -0.17588 0.014035 -0.31022 -0.084543 -0.052421 0.026532 0.01161 -0.1244 -0.06912 0.032998 -0.14902 0.15951 0.17411 -0.19272 0.04991 -0.010682 0.24032 0.076339 0.047806 -0.16769 -0.3259 0.081583 -0.16958 -0.14046 -0.062004 -0.17957 0.10318 -0.20991 0.097164 -0.048931 -0.13686 -0.074554 -0.15368 -0.10308 -0.11061 0.23124 0.10074 0.063702 -0.083507 -0.07046 -0.11517 0.19426 -0.04978 -0.036442 0.19497 0.079694 -0.046286 -0.058381 0.14444 0.021438 0.075135 0.32819 0.054099 0.17631 0.18208 0.25938 -0.1743 0.43839 0.082798 -0.00031243 0.028419 0.21006 0.060504 0.088364 -0.22041 0.085727 0.1673 0.049687 0.06248 -0.11094 -0.050167 0.024378 -0.14511 0.30282 -0.0054825 -0.069529 0.059002 -0.14639 0.081874 0.25299 -0.099531 -0.10847 0.092277 0.1562 -0.00098428 0.097464 -0.045586 0.1291 -0.1382 0.015656 -0.077233 -0.069546 0.40012 -0.20293 -0.18922 0.082001 -0.14097 0.069866 0.32663 0.04148 0.16718 0.10447 0.34784 0.14208 -0.15894 0.074725 -0.087729 0.17719 -0.022197 -0.18665 -0.096478 0.11452 -0.2316 -0.049632 -0.072876 0.19536 -0.24638 0.26485 -0.17163 0.18342 -0.040482 -0.059225 0.011455 0.098593 -0.10773 -0.34245 0.0081285 0.31403 -0.02537 -0.075752 -0.03759 -0.010813 -0.13641 -0.21098 -0.070242 -0.10866 -0.2711 0.1005 -0.16853 0.034627 0.025884 0.19574 0.42803 0.13828 0.37806 -0.17652 -0.042565 0.15672 -0.024619 -0.067026 -0.22909 -0.17072 -0.27418 0.10913 0.19061 -0.075513 -0.30311 0.038966 0.18328 -0.010708 0.018113 0.12733 0.0019824 0.056872 0.04111 -0.12846 -0.093441 0.066377 -0.14303 -0.10907 0.044746 0.12788 -0.13665 0.12689 -0.029595 0.096401 0.14338 0.13761 0.080356 -0.11623 0.19873 -0.23223 0.12289 -0.17505 0.078037 0.12652 0.16914 -0.010766 -0.071861 -0.065455 -0.21393 0.050287 -0.16871 0.21748 0.1181 0.039186 -0.049363 -0.17246 -0.2875 0.19038 0.012786 0.11273 0.12702 -0.12684 -0.30546 -0.073442 -0.11727 -0.011187 -0.10072 -0.34174 0.37268 0.3018 0.25786 -0.18669 0.10741 -0.11652 -0.091167 0.051356 -0.065339 -0.038404 -0.051191 0.24759 -0.068007 -0.20843 0.12345 -0.054013 -0.26918 -0.00033782 -0.021988 0.063821 -0.084829 0.092362 -0.063667 0.054293 +on -0.029945 0.08308 -0.041043 0.062259 -0.019055 -0.070495 0.10458 -0.11022 -0.052828 -0.21471 -0.010283 0.011255 0.044272 -0.12704 0.13873 -0.10672 -0.031042 -0.036724 0.038023 0.14331 -0.15955 -0.010396 -0.30636 0.0018093 -0.21795 -0.19619 0.15655 -0.26115 0.068009 0.0054802 0.018274 0.27194 -0.063782 0.050576 -0.039229 -0.22498 -0.21599 0.028109 0.27633 -0.19207 0.083086 0.066477 -0.049566 0.12438 -0.22175 -0.024482 0.0092416 0.039755 0.030334 -0.30435 0.059653 -0.18663 0.052629 0.0040435 0.021349 -0.08179 -0.012902 0.051812 -0.10407 0.25295 -0.0083517 -0.21269 0.19349 -0.25011 -0.17148 -0.25245 -0.02836 0.009775 0.010365 0.20992 0.094111 0.045987 -0.10821 -0.12871 0.017863 0.016449 0.35166 0.2368 0.087123 0.0014235 0.076331 0.028697 0.1874 0.097398 0.071689 -0.20054 -0.1518 -0.18455 0.247 -0.24415 -0.099852 0.22032 0.28422 -0.26721 0.18074 0.141 0.024393 -0.1074 -0.12624 -0.027884 -0.14301 -0.096826 -0.1293 -0.03152 -0.12661 -0.036811 -0.061348 0.29519 -0.03723 0.24504 0.10346 -0.13672 0.093343 -0.053711 -0.056038 0.10644 0.085047 0.026389 -0.1212 0.020749 0.36126 0.13563 -0.11141 0.27515 -0.021931 -0.033346 0.26127 0.32768 0.16539 0.2657 -0.11442 -0.10774 0.027501 0.20596 -0.26 -0.17816 -0.0702 0.0029366 0.030597 0.036969 -0.11377 0.26168 -0.20023 -0.086989 -0.042935 0.13088 0.26097 0.0067192 -0.28677 0.2712 -0.25236 -0.2575 -0.39759 0.017236 0.15021 -0.17865 -0.061733 -0.078715 0.13485 -0.11931 -0.1454 0.10977 -0.25129 0.12937 0.23836 0.1737 -0.046556 -0.083078 0.12602 -0.14134 -0.27256 0.19661 -0.26557 -0.17845 -0.18839 -0.044315 -0.051716 0.066204 0.14214 -0.047498 -0.17975 0.024502 0.089698 0.023657 0.1227 0.3495 0.14525 -0.17002 0.12992 -0.036131 0.013646 -0.2935 0.021192 0.027402 -0.035963 0.030356 0.036936 0.10434 -0.34108 -0.22907 -0.10944 0.18918 -0.06642 -0.047107 0.038047 -0.13913 0.065176 -0.062903 0.31345 -0.090358 0.44221 0.088019 -0.085611 0.031707 0.0027451 0.21896 0.0056458 -0.45227 -0.11961 -0.12665 0.23553 -0.089455 -0.031027 0.14073 -0.13621 0.025762 -0.23421 0.04172 0.026577 0.14901 0.35331 0.16014 -0.0858 0.10075 0.11963 0.083981 -0.0085175 -0.10134 0.025867 0.0019921 0.11903 0.090903 0.31105 0.093143 0.26736 0.29493 0.03174 -0.06166 0.25909 0.25553 0.21146 -0.036734 0.1269 0.040165 -0.15194 0.12897 -0.49793 -0.0030868 -0.062966 0.090043 0.34313 0.17949 -0.11345 0.14079 0.073598 -0.15301 -0.046048 0.14508 -0.25676 -0.1302 -0.10335 -0.053122 0.042721 0.24057 -0.18248 -0.14799 0.01282 0.26499 0.038375 -0.041837 0.22512 0.082875 -0.21517 0.1009 0.11119 -0.096562 0.07562 -0.078081 0.15468 -0.19181 0.14994 -0.044552 -0.11669 -0.17937 0.36259 -0.16617 0.13773 0.036366 -0.048136 0.0014706 +s 0.038464 -0.11291 -0.17323 -0.03041 0.15791 -0.019141 0.0019244 -0.11037 -0.076457 0.12753 0.11781 -0.13902 0.099159 0.1102 0.064557 0.086609 0.0032735 -0.0087435 -0.17398 0.054122 -0.28031 0.18313 -0.069872 -0.19947 -0.17661 -0.017548 -0.049704 -0.015239 -0.016797 0.19059 -0.16898 0.52075 -0.14446 0.057708 -0.070047 -0.13201 -0.085839 0.019588 0.18062 -0.37744 0.20453 0.018589 -0.23324 0.15698 0.13667 -0.1235 0.030655 0.20784 0.16087 0.17465 0.063654 -0.065543 0.096355 -0.094331 -0.25684 0.18813 0.057432 -0.073132 0.0077761 0.11959 0.12944 -0.25971 0.13682 -0.016024 -0.37095 0.066671 0.08206 -0.10501 0.11285 -0.038756 0.16821 -0.072626 -0.051393 -0.3861 -0.13619 -0.11603 0.12859 0.17121 0.03961 -0.081267 0.1959 0.056111 0.091625 0.043701 -0.18668 0.033272 -0.13498 0.4151 -0.25299 -0.18425 -0.014946 -0.038079 0.16609 -0.0064121 0.066091 0.02267 0.043807 0.060552 0.080007 -0.17192 -0.13464 0.005538 0.068381 0.04762 -0.23787 -0.12178 -0.17201 0.22628 0.17626 0.14631 0.0043271 -0.036512 -0.12546 -0.016598 0.0025892 0.14845 0.14535 0.23339 0.058385 0.084762 0.099059 0.15039 0.18396 -0.040558 0.164 0.01755 0.12023 0.13814 -0.15704 0.039937 0.161 0.25549 0.18153 0.020778 -0.09425 -0.10346 -0.28616 0.044853 -0.070123 0.01281 -0.051044 -0.094495 -0.15318 0.041003 -0.093269 0.16232 0.2233 0.034059 -0.055275 -0.039754 -0.072807 0.056499 -0.14058 -0.044182 -0.16488 0.052832 0.086518 -0.076868 -0.039924 0.27809 -0.1243 0.20393 0.0011994 0.25289 0.14898 0.033952 0.15503 0.053445 0.2614 -0.045747 -0.084473 -0.14395 -0.18902 -0.13388 -0.12626 0.13108 -0.019506 -0.024184 -0.036778 -0.13597 0.22259 -0.040843 0.095631 0.21741 -0.21438 -0.023312 0.1467 -0.16684 0.23378 0.094925 0.020536 -0.060983 0.085806 0.10767 -0.076936 -0.061339 0.0067582 -0.050502 -0.34804 0.050146 0.015361 -0.061954 0.010673 0.071738 0.06038 -0.31371 -0.043667 0.057637 0.14199 0.059277 0.51126 -0.14883 -0.036146 -0.12154 0.041745 -0.11368 0.13902 -0.36065 -0.14418 0.033538 -0.23366 -0.072889 -0.21204 0.066125 -0.19825 -0.0301 -0.091775 -0.061682 -0.054451 -0.069563 0.031283 0.18651 0.040566 -0.1524 -0.13553 0.25094 0.16633 -0.060563 -0.037528 -0.10264 -0.075712 0.064021 0.05656 0.055054 0.12962 0.081269 0.098875 0.13312 0.019775 0.093859 0.13799 0.066917 0.12089 0.14025 0.057053 -0.021536 -0.11202 -0.15134 0.012022 0.0008462 0.18794 -0.022936 0.12724 0.14248 -0.015237 -0.075361 0.15065 0.11984 0.16618 -0.35692 -0.2474 0.091957 0.042723 0.21117 -0.072008 -0.064827 0.39984 0.27504 0.26081 0.036257 -0.00092725 0.097138 0.11537 -0.087621 0.14525 0.19174 -0.030003 0.21575 0.032843 -0.28628 0.0061119 -0.10856 0.040474 -0.12915 -0.15099 -0.30803 0.00945 0.18243 -0.071865 0.094051 +for -0.043457 0.11336 -0.090211 0.10783 -0.12458 0.010564 -0.053752 0.040688 -0.071978 0.12988 0.18367 -0.19067 0.23183 0.2526 0.1769 -0.067999 -0.032019 -0.091964 0.135 0.14054 0.11034 0.21687 -0.072976 -0.15426 -0.03326 0.026052 0.16755 0.030611 -0.11283 0.088465 -0.29436 -0.017995 -0.18437 0.086588 0.20259 -0.092321 0.046651 -0.10229 0.071462 0.069793 -0.13052 -0.014411 -0.056368 0.15818 -0.020047 -0.10617 0.23458 0.0035062 -0.14388 -0.018622 -0.069637 -0.2153 -0.11409 -0.10171 0.029783 -0.04675 0.20507 0.0067837 -0.13647 0.0070587 0.04308 -0.097742 0.33185 -0.24975 0.11143 0.027497 -0.020893 -0.15535 -0.20601 -0.0264 -0.11679 -0.041209 0.052129 -0.14148 -0.24781 -0.046432 0.30543 0.049252 0.17925 -0.048079 0.080292 0.27301 -0.14418 0.021085 0.013487 -0.24578 -0.25759 0.026981 -0.22953 -0.151 -0.12973 -0.046898 0.36185 -0.21275 -0.028743 0.22011 -0.10697 0.035381 -0.24997 -0.12608 0.020057 -0.24323 0.41437 -0.1849 -0.20688 0.18755 -0.1481 0.19374 -0.23983 -0.072315 0.050876 -0.068533 -0.23756 -0.066878 0.02785 -0.10642 0.065645 -0.12159 0.01709 0.0073716 0.25959 0.26045 0.050632 0.33932 0.060457 0.082843 0.20087 -0.0074604 0.035756 0.22386 0.097792 0.25052 -0.30139 0.085823 0.023561 0.067157 -0.10683 -0.20434 0.021773 0.13849 0.08889 0.064833 0.24942 -0.12314 0.21898 0.092902 -0.066623 0.004371 0.10442 -0.011684 -0.18587 -0.15274 -0.1052 0.056705 -0.077613 -0.098058 0.08235 -0.19676 0.073493 -0.16567 -0.12771 0.068033 -0.050141 -0.0066839 0.22982 -0.0097502 0.01318 -0.17115 -0.085712 -0.094221 -0.21663 -0.18938 -0.15326 -0.064401 -0.12948 0.12967 -0.04457 0.16996 -0.11774 -0.29034 -0.135 -0.13239 -0.020521 0.069121 -0.35345 0.041462 -0.054732 0.082544 -0.030277 -0.023645 -0.0077702 -0.21236 0.19582 0.021462 0.013873 -0.12292 0.0091213 -0.036776 -0.077845 0.21115 -0.20513 0.0020311 -0.062409 -0.086912 -0.070559 0.1628 -0.15556 0.051623 0.32346 0.085333 0.27287 0.0054348 -0.082055 -0.15807 0.12814 -0.017721 0.022306 -0.15821 -0.020882 0.0038859 -0.037751 -0.053051 0.043165 -0.22103 -0.037925 0.20364 0.0069072 -0.019936 -0.014179 -0.080207 0.060495 0.22816 -0.32799 -0.26871 -0.054558 0.1814 0.0098955 -0.055567 -0.099914 0.057165 0.13378 0.12753 0.034018 0.084181 0.17292 0.26984 0.19024 -0.095838 -0.048268 0.26195 0.026921 -0.058127 -0.035345 0.14691 0.09446 0.1235 -0.32641 -0.10359 0.057579 0.1355 0.034544 0.16175 0.13866 0.077932 -0.090037 0.085698 -0.076063 -0.10881 -0.079184 -0.025822 -0.31328 -0.035864 -0.11864 -0.028462 -0.22913 -0.09151 0.066334 0.30559 0.050003 -0.030793 0.24058 0.056887 0.043921 0.13876 0.11531 -0.0049904 -0.0093994 0.1054 -0.18862 0.24032 0.071652 -0.052628 0.093925 0.0019137 -0.053472 -0.23075 0.14242 0.11643 0.090122 -0.067711 +as -0.10668 -0.036518 -0.1063 0.063468 0.11089 0.056798 0.19817 -0.00047669 0.1151 0.12766 0.025721 -0.096167 0.084847 -0.20034 0.16011 -0.13566 0.12913 -0.036482 -0.0013579 0.0052643 -0.18697 0.15282 -0.085003 -0.16923 -0.045447 -0.031521 -0.042384 -0.11903 -0.053743 0.0077491 -0.10079 -0.0014938 -0.23998 0.20515 -0.023961 0.03907 -0.050253 0.013688 0.07491 -0.31991 -0.079342 0.14457 -0.15161 0.0047635 -0.095498 -0.12307 -0.085301 0.25123 0.27485 -0.022108 -0.038877 0.083706 -0.02285 0.079031 -0.084699 -0.015823 0.030432 0.0046942 -0.23436 0.2158 0.042915 -0.16513 0.078436 -0.2917 -0.021577 -0.045501 0.0078394 -0.19502 -0.1083 -0.01386 -0.25153 -0.036888 -0.038306 -0.21965 -0.016194 -0.1347 0.12681 0.11563 0.20419 -0.10326 0.26979 0.040638 -0.079217 -0.1489 0.039404 -0.18841 -0.081222 0.20854 -0.42372 -0.092842 0.02847 -0.064213 0.12222 -0.086276 0.16448 -0.029391 -0.089828 0.12399 -0.2145 0.059643 0.016001 -0.27254 0.17223 -0.05487 -0.04919 -0.0075199 -0.089158 -0.0049213 0.10274 -0.21427 0.019886 -0.10638 -0.22215 -0.027423 0.08864 -0.013108 0.16812 0.058269 -0.029014 -0.13752 0.20446 0.16461 -0.25531 0.24799 -0.17534 -0.1073 0.12386 0.16596 -0.025096 0.060844 -0.06466 0.13571 -0.035465 0.084584 0.11602 0.12394 -0.1146 0.009226 0.024469 0.21552 -0.086623 0.058701 -0.03065 -0.11282 0.21441 0.20956 -0.053683 0.17708 -0.040871 -0.068884 -0.039507 -0.082237 0.026662 0.002197 -0.17169 0.17174 -0.17123 0.0026961 0.32867 0.11802 -0.20242 0.064288 -0.27296 0.17342 0.10837 -0.19019 -0.088144 -0.31898 0.13042 0.25379 -0.18172 -0.003441 -0.2074 -0.17084 -0.18809 -0.067014 -0.0077843 0.12018 0.055609 0.062902 0.051946 0.032556 0.064706 0.16043 0.010894 0.26701 0.15682 -0.19018 0.17844 0.037642 -0.094117 -0.2792 0.0062504 0.20934 0.15969 -0.005166 0.029639 -0.034127 -0.15754 0.08945 -0.12987 0.15607 -0.0063243 0.15625 0.17861 -0.12055 -0.20331 0.19912 0.084713 0.10501 0.52838 -0.076569 -0.10239 0.11299 -0.029849 -0.077256 0.063675 -0.20756 -0.06305 -0.042499 -0.041598 0.02283 -0.21428 0.046132 -0.050075 -0.22019 -0.021104 -0.064426 0.014369 0.058189 0.20217 0.11436 -0.072824 -0.12266 -0.20333 0.27137 0.13923 0.055401 -0.0066487 -0.0019663 0.14431 0.16829 -0.066634 0.20795 0.13077 0.081666 0.076304 -0.14139 0.025815 0.020766 0.152 0.019461 -0.079617 0.11885 -0.032576 0.12693 -0.15425 -0.19208 -0.089979 -0.18192 -0.076191 0.096308 0.084752 -0.077118 -0.15407 -0.40903 -0.2408 0.27727 0.070015 -0.23642 -0.26462 0.09025 -0.083525 -0.055758 -0.0044354 -0.18702 0.34108 0.17177 0.039009 0.014808 0.20067 0.014752 0.03399 0.046347 -0.055452 -0.04778 -0.0083971 0.29187 0.2087 0.04187 -0.085302 0.017596 0.038921 -0.042198 -0.11009 -0.11966 -0.032105 -0.0087815 -5.7399e-05 0.13576 +by -0.13167 -0.040817 -0.23956 0.23064 -0.12696 0.11678 0.10581 -0.20413 0.0080369 0.23646 -0.054108 0.12133 -0.15008 0.11509 0.11896 -0.25209 0.10367 -0.065059 -0.080371 0.12708 -0.014658 0.2269 -0.28552 -0.096679 0.063329 -0.033706 0.01759 0.028157 0.15469 0.033508 -0.23307 0.091283 0.023145 0.13172 0.2012 -0.080005 -0.25302 0.003297 0.23424 -0.094455 0.065775 -0.0028773 0.00034232 0.19717 0.033452 -0.20442 0.0010543 -0.010863 -0.15341 0.065852 0.12561 -0.040625 -0.27178 -0.024283 0.080334 0.022827 -0.097376 0.18855 0.011054 0.038045 -0.02144 -0.21974 0.0035103 0.20461 -0.0075506 0.16733 -0.10361 -0.18865 0.031286 -0.081821 -0.11796 -0.0090501 -0.16731 -0.27503 0.047636 -0.033096 0.11845 0.14352 0.15145 -0.047157 -0.099036 0.042062 0.17922 0.22662 -0.081016 -0.066303 -0.19108 0.092628 0.0024941 -0.065267 -0.14996 -0.11355 -0.078145 -0.13441 0.29873 -0.060622 0.1054 -0.11155 0.026942 0.048895 -0.10103 -0.010862 0.24963 -0.087945 -0.099125 -0.1148 0.1452 -0.11545 0.33225 -0.14523 0.077605 -0.099609 -0.068166 -0.050334 0.049693 0.17082 0.283 0.3763 0.0020146 0.14755 0.07047 0.31503 -0.47475 0.38828 0.058978 0.0626 0.14044 0.1298 0.12159 0.1261 0.19995 0.23574 0.13194 0.25251 0.37902 -0.0049426 0.10706 -0.016369 -0.12881 0.04987 0.25352 0.12318 0.17736 -0.20315 -0.21117 0.099453 0.017912 0.019938 -0.015746 0.20934 0.071116 -0.1477 -0.14592 -0.11236 -0.094642 -0.16884 -0.16842 -0.072051 0.17637 0.101 -0.10587 -0.086128 0.024187 0.011435 0.3069 -0.071507 0.17903 0.11991 0.28315 -0.0010412 -0.18539 0.19078 -0.093839 0.061669 -0.10506 -0.028498 0.01504 0.17677 -0.0046986 -0.1237 -0.11957 -0.33566 -0.35805 0.17801 0.09083 0.21286 0.013965 -0.28891 0.056233 0.021966 -0.094326 -0.36791 0.23437 -0.082501 0.13699 -0.41778 -0.21958 -0.10984 -0.16532 0.032684 0.087233 0.2412 -0.21436 0.019845 -0.063727 -0.073478 -0.21645 0.20205 0.21141 -0.03102 0.573 -0.032144 0.039847 -0.05959 -0.0036714 0.070425 0.15985 0.031499 -0.18282 -0.036042 -0.01486 -0.39543 -0.40932 -0.027014 -0.042265 -0.047627 -0.28248 -0.19428 -0.019236 0.24395 -0.21907 0.011405 -0.12631 0.14487 -0.036576 -0.062648 -0.0084789 0.076445 -0.005565 -0.12415 -0.07852 -0.14686 0.12963 -0.11216 -0.0012184 0.027598 0.017539 -0.2169 0.15463 0.14615 0.12645 0.0058155 0.1358 -0.22443 -0.21958 0.2109 -0.0985 -0.066894 -0.17394 0.017303 0.19829 -0.098625 -0.03713 -0.044018 -0.23748 -0.21127 -0.023497 -0.13315 0.011752 0.001701 -0.15698 0.078147 0.027263 -0.17181 -0.15723 -0.23723 0.22997 0.35097 0.092508 -0.021858 0.00041802 0.129 -0.028015 0.031211 -0.067224 0.087442 -0.027041 0.24614 -0.17322 -0.036277 0.32144 -0.23934 0.13895 -0.014339 -0.068493 -0.066417 0.18929 0.32907 -0.11879 0.0031042 +that -0.23983 0.085832 -0.21831 0.19241 0.025195 0.12355 -0.0069764 -0.17742 -0.02976 0.14019 -0.04131 0.021693 0.031669 -0.066504 -0.010106 -0.039781 0.058352 0.077962 0.10951 0.17083 0.030571 0.075172 -0.19127 -0.26914 -0.07159 -0.0033303 0.16572 0.2414 -0.037835 0.092986 -0.096324 -0.053362 -0.13769 0.2023 0.12228 0.0055089 -0.12261 0.065976 -0.093829 -0.0047912 0.060502 0.034472 -0.089815 0.049682 0.10915 0.19243 0.097466 -0.059112 -0.031561 0.0085642 -0.0097376 -0.1566 -0.030448 -0.03733 -0.21254 0.016531 -0.10968 0.14795 -0.0080269 0.06314 -0.17479 -0.080141 0.16124 -0.071978 0.12406 -0.26999 -0.17197 -0.058859 0.046186 -0.07601 -0.074253 -0.039888 0.057741 -0.19435 -0.10719 0.075766 0.16442 0.062963 0.016998 0.098074 0.051912 0.00796 0.049767 0.074819 -0.16363 0.067474 -0.10452 0.073557 -0.10755 -0.1425 0.089114 0.15841 0.3222 -0.10655 0.083618 -0.092492 0.21919 0.048208 -0.061488 0.049201 -0.062859 -0.13971 0.059256 -0.11582 -0.21935 -0.13681 -0.11235 -0.096347 0.046857 0.035071 -0.11585 -0.023621 0.080661 0.028493 0.06903 -0.18985 0.26623 0.17579 -0.035073 -0.031638 -0.026218 0.14236 0.039761 0.38528 0.038298 -0.010169 0.11729 0.11932 -0.050962 0.22691 -0.17552 0.016449 -0.046997 -0.083699 0.069625 0.014247 -0.10832 0.12289 0.016072 -0.033899 0.10722 0.20054 0.1402 -0.10011 -0.07931 0.12327 -0.0031444 -0.089443 -0.086052 -0.10393 0.032676 -0.14476 -0.056825 -0.034722 -0.095045 -0.17064 -0.035918 0.086298 0.17825 0.063758 -0.12496 0.21052 -0.28584 0.15253 0.13151 0.076388 0.029637 -0.093604 0.12136 0.019785 -0.11168 -0.14822 -0.27724 -0.02827 -0.09676 0.14834 -0.13155 0.19224 -0.017957 -0.10059 0.10913 -0.1554 0.0051412 0.24523 -0.21236 0.11514 0.083901 -0.097453 0.21907 -0.18487 0.024778 -0.35162 0.13614 0.13062 -0.086043 -0.023898 0.060116 -0.0034988 -0.2956 -0.055491 0.19128 0.096245 0.044102 0.097388 -0.073929 -0.13039 -0.063722 -0.0042311 0.10625 0.035973 0.30975 -0.037181 0.15494 -0.065034 0.19122 -0.0046243 -0.024803 -0.21901 0.012198 0.18168 -0.21881 -0.15599 0.026207 0.038486 -0.20256 -0.030282 -0.18647 0.049986 -0.18815 0.018358 0.20436 0.072241 -0.034569 0.056817 0.027542 0.19926 0.18312 -0.070488 0.23106 0.01389 0.0459 -0.070822 0.10671 -0.049261 -0.13885 0.20777 0.12232 0.092241 0.0088502 -0.058793 0.19882 0.19537 -0.15112 -0.017619 -0.040276 0.028941 0.039263 -0.0551 -0.008233 -0.11584 0.081303 -0.0047339 -0.085726 -0.14999 -0.094978 -0.13686 -0.1508 0.12912 -0.12408 -0.11013 -0.18316 -0.050477 0.25119 0.14707 -0.15924 -0.12625 0.19323 0.066352 0.14201 -0.032837 0.04996 -0.063273 0.115 -0.28184 -0.005338 -0.062189 0.067656 0.23157 -0.047256 0.03623 0.17711 0.044209 0.057874 0.031027 0.034118 -0.22109 -0.11154 0.2051 0.061947 -0.15744 +it -0.3366 0.13889 -0.068331 0.0079146 -0.020023 0.093429 0.10182 -0.2151 -0.18844 0.15148 -0.14284 -0.11377 0.11161 -0.23444 0.028262 -0.062042 0.21756 0.095647 0.1698 0.071679 -0.054375 -0.046085 -0.21987 -0.27494 -0.25339 -0.10972 -0.0070419 0.03357 0.12896 0.18848 -0.25815 0.17061 -0.38947 0.3481 -0.041047 -0.12456 -0.086325 -0.19126 0.022593 -0.12725 -0.13036 0.098136 -0.2339 0.008161 0.18667 0.20999 0.063713 -0.028508 -0.054716 -0.11117 -0.010525 0.0070143 -0.0041469 -0.036819 -0.0036929 0.078406 0.0038262 0.26416 -0.06283 0.22119 0.062652 -0.14575 0.18947 -0.098799 -0.038427 -0.24093 -0.10867 -0.089518 0.12916 0.059777 -0.015123 0.14633 0.032212 -0.15511 -0.17298 0.08858 -0.081538 0.27585 -0.040939 0.15529 -0.083451 -0.070103 0.1548 0.19894 -0.094732 0.11057 -0.18328 0.00019708 0.032517 -0.076038 0.051504 0.18083 0.25092 -0.15933 0.1487 0.12631 0.15929 0.17724 0.013187 -0.0839 -0.22055 -0.01915 0.1156 -0.010974 -0.12785 -0.19002 -0.22735 0.013581 0.10532 0.053416 -0.03142 0.04568 -0.079156 0.075019 -0.19182 -0.040826 0.34173 0.17852 0.10964 0.0099851 0.2074 0.10894 -0.17686 0.47952 0.15701 0.11366 0.15475 0.098568 0.090232 0.18289 -0.062892 0.012882 -0.11289 0.047716 0.043811 0.0065159 0.032541 0.28292 0.061777 0.17045 0.047034 0.17219 0.10032 0.11206 -0.019359 0.070779 -0.024869 0.036909 -0.08589 0.18344 0.10946 -0.05685 0.096464 -0.16475 -0.055801 -0.15339 0.073 -0.081217 0.23755 0.069371 -0.16822 0.22798 -0.37593 0.034761 0.15086 0.031813 -0.069746 -0.08961 0.12988 -0.012923 -0.024002 -0.25414 -0.19594 -0.15103 -0.21644 0.045066 -0.16032 0.0044476 0.1035 0.14202 0.18504 0.0066014 0.13737 0.13789 -0.043577 0.032058 0.068189 -0.14007 0.10683 -0.0096826 -0.043681 -0.16244 0.11275 0.3178 -0.070198 0.11798 0.19411 0.026728 -0.29832 0.11729 0.064688 0.07844 -0.059657 0.21912 -0.013091 -0.2641 -0.10992 0.12463 0.13129 0.066074 0.18305 0.10516 0.15296 0.040073 0.16806 0.043346 0.038122 -0.21098 0.072374 0.10674 -0.057004 -0.16355 -0.0067051 -0.13049 0.24781 -0.083042 -0.24073 -0.11134 -0.0094638 0.098692 0.20597 0.17607 -0.20891 0.0030144 -0.12683 0.087142 -0.036535 -0.14635 -0.11332 0.043924 -0.023122 -0.041063 0.2974 -0.16771 0.13906 0.13147 0.17896 -0.017101 0.052858 -0.059781 0.11522 0.2598 -0.18943 -0.062224 0.034479 0.0072344 0.078014 -0.15113 0.17729 -0.11423 0.087861 0.078173 -0.11313 -0.19613 -0.051441 -0.037768 -0.15843 0.24705 -0.00826 -0.31003 -0.34136 0.10744 -0.024086 0.081787 -0.0024878 -0.23679 0.21343 0.18235 0.10686 -0.22907 0.18638 0.015871 -0.24017 -0.20794 0.062498 -0.28062 0.052488 0.14059 0.0051189 -0.048301 0.14975 -0.060221 -0.063074 -0.077547 0.045633 -0.15038 -0.026861 0.14517 0.029054 0.074989 +with -0.064206 0.091714 0.11942 0.4186 0.17465 0.11941 0.31859 -0.1638 0.20565 0.088094 -0.046213 0.15331 0.15775 -0.096504 0.022727 -0.14138 0.0098457 -0.026588 0.021183 0.22972 0.042529 0.027243 0.023137 -0.079872 0.0495 -0.061129 0.10546 0.084905 -0.1019 0.025445 -0.22593 -0.0094519 -0.11316 -0.045476 -0.09911 0.0020657 -0.244 -0.20762 0.27893 -0.030601 0.25438 -0.0434 0.141 0.04117 -0.026832 -0.075766 0.099866 -0.10857 0.052744 -0.0064439 0.014667 0.024091 -0.14823 -0.07514 -0.17639 0.0059049 0.0069194 -0.053316 -0.11206 -0.060583 -0.012822 -0.31799 0.087898 -0.062417 0.048166 -0.0059139 -0.018073 0.23661 -0.1531 0.0032921 -0.12837 0.075429 -0.19725 -0.24712 -0.050858 0.10058 0.12841 0.25282 0.097276 0.010521 0.18361 -0.19749 -0.040444 -0.11185 -0.12698 -0.10152 0.027053 0.095504 0.14746 -0.19452 0.055156 -0.15004 -0.039678 -0.039796 0.34592 0.29379 0.24519 -0.099354 0.060815 -0.26003 -0.061743 -0.05527 0.11014 0.11766 -0.21546 -0.15467 -0.091975 0.11697 0.012867 0.046272 0.03336 0.037781 0.019891 -0.064189 0.07923 -0.12147 -0.021964 0.058927 0.039117 0.28289 0.22152 -0.097244 -0.25084 0.35717 0.14103 -0.091674 0.1179 -0.017291 0.0098494 0.2756 0.15504 0.0081984 -0.24424 0.13351 -0.04132 0.040733 0.17727 0.069788 0.10178 0.1053 -0.14727 0.20263 -0.059392 -0.028766 0.063491 0.18252 -0.0014041 0.10274 -0.16481 -0.066712 0.13842 -0.27265 -0.19634 -0.1605 -0.074205 0.0018183 0.1026 -0.043547 -0.0072141 0.055306 -0.014692 0.22269 -0.012514 0.19233 0.021866 -0.11755 0.040916 -0.1911 0.094486 -0.11347 -0.0054213 -0.1179 -0.15947 0.15329 -0.15299 0.093003 0.0057173 0.24517 -0.22961 -0.10959 0.17229 -0.18358 -0.012696 0.058318 0.040257 0.31104 0.10125 -0.1034 0.086398 -0.051279 0.23686 -0.17961 0.20681 -0.076107 -0.0010114 0.055693 -0.15005 0.19155 -0.26852 -0.0636 0.14674 -0.084562 0.1201 -0.016069 0.15589 0.032152 -0.19939 -0.10605 0.28825 0.29976 0.080001 -0.028872 -0.15065 -0.14277 -0.080955 -0.073138 -0.11025 -0.32096 -0.16664 -0.02429 -0.15989 -0.093246 -0.10673 0.21227 0.058826 -0.040371 -0.15165 0.12092 0.025799 0.13896 0.14107 -0.034768 -0.098782 -0.037076 -0.1742 0.15468 0.20271 -0.2016 0.0056756 0.22209 0.065569 -0.04823 -0.0019982 0.27749 0.053513 0.16785 -0.072915 -0.025025 -0.03041 0.10037 -0.084707 -0.15251 -0.045538 -0.076732 -0.18076 0.019518 -0.29083 -0.18053 -0.053213 0.034254 0.28543 0.19922 0.24063 -0.01772 -0.017605 0.24474 -0.010969 0.14306 0.06392 0.074019 -0.12698 -0.067713 0.029559 0.025171 -0.2451 -0.046625 0.14576 0.19015 0.22647 0.18612 0.087883 0.02785 0.28477 -0.050063 0.16087 -0.043498 0.075641 0.4027 -0.038456 0.19304 0.063723 -0.35619 0.17587 0.22165 0.075605 -0.055085 -0.030707 0.088356 -0.015983 -0.25735 +from 0.074123 -0.24449 -0.20993 0.067707 -0.069055 0.02407 0.039651 -0.075543 0.14965 0.22772 0.23997 -0.15625 -0.13645 -0.16233 -0.136 -0.047394 -0.22722 -0.020578 0.21853 -0.057743 -0.2538 0.07426 -0.4313 0.070787 -0.13236 0.0090762 0.041375 -0.17293 -0.13688 0.047738 -0.096345 0.35734 -0.064074 0.315 0.043262 -0.039828 0.26392 -0.0077835 0.1246 -0.062125 0.049646 -0.19449 -0.10296 -0.13227 0.11914 0.11471 0.19222 -0.10544 0.19141 -0.19164 0.16664 -0.072087 -0.017124 -0.024085 -0.054923 0.18161 -0.41752 0.013846 -0.097548 0.14298 0.18272 -0.095173 0.25565 -0.0038474 -0.065212 -0.0097115 -0.51114 0.24172 -0.084955 -0.10739 -0.22902 0.0097627 0.1284 -0.12305 -0.072091 0.12597 0.22261 0.12579 0.1523 0.060826 0.037958 -0.012942 -0.090394 -0.0034238 0.074824 0.13059 -0.24917 0.060374 -0.20008 0.2994 0.025893 -0.10789 0.092428 -0.0028567 -0.19491 0.23134 -0.028209 0.2477 0.15212 -0.08654 0.035328 -0.057431 0.14291 -0.034993 -0.093676 -0.21335 -0.41108 -0.16943 -0.044907 0.10779 0.24495 -0.0034135 -0.16304 0.037063 -0.058801 0.079125 0.25461 0.16792 -0.10822 0.078622 0.31237 0.021625 -0.1846 0.31997 -0.21529 0.019935 0.22055 0.14881 0.31108 0.13899 0.17772 0.054332 0.08957 0.24212 0.11923 0.062396 -0.049008 -0.21631 -0.2272 -0.053169 0.059956 0.002439 0.20858 0.09573 -0.054505 0.23263 0.16189 -0.061374 0.036911 -0.02273 -0.079022 -0.31311 -0.081871 -0.025641 -0.22911 -0.41586 -0.076673 0.043928 0.0073082 -0.030566 -0.19267 0.12633 -0.24819 -0.020164 0.3443 -0.034356 6.2081e-05 -0.072091 0.32803 -0.28308 -0.2078 0.028662 -0.3094 0.076138 -0.085894 0.29858 -0.012965 -0.052991 -0.14979 -0.04495 0.073995 -0.16588 -0.28257 0.19357 0.040774 0.13921 0.11749 0.029632 0.029503 0.025321 -0.039398 -0.087089 0.31311 0.14639 -0.10493 0.073549 -0.097152 0.22761 -0.17507 -0.21137 -0.19015 -0.11867 -0.31333 -0.039106 -0.18574 0.1103 0.049186 0.21492 -0.23672 0.28303 0.10399 -0.11652 0.07139 -0.013092 -0.11487 -0.16952 0.11821 -0.16995 -0.025376 0.02897 -0.011382 0.0089853 -0.10031 0.19524 -0.26482 -0.11916 -0.23742 -0.29037 0.077017 0.13313 0.18052 0.33469 -0.18892 0.056997 -0.22412 0.057391 -0.092851 -0.073241 -0.066436 -0.097719 -0.026805 0.057282 0.15477 0.040247 -0.15614 0.035466 -0.05528 -0.0016932 0.15164 0.14045 0.022603 -0.024509 -0.029928 -0.024789 -0.23132 -0.0048805 -0.0991 0.021038 -0.15909 0.20374 -0.12693 0.13554 0.3949 0.00044854 -0.28062 -0.1417 0.031939 0.023403 -0.034906 -0.094262 -0.12416 -0.20251 -0.10164 -0.058665 -0.020256 0.051373 0.22868 0.20847 0.20915 -0.07355 0.23702 -0.072579 -0.0068663 -0.049043 0.18509 -0.21591 -0.10739 -0.0068317 0.09578 0.070574 0.069152 -0.026582 0.087377 0.14222 0.044832 0.068534 -0.17147 0.097198 -0.36452 -0.081744 +at 0.084657 -0.22584 0.096451 0.10084 -0.32227 0.06084 -0.14098 0.042526 0.25177 -0.15139 0.28946 -0.22224 0.14715 0.21937 0.017641 -0.075882 -0.054542 -0.019967 0.023136 0.34317 0.19269 0.06061 -0.41196 -0.14237 -0.11288 -0.19504 0.10921 -0.065239 0.17814 0.22521 -0.14425 0.19108 -0.051249 0.3514 -0.033516 -0.10391 -0.15866 -0.04648 0.26894 -0.054653 0.026268 0.024519 -0.153 0.0089207 -0.10311 -0.061886 -0.076662 0.16422 0.19202 -0.15849 -0.10444 -0.32162 -0.017646 0.19714 0.063879 0.15029 0.27939 0.20403 -0.11719 0.11302 0.21741 -0.23783 0.22149 -0.099384 -0.15909 -0.23008 -0.16896 0.048093 -0.34688 0.077259 -0.26626 -0.16247 0.053485 -0.0649 0.017268 -0.16991 0.18329 0.20681 -0.078363 -0.19282 0.10032 0.23402 0.21734 0.16295 0.056857 -0.071505 -0.11856 0.065202 -0.0071105 -0.065222 -0.029953 0.051816 0.4249 -0.18516 0.1631 0.068751 0.24889 0.0087197 -0.16567 0.097582 0.097659 -0.052475 0.14066 0.092822 -0.063293 -0.10292 -0.26192 0.14551 0.084639 0.069376 0.217 -0.079723 0.096226 -0.2802 -0.088477 -0.12311 0.30153 -0.087612 0.026935 0.029043 0.44256 0.079062 -0.027775 0.12976 0.065664 0.098004 0.26257 -0.060456 -0.076672 -0.029265 0.079762 0.052325 0.089596 0.070077 -0.20729 -0.11461 0.2513 0.068273 0.046419 -0.021613 -0.094778 -0.011309 0.065823 -0.037588 0.21715 0.076541 0.069592 -0.12947 0.078394 0.19481 0.066025 -0.32922 0.12043 -0.054116 -0.043916 -0.40659 0.13175 0.042698 0.12824 0.36509 0.01419 0.28955 -0.14103 0.14471 0.17529 0.26788 -0.19957 0.07221 0.053943 -0.20463 -0.27569 -0.045307 -0.40483 0.1223 -0.073105 0.11057 -0.19826 0.29006 -0.19438 -0.27404 0.0019843 0.068304 -0.17825 -0.13397 -0.11317 -0.082058 -0.13167 -0.017088 0.060193 -0.2828 -0.10857 0.085549 -0.10687 0.19298 -0.064046 0.039204 -0.071963 0.0143 -0.18933 -0.23111 0.092391 -0.0045494 0.078846 0.10808 -0.13525 -0.021385 0.17449 0.040101 0.21758 0.42214 0.28144 -0.13084 0.092562 -0.025293 -0.2081 -0.015357 -0.30071 -0.0070475 -0.0086043 0.043435 0.13337 0.055808 -0.10396 0.0426 -0.19165 -0.05732 -0.20715 -0.025886 0.038309 0.041086 0.23983 -0.033461 0.035933 0.11489 0.17574 0.036294 -0.034195 0.13229 -0.15982 -0.0012274 0.14255 -0.025759 0.15796 0.1358 -0.065825 0.19361 0.22163 0.12749 0.13667 0.28978 0.19074 -0.13526 -0.14296 0.033069 -0.52474 -0.080285 -0.21442 -0.282 -0.142 0.24223 -0.083328 0.016296 0.036034 0.23413 0.016184 -0.001913 -0.19888 0.078624 0.024006 0.1797 -0.12137 0.20834 -0.35337 -0.020637 -0.1018 -0.14994 0.39498 0.25541 0.17832 0.072025 0.11042 0.19179 0.068597 -0.0062475 0.087407 0.048029 0.24316 -0.10581 0.033797 -0.098828 0.11308 -0.40658 0.00030372 0.005122 0.032004 0.043654 -0.2884 0.046729 -0.094621 0.20779 +he 0.014665 -0.26812 -0.052296 0.23006 0.031144 0.1326 0.15627 -0.035684 -0.068791 0.37745 0.26 0.065356 0.10545 -0.083843 0.0068441 -0.35062 0.087274 -0.084536 -0.079793 0.14406 -0.099383 0.22698 -0.25031 -0.34414 0.032567 0.20315 0.23225 -0.18451 -0.1058 0.1287 -0.20596 0.055626 -0.18326 0.16372 0.0017453 -0.26181 0.015642 -0.21012 -0.098568 -0.027856 0.0090502 0.15216 -0.14542 -0.060665 -0.012078 -0.10709 -0.025372 0.2335 -0.1346 0.043417 0.040352 -0.13142 -0.10796 0.14868 -0.24327 -0.21122 0.055215 0.2452 0.11917 0.1849 -0.15568 0.027578 0.11264 -0.039423 0.045282 -0.25581 -0.15215 0.24204 -0.17778 -0.020735 -0.11384 -0.18628 0.11145 -0.077367 0.027016 -0.092138 0.21866 0.1661 -0.23244 -0.12927 0.21804 0.06546 0.14573 -0.022755 -0.12254 0.016283 -0.29042 -0.10536 -0.13048 -0.21748 0.088834 -0.35676 0.43895 -0.13208 -0.043485 0.20868 0.040794 0.050524 -0.26054 -0.25543 -0.037681 0.0021933 0.2289 0.12642 -0.12268 -0.021991 -0.13756 -0.12565 -0.016195 -0.030606 0.0046082 -0.24541 -0.002142 0.10537 -0.28513 -0.28361 0.26544 0.17673 -0.19454 -0.092296 0.023453 0.20037 0.051594 0.31713 0.013278 0.01814 0.15886 0.14062 0.0089156 0.11651 -0.21173 0.13483 -0.14015 -0.35175 -0.33749 0.0063774 0.010142 0.02523 -0.21273 -0.053858 -0.04604 -0.014979 0.071772 -0.10722 0.047265 0.17662 0.035781 -0.27281 0.0095576 0.093047 0.042057 -0.12991 -0.038015 0.19335 -0.44323 0.079033 -0.15394 -0.10119 0.151 -0.010138 -0.2738 0.34338 -0.22604 0.28772 0.11076 0.050212 -0.028319 -0.15248 0.26818 -0.086068 0.077829 0.074144 -0.12604 0.0096369 -0.063531 0.24053 -0.11003 0.16175 -0.10464 -0.15088 0.17058 0.082295 -0.14244 0.21725 -0.16858 0.20828 0.033688 0.075818 -0.025683 0.084218 0.0021424 0.032686 0.025107 0.31271 -0.22352 -0.14049 -0.0022511 0.11708 -0.30667 -0.064557 0.21376 -0.065726 -0.17451 0.22245 -0.049137 -0.019059 0.041286 0.10033 0.20715 0.14142 0.17575 -0.0085873 -0.029827 0.053633 0.065397 0.082936 -0.074867 -0.22161 0.029769 0.088741 -0.12474 -0.017533 -0.016169 -0.13967 -0.1801 -0.0185 -0.12567 -0.16774 -0.0074254 0.067426 0.26623 0.23513 -0.16071 -0.16117 0.10872 0.0067142 0.028955 -0.026827 0.0024487 -0.11155 -0.086587 -0.14739 0.12836 0.38225 -0.24315 -0.021359 0.19199 -0.22529 -0.12179 0.078892 -0.095018 -0.20916 -0.059001 -0.055153 -0.22721 -0.033763 -0.21755 0.0082018 0.24165 -0.10292 0.084843 0.13294 0.17828 -0.32875 -0.13609 -0.052415 0.025926 -0.026822 0.1133 -0.17822 -0.30246 -0.083471 -0.28678 -0.01545 -0.19332 -0.3002 0.16762 -0.020979 0.076648 -0.13527 0.082477 0.068317 -0.063771 -0.06968 -0.10251 -0.015942 0.098454 0.15689 0.0030096 -0.12414 0.036338 -0.23409 0.017694 -0.054863 0.073746 0.055707 -0.20249 0.15422 -0.077715 0.22867 +this -0.19964 0.085116 -0.055189 0.13142 -0.034263 0.11687 0.024297 -0.36591 -0.16021 0.13041 -0.051105 -0.19426 0.12888 -0.13138 0.051647 0.02113 -0.14945 0.118 0.26445 0.21531 0.059788 0.14565 -0.13513 -0.082425 -0.30358 0.13601 -0.15623 0.077483 0.22425 0.22971 -0.14523 0.20617 -0.19068 0.13975 -0.067428 -0.039962 -0.011683 -0.029614 -0.19031 -0.17548 -0.026692 -0.10578 -0.11332 0.13866 -0.041102 0.12785 0.084305 -0.16118 0.022081 -0.036854 -0.050079 -0.037985 0.069227 -0.10608 -0.036044 0.28917 0.039558 0.096326 0.14466 -0.013434 -0.091264 -0.040229 0.35294 -0.33489 0.10616 -0.35523 -0.077932 -0.0050663 -0.079543 0.11814 -0.13492 -0.048151 0.13197 -0.26917 -0.18266 0.05242 0.14771 0.25209 -0.090966 0.062938 -0.15311 0.18472 0.044006 0.038439 0.05966 -0.20255 0.026222 0.024488 -0.016858 -0.27549 0.10334 0.10343 0.44464 -0.20755 0.02245 -0.072451 0.10391 0.13244 0.079197 -0.003736 -0.096508 0.035129 -0.011803 0.074741 -0.11641 -0.00064235 -0.15859 0.12314 -0.062408 0.1075 -0.051995 0.079683 -0.061127 0.026742 -0.11837 -0.074877 0.57404 0.066379 -0.053467 0.12976 0.12191 -0.065749 -0.10451 0.38098 0.085549 0.18503 0.044096 0.0056013 -0.00055242 0.29563 0.026896 0.15684 0.12214 0.10538 0.069068 0.21219 0.032334 -0.010033 0.07734 0.12691 -0.010455 0.057988 0.17236 -0.091861 0.039457 0.020577 -0.028288 0.15332 -0.083229 0.11851 0.060821 0.13223 0.14614 -0.2856 -0.014111 -0.23565 0.27903 0.032652 0.017968 0.18232 -0.12464 0.12322 -0.18978 0.030301 0.090686 0.08478 -0.063022 -0.12534 0.15142 -0.015543 -0.36105 -0.19801 -0.21259 -0.18934 0.033945 -0.13825 -0.039777 0.057215 -0.02898 -0.21503 0.081745 -0.064233 0.11149 0.39395 -0.056752 0.23975 0.17848 -0.16583 0.11568 -0.04708 -0.13793 -0.15936 0.27785 0.18192 -0.08966 -0.17054 0.024002 0.10111 -0.33998 -0.040697 0.17376 0.1586 0.10284 0.29167 0.062748 -0.15753 -0.16914 0.20502 -0.10835 -0.035556 0.21803 -0.068972 0.10176 0.0054727 0.33023 -0.20426 0.24388 -0.015076 -0.15243 0.14785 -0.1159 -0.15334 0.19533 -0.10903 0.18967 0.038244 -0.011186 -0.061208 -0.019259 -0.0065419 0.30863 0.09396 -0.15441 0.090379 -0.069162 0.037942 0.29172 -0.035638 0.050326 -0.26106 0.18763 0.084209 0.15093 0.00033666 -0.090248 0.15647 0.27421 0.28715 0.00017502 -0.039501 0.071631 0.11474 -0.15752 -0.046249 -0.14411 -0.20785 -0.1202 -0.29892 -0.071695 -0.12621 0.05428 0.22063 -0.38058 0.056328 0.08667 0.05431 -0.044359 -0.06605 -0.21377 -0.22255 -0.16978 -0.10923 0.25012 -0.025356 0.034712 -0.30406 -0.15446 0.013073 -0.16584 -0.17734 -0.090426 0.017501 0.039702 -0.27064 0.27928 -0.12816 0.024732 0.32566 -0.054112 0.035922 0.018636 -0.24873 -0.072194 -0.091842 -0.034728 -0.11994 -0.036952 0.37121 0.038292 0.13426 +be -0.25026 0.22369 -0.096314 -0.026401 -0.13472 -0.008982 0.065405 -0.47185 -0.051056 0.051511 -0.16824 -0.030949 0.055425 -0.12948 -0.0062735 0.1086 0.1216 0.12408 0.058992 -0.06763 -0.0083828 0.095009 -0.1021 -0.1037 -0.15302 0.021146 -0.036643 -0.040302 0.14088 0.15744 -0.0088583 0.027898 -0.1389 0.053186 -0.12304 -0.091924 -0.15491 0.28233 -4.7579e-05 -0.37132 -0.20302 0.0099404 -0.17615 0.065376 0.068181 0.05025 0.076486 0.070419 0.067646 -0.033892 0.014993 -0.3001 -0.1197 -0.072569 -0.078529 0.030499 -0.048392 0.25323 -0.37985 0.081339 -0.0005548 -0.17629 -0.025923 0.13305 0.0017028 -0.057541 -0.18037 0.06683 0.018062 0.036975 -0.31258 0.23392 0.028911 -0.30242 -0.11193 0.10407 0.20486 0.069179 0.17624 -0.19341 0.12059 -0.13434 0.2001 -0.13353 -0.14275 -0.099292 0.075853 0.09379 -0.32696 -0.3651 -0.092877 -0.10166 0.046329 -0.35481 -0.098609 0.080704 0.14017 0.21821 -0.087556 -0.028255 -0.033402 -0.12697 0.084909 -0.1059 0.062273 -0.13115 -0.20217 0.21356 -0.1352 0.064972 -0.0084728 -0.1492 -0.18754 0.23022 0.12852 -0.20356 0.27514 0.1692 -0.062528 0.17163 0.026962 0.20587 -0.29252 0.55029 0.17327 -0.053048 0.19823 0.17507 -0.059659 0.22113 -0.31647 0.034778 0.014308 0.36628 0.091454 0.13519 -0.021655 0.084731 -0.0080609 0.024732 -0.17821 -0.067393 0.10119 -0.16821 -0.11191 -0.086037 -0.14364 -0.10889 -0.099915 0.10719 0.056134 -0.017866 -0.0056781 -0.099943 -0.22417 -0.18912 -0.034503 0.057475 0.24023 0.099867 0.0049938 0.22043 -0.31164 -0.056913 -0.02007 0.093747 0.16696 -0.20301 0.090256 0.30012 -0.10868 -0.21016 -0.22773 -0.092926 -0.37742 0.07472 -0.12559 -0.025903 0.026878 -0.18513 0.016609 -0.17193 0.25518 0.29165 0.14476 0.19666 0.35115 0.023523 0.25183 0.084845 -0.15047 -0.47281 -0.10641 0.2948 0.038983 -0.25462 -0.00026834 -0.012001 -0.36371 0.17908 0.15783 0.044898 0.028195 0.015111 -0.039563 -0.2444 -0.21118 0.26483 0.36933 0.064294 0.31829 -0.14861 0.33797 0.22144 0.32405 -0.0056225 0.11812 -0.24185 -0.094248 0.22022 0.11795 -0.25267 -0.18225 -0.093763 -0.14506 0.023154 -0.22244 -0.042051 -0.064813 -0.11526 0.10159 0.19566 -0.12605 0.032872 -0.094309 0.216 0.18244 -0.22899 -0.015609 0.007531 0.16186 0.1413 0.27935 0.078345 -0.086286 0.089518 0.2332 -0.069231 0.10922 0.21872 0.1242 0.056511 -0.13227 -0.015025 0.14657 -0.023266 -0.039107 -0.24631 0.077292 -0.0051662 -0.034316 0.086529 -0.088394 0.14664 -0.32449 -0.16895 -0.32304 0.36483 -0.10341 -0.22328 -0.33559 0.0096681 0.015918 -0.071303 -0.1666 -0.27372 0.17971 -0.0099447 -0.053653 -0.11846 -0.10818 0.11709 -0.13894 -0.076176 0.011088 -0.21972 0.0033401 0.14299 -0.028053 0.13819 0.14463 0.031906 -0.18493 -0.14341 -0.021136 -0.15106 -0.19847 -0.023305 0.16321 0.19618 +i -0.40083 0.13992 0.12907 -0.11844 -0.24409 -0.071496 -0.12624 -0.10538 0.021209 0.17554 0.32066 -0.076655 -0.11599 0.1818 0.094396 -0.18509 0.067021 0.18963 -0.11674 0.0075544 0.20718 -0.08527 -0.082318 -0.48372 -0.19477 0.016658 0.13037 -0.08229 -0.12701 0.077853 0.10845 0.048532 -0.13885 -0.023352 -0.060823 -0.31839 -0.019554 -0.1885 -0.031728 -0.3455 0.053967 0.10746 0.19029 -0.12995 0.086172 0.23445 -0.03202 0.027213 -0.082134 -0.19291 0.041211 -0.54555 0.089378 -0.15301 0.012136 0.30464 -0.20036 0.014034 -0.13102 0.10406 -0.16595 -0.052645 0.035598 -0.17021 0.20491 -0.20084 0.26766 0.097651 0.097701 -0.10981 0.20629 -0.3151 0.29097 -0.026423 -0.082555 0.32322 0.060972 0.086412 -0.024904 0.25225 -0.17195 0.2637 0.07778 0.089817 0.21588 0.18605 -0.079905 0.12193 -0.05187 -0.047023 -0.087624 -0.28111 0.39698 0.044655 0.10639 0.17851 -0.085488 0.017462 0.12033 0.2419 0.054101 -0.095085 0.0081993 -0.16491 -0.24195 -0.37316 -0.10091 0.12269 0.18091 0.19682 -0.12658 0.067759 0.079479 0.0058875 0.097713 0.076515 0.28721 0.36722 -0.24784 0.33637 0.25466 0.065162 0.0038707 0.51321 -0.003927 0.10281 -0.062984 -0.14607 -0.083552 0.27136 -0.053043 0.051284 -0.3034 0.029091 0.14637 -0.010417 -0.095542 -0.016103 0.21725 0.36548 0.10367 0.071429 0.15473 -0.044417 -0.045747 -0.041136 -0.25878 -0.092717 0.016528 -0.12274 0.1247 -0.11255 0.32138 0.0066014 0.064847 -0.10889 0.010849 -0.028336 0.16727 0.4849 -0.38852 0.41925 -0.17268 -0.067313 -0.11283 -0.02391 -0.1155 -0.32136 0.20107 0.20899 -0.20854 -0.18056 -0.22479 -0.35432 0.057972 0.23497 0.10999 0.27061 -0.21413 -0.34127 0.14516 -0.2007 -0.13604 -0.024438 -0.28124 0.17943 0.27596 -0.42049 0.062588 -0.10503 0.18763 -0.2508 0.025648 0.16668 -0.13414 -0.42009 0.036313 0.17262 -0.71421 -0.14795 0.58208 -0.15923 0.016541 -0.091072 0.018594 0.045834 -0.28081 0.18502 0.032248 -0.0015265 0.16549 -0.020355 0.10414 -0.19742 -0.25135 -0.13147 -0.067539 -0.11853 -0.00047116 0.36873 -0.13839 -0.024654 -0.013609 -0.10761 0.14113 0.029728 -0.030725 0.23215 -0.0065696 0.10441 0.11082 0.016597 -0.24006 0.01712 0.099859 0.31432 -0.025396 -0.10787 -0.24261 0.30304 0.15428 0.083706 0.063191 0.15308 -0.011505 0.18101 0.43653 0.064489 0.10644 -0.39561 0.0331 -0.096854 -0.079486 0.19766 0.18531 -0.23033 -0.064171 -0.28063 0.19345 0.033538 0.020194 0.12357 -0.1725 -0.24075 0.0156 0.1166 -0.032856 0.29472 0.033151 -0.039342 -0.36029 -0.075652 0.15121 -0.021539 0.069992 -0.077885 0.15666 0.038273 -0.14749 -0.23696 -0.17154 0.30902 -0.29702 -0.22584 0.061565 -0.052918 0.074938 0.26361 -0.25301 0.026624 -0.09896 0.19602 0.0032991 -0.1712 0.18921 -0.2334 -0.56724 0.23206 0.079414 0.13813 +an -0.067108 0.0014183 -0.18575 0.16489 -0.24534 0.27442 -0.14976 0.1794 0.039032 -0.10412 -0.11836 -0.25005 0.097268 -0.1855 0.079226 -0.30441 0.10697 0.050226 -0.05342 0.15365 -0.083077 0.34187 -0.15903 -0.27095 0.077108 -0.45049 0.1234 0.23913 0.23134 0.36702 -0.31195 0.20269 -0.28004 -0.019993 -0.096778 -0.14713 -0.10808 0.051971 0.12347 -0.35383 0.057994 0.043842 0.015575 0.047289 0.26144 -0.0010199 0.05677 0.094892 0.082452 -0.22758 -0.16154 0.37473 0.034889 -0.12288 -0.04253 -0.12048 0.10472 -0.15786 0.18425 0.016285 -0.18772 0.083207 0.21165 -0.069999 0.1344 -0.26537 -0.20656 -0.013781 0.10536 -0.13477 -0.17973 -0.077508 0.39863 -0.1491 -0.24838 0.030682 0.19628 0.24353 -0.075409 -0.012853 0.13124 0.20169 -0.20009 -0.18221 0.090066 0.10347 0.0078001 0.077707 0.074893 -0.088733 0.31458 0.14006 0.44936 -0.28195 0.21684 -0.099295 -0.12245 0.0055658 -0.13224 -0.059352 -0.47566 0.099382 0.12039 -0.037683 -0.0056518 -0.04537 -0.09163 -0.016393 0.062906 -0.0069165 0.223 0.04041 -0.39129 0.072712 0.3457 0.022961 0.27431 -0.06153 -0.039516 -0.046008 0.44318 -0.021014 -0.25356 0.61883 0.070176 -0.0045592 0.0040353 0.24567 0.026488 0.094534 -0.028609 -0.01744 -0.16636 -0.23643 0.12687 -0.19006 -0.17911 -0.12807 0.024204 -0.051265 -0.23255 0.14934 0.058696 -0.11689 -0.032973 0.27406 -0.30796 0.35716 -0.096392 -0.11453 0.15556 -0.089407 0.16066 -0.080704 -0.27865 -0.25479 0.0035403 0.15614 0.11544 -0.11242 0.07595 -0.10383 -0.27032 0.12984 0.21313 -0.35816 0.27874 0.08321 0.145 0.083449 -0.15985 0.20965 -0.17859 0.016259 0.0031995 0.26716 -0.16324 0.38751 -0.28368 -0.039973 0.21694 0.1252 -0.13253 0.19007 -0.049799 0.16839 -0.10659 -0.0035849 0.082651 -0.048301 -0.075429 -0.28164 0.14112 0.3223 0.09433 -0.1621 0.045591 0.10928 -0.2348 0.37516 0.12891 0.030086 -0.11905 0.038139 0.11584 -0.3211 -0.18984 -0.27154 0.24411 0.1341 -0.04658 -0.12268 -0.050952 0.024939 0.066966 -0.23294 0.024861 -0.24273 -0.23792 0.19572 0.091152 0.020856 -0.017604 0.24744 0.18309 -5.6148e-05 -0.095182 0.23609 -0.21108 0.11985 0.25488 0.049656 -0.052515 -0.0061348 -0.087046 -0.057408 0.28785 -0.10364 -0.02118 0.037593 -0.21986 0.13574 0.082506 -0.15437 0.091008 -0.10259 0.40257 -0.34492 -0.10568 -0.11181 -0.014502 0.071941 -0.51856 -0.044696 -0.27071 0.16498 -0.028239 0.060804 -0.14116 0.16779 -0.10622 0.18766 -0.026886 0.07539 -0.097996 0.060153 -0.33941 0.11857 0.28548 -0.3165 -0.14515 -0.071001 -0.22944 -0.002594 -0.28214 0.02001 0.15415 0.040214 -0.035019 0.076674 0.32477 0.026201 0.041125 0.067551 0.12288 -0.37067 0.17592 0.32079 0.28704 0.071768 -0.019471 -0.38063 -0.18415 -0.19396 -0.046159 -0.40847 0.071106 0.10503 -0.21437 0.094425 +utc -0.48428 -0.32176 0.19893 0.46017 -0.42713 -0.048353 -0.026216 -0.52409 -0.2359 0.27416 -0.35709 -0.40256 0.19366 -0.26495 0.18056 -0.12858 -0.29003 -0.05781 0.13273 0.4141 0.044489 0.0563 -0.045292 0.019726 -0.18585 0.085899 0.10717 -0.12778 -0.027464 0.33869 -0.33442 0.21194 0.091994 0.37348 -0.25865 -0.070619 -0.26126 0.33048 -0.42579 -0.28211 -0.088483 -0.17591 -0.23531 -0.016519 0.011674 0.054129 -0.027932 -0.012981 -0.069228 -0.1482 -0.041675 -0.33993 -0.28414 -0.40908 -0.33748 0.051912 0.42039 0.058315 -0.0071972 0.2767 -0.068376 0.011432 0.46776 -0.051 0.10508 0.15315 0.29191 -0.10465 -0.18159 0.033912 0.010279 0.40703 -0.064585 -0.2132 -0.060905 0.38332 0.22248 0.19513 -0.021815 0.24547 -0.025301 0.38226 0.31938 0.22011 0.53214 0.042947 0.16149 -0.020663 0.092028 0.22657 0.21158 -0.16041 0.18343 -0.13396 -0.06567 -0.027172 0.013964 0.045881 0.065165 0.30027 0.17526 0.066824 -0.052815 -0.12023 0.26095 -0.084145 -0.13253 0.28631 0.060272 -0.11616 -0.17617 0.15855 0.13374 -0.075498 0.077391 -0.20716 0.19825 -0.22598 0.16929 -0.18486 0.48227 -0.34879 -0.43904 0.74208 -0.10392 -0.088865 -0.19534 -0.0027427 0.16728 0.32927 0.081751 0.014656 0.069382 0.33484 0.35977 -0.25077 0.034434 -0.31405 0.30761 0.42403 -0.27366 -0.13119 0.14726 0.33224 -0.14972 0.21281 0.063995 -0.30588 -0.47515 0.024818 0.2833 0.044557 0.13179 -0.084728 0.073318 0.18197 -0.0489 0.15566 0.49161 0.30123 -0.11857 -0.15212 -0.53843 -0.28876 -0.056063 0.0030809 -0.044774 -0.27874 0.29572 0.091087 -0.12764 0.26199 -0.3544 0.18866 -0.068732 0.045772 -0.059951 -0.48742 0.18282 -0.6876 0.0503 -0.2048 -0.0038009 -0.19067 -0.15979 0.26742 -0.13125 -0.066766 -0.0078525 -0.029119 0.0795 -0.38129 0.058981 0.020859 -0.31863 -0.075038 -0.30266 -0.033341 -0.55053 -0.14469 0.13898 0.081754 -0.061965 -0.098797 0.022741 0.17081 -0.29639 0.092066 0.077344 -0.064231 0.4199 0.029425 0.23973 -0.22587 0.09255 -0.092602 0.083138 -0.23305 -0.093396 0.11623 -0.085089 -0.20005 -0.041773 -0.17667 0.21748 0.11927 -0.19868 -0.11158 0.086228 -0.018281 -0.032333 0.11392 0.04883 -0.18285 0.041366 -0.0049917 -0.0068817 -0.21064 0.34286 -0.17382 0.33725 0.16046 0.34214 0.032393 0.11244 -0.11959 0.19667 0.45179 -0.029606 0.038383 0.16415 -0.43648 -0.21521 0.3047 0.0010787 -0.32584 0.29244 -0.0068554 0.2646 0.10143 0.15874 0.12227 -0.12451 0.11889 0.16019 0.062635 -0.26511 0.17294 -0.56961 0.033574 -0.060857 -0.17523 0.40498 0.24806 -0.30159 -0.12636 -0.095589 0.1132 -0.050348 -0.62738 0.040642 0.12592 -0.13136 -0.12702 0.29255 0.067631 0.1487 0.32518 0.22358 0.41682 -0.12407 0.23633 -0.13029 -0.087825 0.31466 -0.12516 -0.097898 0.40406 0.51224 0.10815 +his 0.10402 -0.28821 -0.15818 0.20985 0.049535 -0.002876 0.096098 -0.024723 -0.0050201 0.36894 0.35031 0.16471 -0.030644 0.17483 -0.066523 -0.2175 0.1822 0.086697 -0.13177 0.1011 -0.17153 0.15379 -0.13414 -0.33524 0.03576 0.29399 0.21437 -0.028075 -0.10089 0.1511 -0.10783 0.26146 -0.17181 0.11925 -0.14755 -0.16129 -0.020832 -0.098309 -0.015326 -0.089957 0.22468 -0.03473 -0.04656 -0.009934 0.15348 -0.11242 0.18949 0.307 -0.06551 0.018304 0.12813 -0.10501 -0.20465 0.16126 -0.29858 -0.13633 -0.046175 0.020232 0.049819 0.10887 -0.13646 -0.17847 0.15018 0.20485 -0.011903 -0.13977 0.046085 0.34986 -0.024604 -0.078071 0.056107 -0.090336 -0.11524 -0.21607 -0.076149 -0.20427 0.30443 0.30296 -0.10428 -0.11743 0.10949 0.22764 0.014133 -0.025727 -0.005435 0.13203 -0.21665 -0.068849 -0.22982 -0.17954 0.13009 -0.29531 0.32598 -0.12503 -0.0089292 0.051138 -0.16682 -0.071382 -0.14329 -0.1527 -0.15729 -0.026343 0.18611 0.078273 -0.052514 -0.10873 -0.077471 0.07973 0.0018202 0.19693 0.13191 -0.11219 -0.0067528 -0.010912 -0.17434 -0.20055 0.11816 0.11507 -0.021962 0.016486 0.16514 0.091797 -0.025318 0.15706 0.077311 -0.020868 0.076571 -0.016562 -0.027863 0.0056971 0.02676 0.30276 0.18429 -0.39858 -0.1974 -0.10722 -0.24991 0.032525 -0.058189 -0.15729 -0.069961 0.056673 0.10521 -0.019909 -0.048332 0.25628 0.13982 -0.17149 -0.030595 0.094349 0.19142 -0.07823 -0.027397 0.06945 -0.29189 0.28549 -0.29543 -0.10823 0.086663 -0.10761 -0.29005 0.13072 -0.049561 0.36925 0.040877 0.20516 0.16198 -0.12005 0.30093 -0.16159 -0.11649 0.054376 -0.12412 0.11427 0.074975 0.32926 -0.14556 0.25363 -0.063666 -0.22407 0.14934 0.074311 -0.13327 0.13586 0.0155 0.20365 0.17495 -0.12586 0.16635 0.11568 0.15053 0.038288 0.034325 0.40924 -0.14291 0.045536 -0.19508 0.03175 -0.20573 -0.026723 0.20341 -0.037178 -0.011121 0.060644 -0.043254 -0.037202 -0.0025812 0.11564 0.085551 -0.0076802 0.24845 0.097478 -0.030324 -0.18236 0.10056 -0.0063066 -0.069151 -0.13354 -0.016692 0.10081 -0.12247 -0.11127 0.0041489 0.030739 0.047028 0.17093 -0.18525 -0.36397 0.029484 -0.028286 0.25925 0.17551 -0.10166 -0.19536 -0.10045 0.074277 0.15925 -0.048295 -0.06633 -0.11771 0.015967 -0.19225 -0.0088948 0.42897 -0.056805 -0.05076 -0.067327 -0.22538 0.022078 0.12371 -0.08955 -0.21704 0.13323 -0.067719 -0.18504 0.061412 -0.23275 -0.06545 0.33823 -0.047858 0.038828 0.26028 0.14815 0.047344 -0.15341 -0.16757 0.12126 -0.023437 0.056399 -0.31843 -0.36956 -0.20536 -0.042763 0.35714 -0.17906 -0.30057 -0.042492 0.24998 0.13782 -0.014922 0.060555 0.21477 0.046219 0.066885 0.04799 0.24497 -0.044823 0.18982 -0.025087 -0.18196 -0.046023 -0.29132 -0.12802 -0.032446 0.1587 0.028899 0.077686 0.44013 -0.097676 0.22984 +not -0.10165 0.059919 -0.1232 0.12549 0.081861 -0.10623 0.010521 -0.30959 -0.20744 0.14257 -0.2189 -0.075084 0.051165 -0.23372 0.17875 -0.079692 -0.0025422 0.32958 0.040092 0.082214 -0.070752 0.12185 -0.18589 -0.16153 -0.005884 -0.0061922 0.066425 0.22926 0.09312 0.10566 -0.093385 -0.086662 -0.28523 0.1842 -0.20413 -0.24826 -0.10283 0.26559 0.017577 -0.29948 -0.080651 0.040256 -0.15623 0.12859 0.23405 0.3707 0.16416 -0.24976 0.071859 -0.13659 -0.079147 -0.23499 0.13596 -0.077971 -0.16653 -0.13163 0.12363 0.068203 -0.12249 0.21363 -0.21791 -0.23386 0.24773 -0.1945 0.1456 -0.17696 -0.067882 0.022953 0.15419 -0.13254 0.089502 0.30693 -0.061084 -0.18089 -0.099734 0.10039 0.11981 0.27519 0.066889 0.12991 0.0004807 0.081999 -0.088535 0.095537 -0.043715 -0.058082 -0.1779 0.059431 -0.19557 0.073797 -0.10429 0.2592 0.38376 -0.3283 0.040794 0.1686 0.081748 -0.013447 -0.065994 -0.072089 -0.070913 -0.13503 0.032871 -0.22361 -0.13109 -0.18579 -0.043896 -0.17439 0.12251 0.20237 0.12065 -0.051787 0.091358 0.013848 0.23909 0.070455 0.343 -0.00051651 0.14629 -0.25541 0.18622 0.28975 -0.23453 0.38065 -0.033524 -0.17608 0.089913 0.11165 0.0042652 0.23004 -0.24383 0.05827 -0.15064 0.090602 0.067073 -0.072764 -0.016719 0.12593 0.10604 0.046636 -0.21302 0.19356 0.14575 -0.040098 0.0067549 0.12274 -0.24602 -0.044288 -0.24008 -0.016141 0.15613 -0.071872 0.1744 0.097406 -0.067777 -0.043213 -0.082053 0.13555 0.26349 0.16 -0.14858 -0.0088246 -0.19326 -0.044553 -0.031665 0.070091 -0.040542 -0.19398 0.19131 0.18515 -0.14181 -0.23062 -0.28975 0.10269 -0.007946 0.11435 -0.16898 0.023102 0.082441 -0.013947 -0.1318 -0.28277 0.12417 0.10896 -0.024558 0.28635 -0.044126 -0.003302 0.19125 0.02919 0.028847 -0.22327 -0.10749 0.085832 -0.20578 -0.00034527 -0.16539 -0.10246 -0.25074 0.24211 0.15598 0.086186 0.075045 0.010384 0.085698 -0.016985 -0.14958 0.21403 0.26406 -0.0069881 0.28679 -0.091404 0.2526 -0.0092158 0.10054 -0.078072 0.019475 -0.25116 -0.091251 0.15673 -0.0138 -0.099987 -0.094965 -0.15354 -0.027002 0.092738 -0.33393 -0.0022815 -0.27831 -0.044561 0.36797 0.35371 -0.27255 -0.15559 -0.019929 0.047881 0.23914 -0.044706 -0.040735 0.033079 -0.034221 0.11005 0.23268 -0.039818 0.043159 0.2654 0.29131 -0.047859 -0.023094 -0.12603 0.13355 0.044156 -0.22604 0.14485 0.002346 0.031957 0.10215 -0.17147 0.17108 -0.046337 0.018677 0.15571 -0.26299 -0.1086 -0.17212 -0.085148 -0.22671 0.43174 -0.20754 -0.072317 -0.11661 -0.039356 0.02855 0.14251 -0.12054 -0.20299 0.01639 0.095018 0.09295 -0.1545 0.064815 0.082072 -0.16931 -0.052238 0.1054 -0.10485 0.11488 0.55399 -0.074979 0.063991 0.10147 0.13905 -0.051805 -0.0099941 0.020687 -0.29344 -0.10568 -0.058229 0.10437 -0.097786 +– -0.074243 -0.14581 0.0042414 -0.054143 -0.061729 0.17953 -0.069429 -0.12135 -0.11875 0.16621 0.20177 -0.017226 0.1573 -0.03953 0.090012 -0.036687 -0.26098 0.0041905 -0.11284 0.023359 0.14 0.089038 -0.053351 -0.14647 -0.36383 -0.14891 0.2176 -0.40479 0.34155 -0.34712 -0.21871 0.17763 -0.031031 0.10545 0.24395 -0.19795 -0.093159 -0.44803 0.15658 -0.25791 0.18745 0.068332 -0.072662 0.22322 0.13603 -0.32969 -0.15249 0.085624 0.25487 0.28128 0.010627 -0.35538 -0.033864 -0.16449 -0.089795 -0.27825 0.10672 0.13474 -0.03855 0.343 0.031718 -0.16919 0.091895 0.10994 -0.091711 -0.10035 0.14889 -0.18087 -0.32579 0.0049095 -0.14462 -0.20269 0.055001 -0.070278 0.36124 -0.19905 0.51309 0.015315 -0.24274 0.33375 -0.0067908 0.19277 -0.14527 0.072561 0.11603 -0.094053 -0.021575 -0.15835 0.086366 0.021454 -0.21514 -0.22843 0.11517 0.10596 -0.12265 -0.044811 0.0048639 -0.086847 0.058545 -0.05123 0.22049 -0.033784 0.082348 0.0076006 0.24701 -0.1474 -0.13146 -0.01793 0.22089 -0.32185 0.1407 0.11082 -0.20397 -0.070276 0.17148 -0.064251 -0.090867 0.27986 -0.13876 -0.0034167 0.37916 0.010541 0.097424 0.057774 0.027264 -0.13204 -0.17153 0.20486 0.005908 -0.17919 0.032869 0.026045 -0.067336 0.1405 -0.12048 -0.1356 -0.1709 -0.48859 0.16916 0.042499 0.038963 -0.0965 0.41464 -0.02048 -0.12186 0.34176 -0.085286 -0.037889 0.14855 0.15346 -0.11007 -0.091718 -0.23075 -0.039512 0.073513 0.097324 -0.14733 -0.164 0.21308 0.12019 -0.17643 0.045059 -0.27805 0.31068 0.18107 -0.26007 -0.0096112 0.35491 0.17522 -0.22537 -0.16697 -0.052645 -0.038348 0.10752 0.060932 0.45545 0.029672 0.17492 0.014216 -0.11258 -0.064369 -0.28497 -0.12605 -0.14725 -0.11215 0.50552 -0.021125 0.19148 0.20749 -0.23089 -0.0025873 0.046581 0.27259 0.23126 -0.041411 -0.22447 0.16386 -0.21997 -0.065836 -0.12412 0.048542 -0.27597 -0.22871 -0.13584 0.32973 0.082569 -0.016757 -0.0021851 0.43885 0.30782 0.43322 -0.12505 -0.021478 -0.41959 -0.1909 -0.084843 -0.058456 -0.25144 -0.56395 0.0065123 0.090346 0.095143 -0.35786 0.26598 -0.048906 0.00013924 -0.060989 -0.2965 0.083843 0.21255 -0.049793 0.3673 -0.21245 -0.23451 -0.32343 0.011691 0.06591 0.21766 -0.066193 -0.057447 -0.30345 0.13892 0.2163 -0.33747 -0.021699 -0.19323 0.084407 -0.11848 0.26885 -0.19656 -0.038939 -0.39928 -0.16134 0.12309 0.17358 -0.2044 -0.13378 0.22725 -0.033322 0.082696 0.036003 0.2597 0.2478 -0.07049 0.1423 0.10547 -0.01697 -0.00038213 0.28261 0.29803 -0.31649 0.15573 -0.1565 -0.060337 -0.019986 -0.1741 0.31426 0.15278 0.10003 0.0032204 0.024748 -0.17344 0.0030854 0.50289 0.23061 0.025332 0.022417 0.090369 0.18072 0.18711 0.18092 -0.18509 0.29914 0.027199 -0.15691 -0.022083 -0.061926 -0.087543 0.13087 -0.10008 +are 0.068075 0.11922 0.023882 0.37069 0.014192 0.097715 0.21779 -0.24945 0.0011198 0.16098 0.0064797 0.33891 -0.11749 -0.037715 0.18563 -0.069853 0.17305 -0.031465 0.040186 -0.27739 -0.20284 0.029981 -0.27263 -0.025092 0.091772 0.1102 0.38902 -0.10087 -0.17198 -0.067105 -0.040523 0.079384 -0.14774 0.12478 -0.16603 -0.099398 -0.077271 0.39471 0.0054795 -0.08421 0.012772 -0.18077 -0.030225 0.091158 0.035682 0.069845 0.1622 -0.097343 0.016863 -0.074525 0.053345 -0.21452 0.033379 0.041069 -0.27623 0.077255 -0.014886 0.25726 -0.43105 0.22767 0.0091815 -0.07473 0.22352 0.092458 0.037888 0.28344 -0.27073 0.032617 -0.068675 -0.058164 -0.17353 0.12066 0.0050963 -0.17134 -0.33808 -0.08456 0.21941 0.19253 0.095015 -0.14823 0.0015282 0.10643 -0.057338 0.063292 -0.09634 -0.11199 -0.065599 0.20725 -0.014514 -0.049921 -0.055564 -0.08997 0.013941 -0.33375 0.020615 -0.098456 0.15909 0.008886 0.35115 0.010636 0.262 0.093022 0.18694 -0.18338 -0.16586 -0.13103 -0.072261 0.048203 -0.075256 -0.13489 -0.082061 -0.075493 -0.21996 0.0051421 0.20318 0.0012931 0.067616 0.15115 0.10954 0.21893 0.17318 0.10901 -0.20532 0.29342 0.022555 0.24915 0.32257 0.13122 0.086716 0.21107 -0.096713 0.023109 -0.13828 0.302 0.15696 -0.049769 -0.04199 0.11019 -0.021979 -0.080457 -0.050684 0.26178 0.2403 -0.09769 0.14033 0.11232 -0.32539 -0.034091 -0.03529 0.048993 -0.075889 -0.34727 0.016038 -0.048272 -0.021335 -0.13193 0.11539 0.024062 0.44077 0.038008 0.14401 0.29159 -0.24173 -0.0049045 0.15583 0.10192 -0.10392 -0.28757 0.28469 0.41803 -0.042302 -0.051294 -0.098563 0.34091 -0.11194 0.19712 -0.025254 -0.06966 0.038747 0.060655 -0.089978 0.0086719 0.15042 0.25503 0.27898 0.13669 0.055458 0.05992 0.3318 -0.15095 -0.030234 -0.17807 -0.17358 0.0071614 -0.00084657 -0.27386 -0.050951 0.17567 -0.07578 -0.083602 0.14937 -0.17486 -0.11393 -0.12485 -0.052407 -0.1646 -0.11442 0.18861 0.24865 0.05498 0.14604 0.034552 0.067551 0.21737 0.10234 -0.0341 -0.14013 -0.20881 -0.06207 -0.05566 -0.023096 -0.037693 -0.24167 -0.090629 -0.17715 0.20651 -0.081545 0.015374 -0.013538 -0.059219 -0.19558 -0.098134 -0.16625 -0.20143 -0.33186 0.16345 -0.099827 -0.2949 0.08549 0.021519 -0.0017567 -0.025824 0.19679 -0.06622 -0.031677 0.50367 0.28156 -0.056368 0.16811 0.015189 0.039304 0.1924 -0.24432 -0.14347 0.016411 0.073853 -0.081446 -0.2148 0.12565 -0.15951 0.033415 0.29264 -0.22688 0.012675 -0.34332 -0.094871 -0.16327 0.37924 -0.1183 0.12053 0.17636 0.31 0.15456 -0.0423 0.010965 -0.06829 0.21338 0.1291 -0.20109 0.13406 0.20265 0.017755 0.10243 0.12721 -0.048709 0.1251 0.090134 0.15317 -0.50606 0.39727 0.078705 0.087608 -0.089584 0.1835 0.11305 0.051525 -0.27361 -0.060681 0.37629 -0.1347 +or 0.15704 0.27477 -0.1464 -0.04292 -0.10607 -0.11715 0.051673 -0.32192 0.33107 -0.025881 -0.075172 -0.074813 0.2081 0.099941 0.041541 0.030858 -0.25155 0.25441 -0.084407 -0.051553 -0.17238 -0.15269 -0.18267 0.18355 -0.051123 0.07332 -0.022929 -0.0063468 -0.005875 -0.14793 0.0059168 0.30124 -0.2651 -0.021407 -0.27338 -0.12335 -0.038612 -0.015882 0.11503 -0.11516 -0.0025974 -0.054351 -0.12987 -0.10556 0.13894 -0.015744 -0.15422 0.097752 0.153 -0.12647 -0.1452 -0.1462 -0.13567 -0.13104 -0.4195 -0.075874 0.036777 -0.2402 -0.060928 0.12043 -0.30466 -0.16522 0.24939 -0.0083877 -0.0002194 0.12085 -0.10663 -0.1413 -0.013368 -0.0058912 -0.41856 0.16722 0.012261 -0.039972 -0.16393 0.097758 0.35358 0.064022 -0.02861 0.082674 0.044896 0.04129 0.14051 -0.017957 0.052639 -0.049675 -0.074805 0.16103 -0.17408 -0.022082 -0.083101 -0.27132 0.17934 -0.44707 0.13648 0.22114 -0.0046031 0.23959 -0.12924 -0.0026605 -0.22004 -0.10051 0.025711 -0.13299 0.19071 0.064071 -0.02278 0.0032825 -0.16831 0.043757 -0.11602 -0.091856 -0.38552 0.094749 0.036016 0.077829 0.019377 0.042153 -0.012166 0.4145 0.26425 0.19812 -0.06433 0.26048 0.099399 -0.14283 0.15676 0.21875 -0.06971 0.23653 0.064968 0.05967 0.14283 0.19122 0.19368 -0.10592 -0.14375 -0.11758 0.12519 -0.099381 -0.26858 -0.041878 0.11157 0.09033 0.13836 0.14039 -0.242 -0.054919 -0.25838 0.20088 -0.11406 -0.14746 -0.0050198 -0.1858 -0.24144 -0.0092371 0.11046 0.03752 0.21497 0.014071 -0.22261 0.18182 -0.15965 -0.089955 0.2123 -0.20447 -0.088009 -0.194 0.10807 0.2324 -0.19668 -0.033181 -0.11221 0.20041 -0.16249 -0.030724 -0.17868 -0.012331 0.10392 -0.031104 0.041706 0.061677 0.21223 0.17411 -0.032238 0.32212 0.21967 0.036921 0.2571 0.083746 0.02917 -0.096245 0.12359 0.0010644 -0.24225 -0.19914 0.17453 0.089325 -0.42055 0.13403 0.0055108 -0.14981 -0.0057878 -0.0679 -0.19506 -0.15872 -0.37655 0.27361 0.047729 0.16533 0.054212 -0.021458 0.14338 0.14566 0.015581 -0.17634 0.042809 -0.29286 -0.19828 -0.025737 -0.18551 -0.23724 -0.21856 0.34016 -0.015677 0.21319 -0.21419 -0.027561 -0.021925 -0.022113 0.12934 0.031221 -0.20615 0.03313 -0.12703 0.22021 0.13355 -0.1373 -0.13107 -0.072012 0.053241 0.077847 0.2131 0.03414 0.014275 0.49335 0.29841 -0.013242 0.067344 0.15452 0.14319 0.015675 -0.16666 0.052152 0.095985 0.076897 0.13227 -0.30337 -0.044407 -0.1432 -0.17713 -0.040572 -0.20965 0.067509 -0.14875 -0.26898 -0.15289 0.22591 0.17172 -0.098214 -0.26325 0.22259 0.093613 -0.12336 -0.0639 0.13469 -0.039753 -0.1112 0.20467 0.20881 0.14671 0.062785 -0.016639 0.22037 0.23413 -0.12865 0.21238 0.32971 -0.13284 0.034719 -0.032905 0.047265 -0.0013959 -0.010848 -0.031438 -0.011604 -0.17007 0.16054 0.10169 0.036166 +talk -0.51502 -0.087155 0.29287 0.5651 -0.28805 -0.17474 -0.038578 -0.51808 -0.208 0.057625 -0.25418 -0.070127 0.17217 -0.17911 0.23253 0.0020426 -0.35401 0.046652 0.12056 0.38395 -0.098002 0.35237 -0.041988 0.046982 -0.28973 -0.030722 -0.12125 0.046543 0.018254 0.038112 -0.20077 0.20537 -0.21331 0.15839 -0.44963 -0.09859 -0.042303 0.29175 -0.044655 -0.27497 -0.084447 -0.25379 -0.4609 0.10064 -0.0055138 -0.16253 -0.044512 -0.22172 0.17125 -0.025951 0.031526 -0.378 -0.14173 -0.3983 -0.34191 -0.012546 0.21553 0.055421 0.066442 0.2283 -0.084358 0.082958 0.38922 -0.069284 0.14633 0.12257 0.36995 -0.0031165 0.018671 0.049937 0.091243 0.27755 -0.024257 -0.26027 0.07692 0.28322 0.33993 0.26507 0.067408 -0.033386 -0.18819 0.16684 0.4216 -0.0010725 0.54386 -0.15157 0.10137 0.12335 -0.13373 -0.0099552 0.11231 -0.093794 0.31382 -0.22426 -0.18026 -0.078615 -0.074403 -0.0083639 0.24154 0.26961 0.092677 -0.16979 0.042122 -0.020092 0.36024 0.071364 -0.29228 0.22043 0.066795 0.0076619 -0.30348 0.13248 -0.0071443 0.037317 0.078576 0.016024 0.098381 -0.14786 -0.052254 -0.10443 0.45094 -0.10489 -0.21742 0.47534 0.06089 -0.050889 -0.084747 0.17821 0.035628 0.4539 0.19804 0.22578 -0.077802 0.3353 0.17344 -0.09908 0.059217 -0.17151 0.21276 0.22492 -0.36317 -0.067479 0.15167 0.29204 0.0040326 -0.026961 0.18859 -0.0118 -0.34211 0.11941 0.19878 0.020734 0.26005 -0.054375 -0.13848 -0.030475 -0.10115 0.19098 0.4534 0.29641 0.016614 0.13778 -0.55542 -0.04297 0.0039076 -0.23734 -0.020629 -0.23122 0.19121 0.076433 -0.27428 0.35226 -0.35025 -0.17145 -0.24696 0.26374 -0.035996 -0.42555 0.32856 -0.54186 0.27558 -0.13008 0.10612 -0.057362 -0.40505 0.38429 0.1689 -0.15704 -0.053162 0.19776 -0.20164 -0.22386 -0.0024748 -0.10298 -0.17367 -0.29494 -0.26827 -0.10596 -0.4487 0.10969 0.065727 0.10714 0.28274 -0.036414 0.094313 -0.079026 -0.60359 0.17576 -0.11556 -0.28082 0.5163 -0.15851 0.24633 -0.12513 -0.0021006 0.032827 0.29735 -0.12502 -0.063655 0.30564 0.14165 -0.27447 -0.11954 -0.15022 0.05908 0.055581 -0.33298 -0.36227 -0.1382 -0.012297 -0.0011931 0.17768 0.23547 -0.14427 -0.16888 0.1063 0.1136 -0.018082 0.094457 -0.16756 0.20222 0.14059 0.35022 0.10239 0.057565 0.20441 0.22367 0.48103 0.065504 0.17266 0.31872 -0.43984 -0.30028 0.19134 0.18433 -0.31557 0.14953 -0.1969 0.096832 -0.061628 0.0408 0.091795 -0.21148 -0.013321 0.3421 0.077817 -0.17176 0.23772 -0.39733 0.056059 -0.07854 -0.020592 0.46005 0.17168 -0.26961 -0.17015 0.10934 -0.23509 0.079249 -0.35777 -0.054466 0.4247 -0.23561 -0.099701 -0.051848 -0.14279 0.028812 0.31988 0.21254 0.32248 -0.13966 0.19339 -0.057603 -0.10295 0.33619 -0.14097 -0.048378 0.45479 0.43523 0.14572 +which -0.1366 0.089613 -0.14943 0.11649 -0.01319 0.17219 0.026408 -0.18583 0.094055 0.11502 -0.053152 -0.024419 0.076843 -0.019564 -0.1061 -0.16221 -0.010032 0.049038 0.18104 0.15793 -0.10595 0.031939 -0.092641 -0.16962 -0.056751 -0.087791 0.065532 -0.031698 0.033936 0.11224 -0.24995 -0.0024345 0.0079827 0.28455 0.17273 -0.041929 -0.11081 -0.15354 -0.029476 -0.05442 0.067539 -0.038531 0.0085609 0.057694 0.065164 -0.0026675 -0.016484 0.010404 0.07781 -0.011431 0.14611 -0.13983 -0.021891 0.12978 -0.18038 0.056892 -0.11715 0.09215 -0.067667 0.0071631 0.024219 0.017571 0.28959 -0.0074404 0.081526 -0.28356 -0.22615 -0.14195 0.085809 0.057779 -0.19975 0.0010409 0.019223 -0.12793 -0.049878 -0.091973 0.13904 0.14927 -0.13723 -0.050327 0.051943 -0.063355 -0.024172 0.082238 -0.1248 -0.016045 0.066155 0.15183 0.060598 -0.13138 0.021951 0.020506 0.21477 -0.26457 0.090804 -0.036147 0.21892 0.10993 -0.072831 -0.026577 -0.20511 -0.008926 0.2213 -0.060568 -0.26017 -0.12535 -0.10255 0.041481 -0.0099699 -0.058545 -0.10755 -0.040484 -0.082955 -0.086121 -0.057899 -0.11497 0.12638 0.0373 0.043054 0.069624 0.30646 0.13169 -0.11527 0.44147 0.012816 0.036934 0.25245 0.16918 0.060928 0.19901 0.049581 0.071278 0.012012 -0.063791 -0.1203 0.11302 -0.047718 0.20644 0.079929 0.038033 0.23802 0.1475 0.23901 -0.011012 -0.042428 0.19112 0.01067 -0.034236 0.036252 0.11664 0.032867 -0.16543 -0.10125 -0.044732 -0.096869 -0.14071 0.050549 -0.022551 0.19573 -0.11806 -0.16719 0.12285 -0.19589 0.13134 0.27461 -0.11551 -0.071565 -0.04092 0.14418 0.012053 -0.098775 -0.14701 -0.13802 -0.10642 -0.15041 0.047264 -0.033371 0.13185 -0.093542 -0.024369 0.071935 -0.098267 0.0045845 0.0013461 0.0075303 0.12576 0.12891 0.025221 0.15136 -0.11688 -0.036385 -0.25848 0.30017 0.16147 -0.14445 -0.021881 0.066263 0.11211 -0.13981 -0.16118 0.14848 0.13138 -0.05233 0.23926 -0.11716 -0.09338 -0.079087 0.044523 0.015428 0.067357 0.13241 -0.01073 0.045651 0.034833 0.10518 -0.0099894 -0.048695 -0.20633 0.026859 0.06574 -0.081094 -0.13418 0.018345 0.17805 -0.016394 -0.016459 -0.2573 -0.18557 -0.097033 0.037761 0.24172 0.087141 -0.057182 0.010641 -0.018008 0.15687 0.11464 -0.27033 0.12867 0.019615 -0.091443 -0.070544 -0.0061156 -0.049995 -0.081001 0.16626 0.094093 0.0074724 0.030116 -0.0012607 0.009622 0.14521 -0.10851 -0.079409 -0.1251 0.10606 -0.060301 0.013551 -0.027379 -0.21868 0.032708 -0.05434 -0.069004 0.019942 -0.046241 -0.072318 -0.12047 -0.064143 -0.048557 -0.078251 -0.28058 -0.073269 0.044686 0.0655 -0.19013 -0.061642 0.14578 0.12103 0.072491 -0.056212 0.12846 0.0018487 -0.12455 -0.12468 0.13788 -0.20864 0.031815 0.1586 -0.15104 0.0043366 0.027146 -0.13943 0.061288 0.085656 0.010775 -0.1026 -0.11045 0.10613 0.032806 -0.066088 +also -0.10199 -0.029575 0.044086 -0.009556 -0.091235 0.067535 0.019021 -0.083682 0.085467 -0.035428 -0.018385 0.052966 0.19551 -0.068552 0.047272 -0.10403 0.10777 0.17372 -0.11649 0.0087456 0.033866 0.10598 -0.11332 -0.25169 -0.097752 -0.09137 0.086589 0.051324 -0.13105 -0.041564 -0.091289 -0.060466 -0.012236 0.15386 0.32111 0.059388 -0.16265 0.1027 0.062333 -0.097792 0.0036074 0.13996 0.052064 0.037899 -0.084553 -0.00072753 -0.078382 0.061794 0.054656 -0.059954 -0.058602 0.01573 -0.029489 0.16198 -0.14704 -0.072781 0.1328 -0.0074195 -0.31438 0.050634 0.027006 0.1446 0.063948 -0.18001 0.13802 -0.029694 -0.2869 -0.031812 0.070403 -0.082781 -0.1779 -0.074744 -0.0031902 -0.1866 -0.19473 -0.12418 0.2048 0.13232 -0.057654 -0.083787 0.21755 0.07123 -0.13457 -0.016186 -0.10486 -0.093296 -0.08005 0.0094487 -0.082128 -0.09243 0.067953 0.11587 0.25693 -0.12683 -0.00049712 -0.050758 0.10701 0.14283 -0.18908 0.042387 -0.083653 -0.069712 0.2265 -0.17424 -0.2035 -0.028741 -0.0090919 0.024013 0.10139 -0.079693 -0.079487 -0.052665 -0.13967 -0.052957 -0.22001 -0.063987 0.13558 0.1752 0.070688 0.091437 0.22637 -0.0053784 0.13638 0.25446 -0.031823 -0.052998 0.17931 0.025283 -0.077359 0.21873 0.033037 0.28444 -0.11726 -0.12749 -0.030037 0.072029 -0.1929 0.058983 -0.13218 0.1109 0.089714 0.20154 0.18655 -0.12028 0.23454 0.32869 0.05501 -0.034246 0.15899 -0.0058268 -0.15113 -0.22112 0.021726 -0.037808 -0.051634 -0.0030719 -0.077365 -0.099068 0.32765 0.060159 -0.11181 0.18229 -0.21733 0.13687 0.31553 -0.13248 -0.10967 -0.15215 0.12272 -0.010188 -0.14129 -0.16995 -0.082264 -0.038325 -0.0174 -0.12772 0.24262 0.083355 -0.059138 -0.046193 0.10283 0.0051551 -0.079153 0.15747 -0.043459 0.22579 0.087606 -0.022363 0.14214 0.037063 -0.082087 -0.18713 0.191 0.13647 0.016245 0.014273 0.13118 0.09029 -0.22856 -0.10881 0.14809 0.18069 -0.01077 0.17902 0.091191 -0.065434 -0.12803 0.13762 0.14837 0.19205 0.39363 -0.16942 -0.11687 0.038142 -0.016133 -0.070637 -0.057537 -0.087532 -0.048222 -0.022712 -0.056314 -0.13467 -0.25796 -0.047064 -0.15093 -0.082384 -0.1602 -0.18496 0.060734 0.10906 0.13877 0.051332 -0.014719 -0.041195 0.080713 0.17732 0.17239 -0.078599 0.12017 0.10604 -0.19992 -0.055807 -0.08637 0.031074 -0.086495 0.23517 0.17327 0.00037676 0.059224 -0.0091838 0.20371 -0.019742 -0.011187 0.010585 -0.061877 0.059871 -0.071681 -0.052947 0.12472 -0.21844 -0.044127 0.16826 0.11384 -0.089687 -0.038195 -0.11779 -0.22465 0.153 0.029225 -0.22414 -0.3777 -0.12909 -0.13505 -0.050751 -0.079058 -0.27431 0.16502 0.10421 -0.010874 -0.14634 0.10699 -0.058726 -0.037787 -0.072274 0.072365 -0.10982 -0.095985 0.26826 -0.03556 0.05075 -0.11292 -0.06942 0.086165 0.065727 -0.054321 0.052511 -0.16253 0.2015 0.0041331 0.075331 +has -0.037104 -0.15934 -0.20972 0.16271 -0.083254 0.087212 0.12751 -0.2475 -0.040555 0.18439 0.10943 0.38661 0.23639 -0.12139 0.079275 0.056292 -0.052791 0.016059 0.18267 0.086483 -0.063912 0.32852 0.086933 -0.35911 -0.11532 0.032592 0.1349 0.22591 -0.033666 0.13442 -0.19404 0.3927 0.071071 0.20843 -0.03972 0.039964 -0.063742 0.18055 0.016079 -0.25214 0.12943 -0.12358 0.025545 0.05405 -0.18598 0.14679 0.16485 0.018224 0.19253 0.046268 -0.31555 -0.22574 -0.071412 0.14357 -0.031327 0.045249 -0.024863 0.17802 0.034869 0.032205 0.12742 0.088153 0.20316 -0.23777 0.12876 0.045867 -0.17198 0.1603 0.12483 0.26149 -0.17178 0.025935 0.1345 -0.13649 -0.24397 -0.032723 0.17895 0.39486 -0.13397 -0.22152 -0.037225 -0.01479 0.13754 -0.19564 -0.062243 -0.39478 -0.0066871 0.026155 -0.15922 -0.0091263 0.20696 0.17439 0.34976 -0.2265 0.23913 -0.10844 0.22845 -0.016551 -0.093076 -0.20824 -0.12598 -0.017496 0.36861 0.087194 -0.07378 -0.20465 -0.24162 0.098533 -0.066151 -0.072473 -0.20388 0.26605 -0.03353 -0.098308 -0.20663 0.015082 0.31075 0.09264 0.262 0.21772 0.031057 0.010123 -0.10078 0.24702 -0.057209 0.027766 -0.02456 0.28584 0.10478 0.19865 0.036808 0.22754 -0.053619 -0.016135 0.010575 -0.01272 0.1627 0.019843 -0.13141 0.0065325 -0.212 0.047192 0.075736 -0.084365 -0.0053548 0.17796 0.024891 -0.23105 -0.026875 0.12094 0.049634 -0.0070304 -0.056275 0.033928 -0.17572 -0.022068 -0.10128 0.1107 0.60892 0.091303 0.21521 0.21085 -0.39308 0.065964 0.41137 -0.059475 0.16561 -0.16754 0.13284 0.18948 0.16141 0.01466 -0.044996 -0.012112 -0.15361 -0.19217 0.25575 0.16979 -0.091726 -0.25373 -0.006567 -0.16052 0.087937 0.30702 -0.057858 -0.11965 0.20803 -0.26305 0.067702 -0.024586 -0.16093 -0.25264 0.20752 0.1498 -0.27518 -0.34051 -0.011728 0.053596 -0.21899 0.0014362 0.17574 0.034705 -0.049522 -0.0173 -0.31771 0.20279 0.079172 0.11655 0.19118 0.15154 0.10863 -0.062324 -0.26874 0.05175 0.03137 -0.057502 3.1331e-05 -0.17627 0.087096 0.038063 -0.24935 -0.15896 0.016353 -0.14652 0.034936 -0.092346 -0.12546 -0.016827 -0.083488 0.19805 0.053528 0.15698 0.081108 -0.0216 -0.097507 -0.089972 0.067253 -0.087335 0.065078 0.17124 0.042137 0.18912 0.20367 -0.096758 0.046836 0.070811 0.14696 0.0087765 -0.074154 -0.012712 0.16641 0.1635 -0.045091 -0.16329 -0.12624 0.056128 -0.0043689 0.18184 0.063412 -0.051545 0.25422 0.15186 0.06973 -0.19457 -0.10782 0.18095 0.054198 0.12992 -0.14423 0.015112 0.094256 0.20209 0.15561 -0.023712 -0.19833 -0.37299 0.49199 0.28813 0.25381 -0.054711 0.14948 0.080718 0.073101 -0.16722 -0.088161 -0.050944 -0.045697 0.061521 0.088355 0.21334 -0.18823 -0.32114 -0.010622 0.066662 -0.028784 -0.27054 0.17808 0.17786 0.11754 -0.056556 +were -0.068445 0.099087 -0.24308 0.33548 -0.0031275 -0.006333 -0.10889 -0.21951 -0.0024221 0.4146 0.23566 0.20982 -0.24496 0.14248 -0.026614 -0.11096 0.15741 -0.16144 -0.028646 -0.13093 -0.22131 0.0014234 -0.15683 -0.0050016 -0.12766 0.083324 0.17756 -0.030187 0.060405 0.12931 0.034978 -0.0091733 -0.1643 0.13999 -0.026577 -0.19496 -0.053957 0.097141 0.28673 -0.059726 0.11305 -0.20915 -0.11046 0.18123 0.081285 -0.34466 0.11424 -0.12561 0.11813 0.033823 0.038107 -0.064745 -0.23124 0.25065 -0.33116 0.017042 -0.055454 0.42565 -0.45323 0.21068 0.069609 -0.14523 0.089408 0.1035 0.28437 0.236 -0.20279 0.14852 -0.42737 -0.073198 -0.11078 -0.07642 -0.073162 -0.23988 -0.17318 -0.0068665 -0.012479 0.010396 0.1508 -0.26472 -0.0016496 -0.0094123 0.0092361 0.26676 -0.054224 -0.19992 -0.045789 0.13606 0.055979 -0.22412 -0.3968 -0.39842 0.045851 -0.31815 -0.062014 0.15047 -0.047315 -0.11278 0.16557 -0.10734 0.13977 0.27197 0.14378 -0.060688 -0.24365 -0.098889 0.06011 0.23275 -0.23157 -0.066255 0.06991 -0.0064679 0.0080212 -0.046175 0.313 0.13919 0.23846 0.32081 -0.060535 0.30826 0.10715 0.38716 -0.10936 0.22095 0.10203 -0.12118 0.29876 0.25772 0.065966 0.34236 -0.10608 -0.018972 -0.076393 0.22523 0.20145 0.016278 -0.091804 0.19749 -0.1022 0.028801 0.092751 0.08596 0.14952 -0.026422 0.35293 0.24252 -0.31605 0.03504 -0.024624 0.19853 0.0043439 -0.17677 -0.0090416 0.14211 -0.12829 -0.046166 -0.078442 -0.078174 0.42481 -0.20228 -0.040442 0.21548 -0.023974 0.1256 0.20805 0.15724 0.13651 0.04322 0.36508 0.40936 0.022476 0.14754 -0.20224 0.34179 -0.16612 0.027713 -0.23979 -0.082436 -0.12374 0.12392 0.089757 0.070725 -0.075194 0.17363 0.093092 0.18117 0.015701 -0.041446 0.20614 -0.048112 -0.05081 -0.26021 -0.12195 0.24293 -0.079592 -0.21686 -0.18585 0.14748 -0.06935 -0.23259 -0.16425 -0.21497 -0.013283 -0.05236 -0.058112 -0.099351 -0.028415 0.14002 0.4723 0.27792 0.32984 -0.24909 -0.10459 0.053025 0.044867 0.10055 -0.27034 -0.22223 -0.20335 0.074912 0.050363 -0.020285 -0.12366 0.12841 -0.12174 0.22227 0.061548 -0.044235 -0.029434 0.067892 -0.11174 -0.16842 -0.060431 -0.040204 -0.20923 0.046015 0.17366 -0.053212 -0.035433 0.14074 0.089744 -0.12077 0.16616 0.03921 -0.22334 0.10902 0.13832 -0.16309 0.10215 0.11897 -0.041193 0.07898 -0.16219 -0.23182 0.041993 0.021981 -0.07708 -0.067524 -0.32592 0.10935 -0.074117 0.024167 -0.30704 0.019811 -0.37234 0.15542 0.0045722 0.16267 -0.014282 0.037255 -0.017401 0.059816 -0.0010507 -0.048395 -0.12962 -0.056961 0.14012 0.34957 0.00018399 -0.032245 0.16807 -0.028524 -0.011653 0.1483 0.12325 0.16128 0.0022709 0.1181 -0.3508 0.076117 0.13761 0.18703 -0.23417 0.45034 0.01554 0.31797 -0.35996 -0.08788 0.056966 -0.013823 +but -0.079164 0.076763 -0.21548 0.16528 -0.11802 0.039405 0.011044 -0.09713 0.010117 0.22486 0.045442 -0.11089 0.1399 -0.074201 0.075995 -0.1036 -0.094509 0.050348 0.045914 0.20964 -0.0067661 0.044842 -0.21211 -0.18314 -0.097933 0.010572 0.1852 -0.019973 -0.0088071 0.029456 -0.24142 0.022411 -0.20667 0.22668 0.0063956 -0.045143 -0.11583 -0.050365 0.0046732 -0.056415 0.070365 0.0063326 -0.0029066 0.016326 0.069693 0.11918 0.23497 0.13913 -0.041517 -0.066877 0.050167 -0.26195 0.082991 -0.022692 -0.25655 0.11535 -0.086147 0.16483 -0.15154 0.14778 -0.121 -0.16445 0.13407 -0.019638 0.045871 -0.087815 -0.088777 0.063853 0.040907 0.0038579 -0.04986 0.063078 0.0037467 -0.24193 -0.10222 0.18381 0.11146 0.25749 0.045231 -0.080679 0.084817 -0.14721 0.0085681 0.11134 0.035577 0.096459 -0.0013639 0.066321 0.016865 -0.097138 -0.021317 -0.072953 0.25688 -0.093827 0.12221 0.1121 0.25924 0.10369 -0.12412 -0.17753 0.063635 -0.11677 0.12718 -0.040048 -0.16494 -0.22505 -0.16007 -0.03995 0.047366 -0.015505 -0.023187 0.08562 -0.020509 -0.025692 0.14583 -0.22879 0.18418 0.10301 0.033076 -0.10496 0.049255 0.10506 0.012432 0.50282 0.052452 -0.12038 0.21932 -0.092614 0.04883 0.030281 -0.18125 0.05154 -0.12871 0.010433 -0.074875 0.060996 0.0060966 0.061643 0.039672 0.023959 -0.07049 0.011611 0.17537 -0.092446 0.091484 0.061307 -0.13374 -0.052023 -0.062569 -0.094123 -0.039178 -0.093719 0.027621 0.14292 -0.15661 -0.02841 0.012859 0.13379 0.2289 -0.07874 -0.18321 0.24078 -0.066658 0.15385 0.11702 0.077492 -0.14442 -0.15717 0.22157 0.0027687 -0.086402 -0.13276 -0.16944 0.018067 -0.18639 0.1014 0.0031304 0.17413 -0.068919 -0.17704 0.17879 -0.15309 0.17393 0.0038439 -0.1513 0.11727 -0.0099599 0.085904 0.18165 -0.10413 -0.0037074 -0.23635 -0.043408 0.17194 -0.077636 -0.068464 0.058019 -0.019928 -0.24853 -0.095232 0.076296 0.057998 0.028065 0.072391 0.034423 -0.12335 -0.034197 0.046138 0.13778 0.014685 0.25908 -0.007901 0.13487 -0.031072 0.018154 -0.011763 -0.036748 -0.099195 -0.066583 0.14907 -0.14969 -0.20533 0.04719 -0.11187 -0.02049 0.0067442 -0.12955 -0.017289 -0.12694 0.062896 0.27812 0.22291 -0.20145 -0.11806 -0.15738 0.20915 0.1486 -0.086578 0.030686 0.091274 0.083729 0.0097084 0.1053 -0.023798 -0.17284 0.28921 0.14236 0.060793 -0.053195 -0.029509 -0.047385 -0.065573 -0.25968 -0.11444 0.085377 -0.03488 0.048367 -0.16444 -0.051247 0.023075 0.056656 0.05537 -0.10491 -0.30133 -0.07454 -0.092246 -0.13257 0.16204 -0.044964 -0.10008 -0.30789 -0.047837 0.10486 0.15051 -0.068935 -0.11495 0.037402 0.18803 0.022191 -0.044601 0.1068 0.10474 -0.18209 -0.091639 0.013183 -0.033254 -0.019837 0.32707 -0.11688 -0.049202 0.057843 0.072315 0.06032 0.010248 0.091444 -0.146 -0.1364 0.13391 0.0094585 -0.038994 +have -0.13952 0.032673 -0.26126 0.060333 -0.072865 6.859e-05 0.16065 -0.27848 0.067919 0.29608 0.17328 0.1855 0.091478 -0.12249 0.093476 0.01337 0.013748 0.13742 0.19074 -0.12157 0.012453 0.048378 -0.041583 -0.2059 -0.10408 -0.068403 0.22865 0.15968 -0.12043 0.17138 -0.09117 0.0035199 0.043324 0.23696 -0.022424 0.011824 -0.082673 0.21019 -0.029366 -0.31642 0.093056 -0.042443 0.096904 0.0029256 -0.023544 0.027587 0.18325 0.028752 -0.012757 -0.074628 -0.19008 -0.33032 0.014832 0.023042 -0.30714 -0.0051089 -0.2806 0.28887 -0.28527 0.08489 -0.13245 0.031083 0.096405 -0.083038 0.075022 -0.074193 -0.10781 0.23301 -0.018352 0.076494 -0.12163 0.016636 -0.071522 -0.36442 -0.18188 0.16523 0.24855 0.27905 -0.029587 -0.13194 0.017264 0.032602 0.024678 0.043709 -0.12155 -0.094618 0.034384 0.013231 -0.14725 -0.13656 -0.12586 -0.063581 0.21182 -0.33222 0.27593 0.00076818 0.23512 -0.17294 -0.05502 -0.042188 0.056569 -0.075554 0.10821 -0.10783 -0.12396 -0.21411 -0.097453 0.1037 -0.042007 0.027932 -0.047195 0.0010598 0.0010419 -0.016564 0.061864 0.0024039 0.22027 0.17753 0.03071 0.36608 0.078102 -0.027116 -0.032718 0.37169 0.091258 -0.087317 0.0058107 0.13911 0.022874 0.36481 -0.08171 0.047501 -0.27414 0.17094 0.097376 0.1034 -0.10736 -0.025921 0.12131 -0.16938 -0.11803 0.070568 0.049375 -0.08653 0.075679 0.028489 -0.21527 -0.22059 -0.11428 0.046701 -0.046209 -0.22721 -0.048625 -0.070138 -0.23841 -0.085484 -0.14931 0.23539 0.4079 -0.027133 0.091937 0.28157 -0.27637 -0.06226 0.18938 0.13038 0.052101 -0.16478 0.21915 0.24318 0.062355 -0.082933 -0.34179 0.028754 -0.28708 0.086175 0.17013 0.2272 0.015207 -0.24225 0.041857 -0.19292 0.1254 0.20591 0.085465 -0.092265 0.18977 -0.17464 0.19815 -0.12635 -0.082679 -0.35229 -0.058289 0.044128 -0.15709 -0.37541 0.12154 0.061869 -0.24952 -0.014607 0.14386 0.036606 0.053013 -0.016534 -0.090166 0.078929 0.10665 0.11283 0.23588 0.18032 0.21043 -0.033601 0.029407 -0.022544 0.061579 0.020573 0.0072942 -0.10252 0.074378 0.19089 -0.33314 -0.31071 0.027403 -0.14254 -0.12556 0.12013 -0.059785 -0.096796 -0.10645 0.10526 0.010426 0.1235 -0.03647 -0.045269 0.0084907 0.072174 0.0030122 -0.12617 0.083128 0.30058 0.10765 0.053047 0.20872 0.0082084 -0.13375 0.23055 -0.0061244 0.019615 -0.023229 0.063003 0.15248 0.0087041 -0.2119 -0.012478 -0.037575 0.0078768 -0.01821 0.010409 0.0086983 -0.096311 0.17742 0.22879 -0.15267 -0.087855 -0.26727 0.083071 -0.15516 0.27652 -0.12538 0.089815 0.063362 0.0892 0.17262 -0.13381 -0.11419 -0.19908 0.23679 0.20202 0.11059 0.034961 0.039949 0.029348 0.070962 -0.14683 -0.039284 -0.03305 -0.046532 0.058446 -0.066828 0.36073 -0.0019005 0.066695 0.078978 0.057812 0.041522 -0.17791 -0.27556 0.23043 0.10307 -0.042208 +# -0.33783 -0.46272 0.53584 -0.26954 -0.21923 -0.51357 -0.020408 0.30215 0.086283 -0.11499 0.21559 0.08347 0.027916 -0.15428 0.083918 0.0094827 -0.14005 0.33949 0.086982 0.39701 -0.18131 0.054713 -0.11132 -0.19203 -0.28342 -0.089512 -0.011969 -0.40963 0.037766 0.015782 -0.12584 0.51497 -0.39823 0.35138 -0.00721 -0.11274 -0.26757 -0.068547 0.013989 -0.2845 0.36509 0.19542 0.1625 -0.27281 0.48504 0.19891 -0.41764 -0.14692 -0.13238 0.17459 0.048818 -0.23589 -0.052575 -0.23342 -0.124 0.064905 0.29386 0.029794 0.2198 0.2797 -0.0029884 -0.14927 -0.0049408 0.031577 -0.26179 -0.12889 0.089082 0.20452 -0.0060433 0.12221 0.14067 -0.12217 0.23624 0.21083 -0.15396 -0.079872 0.37937 -0.13856 -0.039084 0.73861 0.068836 -0.18625 0.045758 -0.066132 0.18613 0.27695 0.28147 -0.42515 0.23793 -0.14631 0.22993 0.61561 -0.060574 -0.35097 0.16792 0.051053 -0.16009 -0.29895 -0.19505 -0.10886 0.22052 0.08863 -0.21225 -0.35091 0.34576 -0.21251 -0.42654 0.34126 0.37348 -0.29739 0.080974 0.18524 0.12869 -0.13522 0.080356 0.02311 -0.1287 0.24801 -0.30035 -0.070724 0.5898 -0.041647 0.019651 0.41622 0.085958 0.16588 0.097476 0.1847 0.012092 0.27236 0.031466 -0.26864 0.25659 0.23726 0.12217 0.055035 0.10406 -0.20587 0.12583 -0.028772 -0.034486 0.13546 0.54517 0.1462 -0.0019388 0.18521 0.14408 0.17377 -0.28288 0.0087268 -0.036924 -0.12551 -0.15365 -0.13336 -0.026043 0.075122 -0.019026 0.25856 0.048164 0.10764 0.18018 -0.029612 -0.36647 -0.040401 0.033421 0.19999 -0.001088 0.041551 0.18175 0.25653 -0.073287 0.13692 0.3381 -0.06364 0.28354 -0.14146 0.2793 -0.26352 -0.1599 -0.22268 0.32419 -0.2956 0.072796 0.084997 -0.25965 0.29456 0.083395 -0.22549 0.36079 0.047755 0.2922 -0.30838 -0.30739 0.26905 -0.065897 -0.17941 -0.069243 0.0068263 -0.17722 -0.13962 -0.11422 -0.19855 -0.011729 0.080025 -0.3121 -0.0019622 -0.35791 -0.043522 0.2897 -0.1919 0.58294 -0.29888 -0.18156 -0.44678 -0.17355 -0.26505 0.31321 0.083984 -0.31756 -0.39807 -0.17084 -0.094566 0.22088 -0.12916 -0.07987 0.28702 -0.25852 0.079283 0.16494 0.10749 0.11516 0.53328 -0.11709 -0.51756 0.0016254 -0.11559 -0.31293 0.17525 0.18469 -0.20247 -0.012455 0.1085 0.11426 0.075326 0.30413 0.096684 0.14044 -0.067963 0.094512 -0.16993 0.2779 -0.39712 -0.1915 0.29722 0.039612 -0.47851 -0.35353 0.025193 -0.054657 -0.064994 0.23585 0.013337 0.25461 -0.092264 -0.084375 0.22177 -0.20684 0.12507 0.25479 -0.15971 -0.36794 -0.16522 0.11729 -0.402 0.21877 0.021249 0.13236 0.24137 -0.19358 -0.41206 -0.050856 0.23663 0.058664 0.25135 0.37349 0.47308 0.20536 -0.0039965 -0.19092 -0.0091019 0.22861 -0.16327 0.061961 0.070545 0.34505 -0.2439 0.24747 -0.20806 0.16926 0.41103 +one -0.15975 -0.11947 0.1206 -0.058631 0.0045518 0.16518 0.057441 -0.11684 -0.041827 0.12017 0.13869 -0.16179 0.012515 -0.10794 -0.09677 -0.12759 -0.01096 0.029151 -0.045737 0.19192 -0.0029964 0.13029 -0.18603 -0.2492 -0.021503 0.038976 0.062091 0.18154 0.026974 -0.041506 0.068561 0.043121 -0.1334 0.19927 -0.082706 -0.206 -0.011017 -0.015346 0.035709 -0.091467 -0.015454 -0.13002 0.013462 -0.074707 0.13672 0.11459 -0.00042464 0.087671 -0.041594 -0.26236 0.11727 -0.032542 0.15327 0.084043 -0.15323 0.12151 -0.039098 0.21431 -0.17078 0.064537 -0.010708 -0.22635 0.19764 -0.079257 -0.17399 -0.074398 -0.30092 -0.076673 0.15798 -0.046183 -0.0098803 -0.1065 0.22805 -0.2408 0.083646 0.078239 0.30403 0.19219 0.0015495 0.0924 0.28751 -0.051705 -0.075722 0.047296 -0.055046 0.008757 -0.1959 0.14364 -0.074343 -0.23497 0.041986 -0.021902 0.42028 -0.12753 0.084303 -0.060725 -0.022756 -0.025223 -0.10213 0.12902 0.081798 -0.09211 0.19358 0.15622 -0.068493 -0.17788 0.011035 0.080236 0.019854 0.0012992 0.033226 0.060357 0.0045871 -0.11683 -0.0023224 -0.22026 0.22241 0.10597 -0.10742 0.21804 0.24079 0.18627 0.058723 0.3724 0.058639 0.10556 0.24689 0.31107 -0.012539 0.20886 0.055165 0.084453 -0.044919 0.025486 -0.10533 -0.13423 -0.050619 0.074831 0.0018074 -0.025952 -0.025049 -0.090231 0.18106 0.0095015 0.088309 0.12771 -0.024992 0.012467 -0.073079 -0.030617 0.077176 -0.20627 0.016879 -0.1694 -0.098233 0.031944 0.13219 -0.024618 0.38094 0.049089 -0.14601 0.21354 0.12951 -0.012339 0.20741 0.084643 0.063456 0.13952 -0.012555 -0.075766 0.078254 -0.14594 -0.13576 -0.06962 -0.1481 0.10953 0.13115 0.091209 0.22203 0.024187 0.094425 0.10661 -0.12666 0.10078 -0.24013 -0.086848 0.16123 -0.16499 0.15834 -0.10613 0.025616 -0.24812 0.064194 0.14945 -0.11716 -0.023196 0.09408 0.1758 -0.14415 0.0091053 -0.089035 -0.15269 0.20287 -0.048679 0.10999 -0.19199 0.016916 0.16987 0.13407 0.14832 0.25561 -0.11481 0.045976 -0.10453 0.30471 -0.15655 -0.061218 -0.30802 -0.026884 0.12473 -0.039791 -0.041234 -0.226 0.15898 0.054095 0.061063 -0.073954 0.1043 0.22585 0.031939 0.12919 -0.096408 0.0081266 -0.16276 0.0072641 0.0078385 -0.083285 -0.051933 0.10724 -0.09901 0.022409 -0.13039 0.098835 0.12858 0.2241 0.35791 0.14927 -0.0027789 -0.012156 -0.052336 -0.028042 -0.12707 -0.30563 -0.13107 -0.034678 0.057156 -0.11817 0.053926 -0.030918 -0.081919 0.03569 0.20399 -0.058047 0.040065 -0.26625 -0.19684 -0.10962 0.0073118 -0.042628 -0.3038 -0.13094 0.058487 -0.022466 -0.018682 -0.080546 -0.13088 0.083377 0.18244 -0.040967 -0.0075252 0.17436 0.056789 -0.082256 0.10226 0.055698 -0.12877 0.14352 0.074599 -0.11855 0.13643 0.052458 -0.07947 0.047825 0.040355 0.0064958 -0.017689 -0.060724 0.13168 0.19878 -0.029531 +rd -1.1506 -0.53222 -0.12513 0.24516 -0.044497 0.071324 0.2212 0.30723 -0.53325 -0.65087 0.078443 0.15601 -0.59255 -0.20201 0.26252 -0.20066 -0.21912 0.41569 0.1706 0.64272 0.52688 -0.66402 0.17654 -0.15823 -0.46057 -0.23955 0.06709 -0.37887 0.030493 0.61101 -0.25793 -0.092593 0.31114 0.25795 0.14443 -0.7101 -0.43319 0.3743 0.00040208 -0.40611 0.53347 0.53557 -0.011311 -0.046855 0.7912 -0.081955 0.37833 0.12741 0.3237 -0.014835 0.01076 -0.36059 0.010903 -0.48337 -0.19585 -0.1163 0.32341 0.29752 -0.42582 0.29559 -0.026663 -0.47067 -0.18093 0.054899 -0.23599 0.47633 0.21212 -0.43929 -0.44011 0.049869 0.2901 0.32495 0.43541 -0.35405 0.17429 0.14343 0.21127 0.24423 -0.2296 -0.099936 -0.73098 -0.13036 -0.28419 -0.038316 -0.18245 0.069179 -0.28172 -0.44685 -0.084947 0.079225 -0.47762 0.24751 0.011895 0.43968 0.23164 0.27289 -0.18501 0.11414 0.18385 -0.18625 0.4081 0.053863 0.11322 -0.076036 0.24222 0.12916 0.36993 0.076587 0.023933 -0.14553 -0.16695 0.47063 0.18966 0.21221 0.27879 -0.1734 0.14801 0.063849 -0.356 -0.10932 0.27571 0.24499 0.28805 0.47444 -0.27962 -0.13797 0.25603 0.34962 0.04083 -0.29996 -0.1505 0.38472 -0.23068 0.29573 0.45936 0.091195 -0.37063 -0.20439 0.0065503 0.32137 -0.55914 0.091268 0.34138 0.56403 0.080535 0.91205 0.43865 0.32759 -0.33666 -0.27557 0.038318 0.32302 -0.2694 0.60063 -0.45281 0.32183 -0.11218 -0.37466 0.11372 -0.44513 0.12644 -0.094009 0.18284 -0.25606 0.43177 0.097998 -0.37742 0.35549 0.47012 -0.003429 -0.19644 0.33319 -0.193 0.31495 -0.1205 0.82368 -0.1781 0.060243 0.20036 -0.22298 0.084018 0.3069 -0.65609 -0.17576 -0.54272 0.7062 -0.20235 -0.24904 0.49256 -0.6516 -0.17595 0.11237 0.17609 0.36525 -0.17019 -0.22523 -0.15181 0.22033 -0.339 -0.38465 0.2427 0.1794 -0.088431 0.25001 0.029498 -0.57946 0.49922 -0.020088 0.74543 0.48342 0.60401 -0.38432 0.19858 -0.3588 -0.29679 -0.47735 -0.011448 -0.16365 -0.04918 0.39467 -0.29667 0.36901 -0.15962 0.18151 -0.72476 0.38553 0.0036152 0.31533 -0.049102 0.42861 0.317 0.26095 0.072854 -0.083571 -0.23165 0.36299 0.27881 0.015 -0.053529 -0.31267 -0.3332 -0.12547 0.43742 -0.50906 0.21175 -0.63012 -0.18907 0.2023 -0.55823 -0.38016 -0.18399 0.51233 -0.022029 -0.010926 0.049053 0.21971 -0.045781 -0.52667 0.25465 0.15584 -0.029283 -0.1275 0.34815 0.4716 -0.10404 0.058572 0.18349 0.11524 0.26726 -0.16695 0.0032392 -0.019125 -0.25667 -0.10205 -0.20139 -0.52388 0.45371 0.58223 0.26213 -0.014628 -0.061389 0.59443 -0.17744 -0.49786 0.24411 0.31045 -0.38686 -0.041837 -0.20336 0.22771 0.12722 -0.8523 0.3123 -0.17051 -0.10118 0.00091675 0.027635 -0.28538 0.41543 0.21071 +new -0.12955 0.24179 -0.10623 0.29449 0.1131 0.0093337 -0.070727 0.088183 -0.33985 0.39531 0.12979 -0.18196 0.43787 -0.056544 -0.19537 -0.21653 -0.25153 -0.19905 0.26231 0.084574 -0.28642 0.030997 -0.024378 -0.41437 -0.1748 -0.20716 0.1654 -0.0025792 0.12467 0.11477 -0.085216 0.17012 -0.1149 0.48666 0.10669 0.13098 0.11514 -0.28485 0.039327 0.053211 0.0006997 -0.14654 0.011879 0.46906 -0.11752 -0.10176 0.077026 -0.027737 0.0089576 -0.27024 0.045685 0.0055222 -0.033356 -0.017371 -0.00048905 0.14575 0.10295 0.13754 0.16308 0.077965 -0.029517 0.00013956 0.36202 0.12424 -0.0093344 -0.027041 -0.21092 0.13414 -0.24618 -0.090988 -0.0051445 0.48305 0.15938 -0.39123 -0.019111 -0.041795 0.16712 0.065207 0.21199 -0.0041642 0.15393 0.33902 -0.18736 0.04337 0.028464 -0.16128 0.10977 0.19242 -0.15161 0.0022597 -0.40183 0.020187 0.084292 0.27929 -0.027309 0.020892 0.042743 -0.066257 -0.087884 -0.011187 0.23146 -0.32981 0.1602 0.12829 -0.039458 0.039933 -0.26897 -0.040194 -0.032107 0.101 -0.08744 -0.078672 0.069851 0.0030479 0.083331 -0.14878 0.094587 0.10227 -0.24684 0.25061 0.15938 0.012483 -0.28118 0.34362 -0.30959 -0.13498 0.24835 -0.11417 0.14903 0.4254 -0.21527 0.20214 0.057823 -0.092157 -0.085088 -0.21882 -0.24462 0.074187 -0.18674 -0.074741 0.44042 0.26897 -0.22469 0.052153 -0.070826 0.35453 0.066469 0.028829 0.11349 0.35387 0.049402 0.13582 0.22257 -0.11815 -0.17412 0.00087315 0.14012 -0.26935 -0.10264 0.12585 0.18673 0.41584 0.18244 0.14853 0.43969 0.10556 -0.1059 -0.10544 -0.00091309 -0.18417 -0.056499 -0.044492 0.071062 -0.039341 -0.2701 0.014851 -0.22695 0.0087606 -0.1144 0.18396 0.035879 0.011803 -0.0013004 0.23599 0.16706 0.30801 0.038263 0.0009701 0.12152 0.19159 -0.3046 -0.36948 0.24153 0.19957 -0.010587 -0.10623 0.28107 0.24005 -0.23075 -0.045219 0.33029 -0.11888 -0.39559 -0.16307 0.19163 -0.43538 -0.1871 0.011505 0.4005 0.074896 0.31542 -0.25711 -0.09735 -0.45449 0.062201 -0.34596 0.0015342 -0.033099 -0.12706 0.16169 0.013766 0.14263 -0.16703 0.14728 -0.14568 0.049475 -0.20949 -0.012764 -0.14162 0.23032 0.20316 0.055513 0.2356 0.027813 0.18818 -0.39263 -0.079622 0.25344 -0.10851 -0.05999 -0.064461 0.053858 0.028328 -0.025627 0.20152 0.39267 0.22053 0.23862 0.35199 -0.080319 0.40317 -0.051639 -0.028799 -0.0059812 -0.02006 0.10853 0.038202 -0.13835 0.24992 0.16572 0.17968 0.1112 0.213 0.17364 -0.13088 0.042258 -0.070842 0.13065 -0.28965 -0.017642 -0.026392 -0.24336 -0.093841 -0.085507 -0.24265 -0.20142 0.15112 0.18707 0.22868 0.15166 -0.26356 0.12302 0.14609 0.13897 0.13981 -0.033191 -0.35564 -0.22532 -0.16505 -0.043178 0.13238 -0.082657 0.082819 -0.090364 -2.5277e-05 -0.2816 -0.11103 -0.024509 0.060905 0.25074 +first -0.18501 -0.020656 0.013468 0.080072 0.15848 0.077652 -0.17286 -0.062626 0.03685 0.093325 0.14926 0.095012 0.034983 -0.070536 -0.01886 -0.21087 -0.073209 0.046374 -0.049039 0.25491 0.20739 -0.0038093 -0.064161 -0.37491 -0.17631 -0.12171 -0.071142 0.034826 -0.027048 0.059557 -0.13166 -0.15029 -0.058682 0.0043365 0.073276 -0.2614 0.11214 0.076434 0.13177 -0.35367 0.18815 -0.038915 -0.14137 0.035661 -0.039416 -0.028954 -0.0088364 0.04533 0.041871 -0.036881 0.093625 0.059692 0.11834 -0.00077996 -0.051154 0.12762 0.035008 0.13595 0.10694 0.01339 -0.02663 -0.11904 0.080367 -0.098269 0.070955 -0.19735 -0.33299 0.25476 0.026776 0.19078 0.07554 -0.063196 0.18595 -0.12805 0.15236 -0.058321 0.23472 0.1434 0.05745 -0.11081 0.18194 0.12132 -0.17389 -0.011545 0.003841 -0.28814 -0.27059 0.0133 -0.085491 -0.15749 -0.20665 -0.17703 0.42666 -0.01708 0.099522 -0.19859 -0.073646 0.19781 -0.16378 0.16586 0.0010184 -0.10732 0.22438 0.041504 -0.0066085 -0.15476 0.090945 -0.041936 0.162 0.067129 0.2207 -0.015094 0.14988 -0.060156 0.037418 -0.14087 0.11635 0.17485 0.15556 0.056476 0.30164 0.00048755 -0.15577 0.40593 0.17787 0.10232 0.35935 0.12156 0.22889 0.1697 -0.072115 0.1616 -0.059683 0.012007 0.029971 -0.069382 -0.051313 -0.042249 -0.015726 0.11086 0.080265 0.10537 0.34406 -0.033952 -0.026585 0.33055 0.044762 -0.12563 0.022151 -0.0059314 -0.065732 -0.089251 -0.067698 -0.041101 -0.24027 0.078363 0.023734 -0.061767 0.14534 0.0017447 -0.075184 0.23502 -0.055807 0.062096 0.27978 0.17767 -0.024348 0.332 0.29577 -0.019764 0.03667 0.12557 -0.039628 -0.11762 0.012928 0.10547 0.024665 0.18401 -0.033457 -0.047673 -0.013899 0.023513 -0.28268 0.12474 -0.14565 0.26212 0.15513 -0.15004 -0.012862 -0.12302 -0.05961 -0.10883 0.064208 0.066889 0.0099247 -0.19963 -0.046666 -0.079046 0.044068 -0.16711 -0.046667 0.19004 -0.10784 0.014607 0.18075 -0.2614 -0.039048 0.13739 0.38794 0.3453 0.39875 -0.18913 -0.015323 -0.11855 -0.028095 -0.11864 0.041397 -0.12161 -0.27637 0.29 0.10307 -0.012667 -0.086965 0.22868 -0.10608 0.18905 -0.13645 -0.17904 0.095407 -0.087892 0.24102 -0.018986 -0.043618 -0.090145 0.1517 0.064428 0.059362 0.040603 -0.096987 -0.21232 -0.32531 0.086149 0.13176 0.056504 0.076689 -0.0025941 0.092582 0.15293 0.083922 -0.16652 -0.032714 0.019814 -0.011476 0.031839 -0.042109 0.085543 -0.31194 0.091586 -0.15964 -0.11322 0.21244 0.19689 -0.033659 -0.0051993 -0.062106 -0.0016829 0.047401 -0.19752 0.30247 -0.13495 -0.32111 -0.081742 -0.10655 0.13892 -0.20922 -0.069019 0.11526 0.065076 0.18484 0.024973 0.01456 -0.026564 0.016125 0.07159 0.37791 -0.11048 0.036626 0.1698 -0.06143 0.011747 -0.035502 -0.12379 0.17471 -0.04164 -0.04867 0.082536 -0.014208 -0.22912 0.00083986 0.15648 +page -0.32935 -0.036416 0.17821 -0.072867 -0.32466 -0.42039 0.032688 -0.0049149 -0.078871 -0.17333 -0.01095 -0.13075 -0.16793 -0.13803 0.55748 0.099044 -0.22223 -0.022698 0.51157 0.22466 0.040375 0.52957 -0.051943 0.059649 -0.27743 -0.33979 -0.08659 0.061577 0.35921 -0.0017234 0.29639 0.08754 -0.4021 -0.10301 -0.24128 -0.26396 -0.11806 0.02772 -0.11039 -0.61078 0.15757 -0.1091 -0.27818 0.12356 0.15937 -0.16149 0.076484 -0.14555 0.13721 0.015057 0.29169 -0.34808 -0.022412 -0.18246 -0.13372 0.41472 0.059405 -0.42064 -0.20175 0.2882 0.066617 0.28121 0.058301 -0.11666 -0.035873 -0.26573 0.48025 0.39234 0.021312 0.26535 0.34666 0.31004 0.43961 -0.47645 -0.0079027 0.065862 0.33676 0.46505 -0.22238 -0.19823 -0.064554 0.29617 -0.046413 -0.0032442 0.089318 -0.32391 -0.06996 -0.23369 -0.22887 -0.19728 0.15682 0.051657 -0.16983 -0.2037 -0.29197 0.055086 -0.2591 -0.13269 0.01839 0.29623 0.044336 -0.85969 -0.002254 -0.20968 0.44827 0.6723 -0.48393 0.13781 0.19926 0.0081333 -0.14694 0.21927 0.26691 -0.12379 -0.097714 -0.03867 0.33845 0.23155 -0.36169 -0.079136 0.35399 -0.05884 0.34019 0.29243 0.50704 0.23601 -0.20424 0.27046 0.019574 0.43983 0.021816 -0.50183 -0.094589 0.15839 0.0049928 0.40533 0.21622 0.16044 0.18233 0.55841 -0.27192 -0.0052973 -0.047076 0.34039 -0.20456 -0.11014 0.21802 0.3518 -0.33288 0.40795 0.18924 0.29725 0.37474 0.02536 -0.15789 -0.091439 -0.036944 -0.29901 0.19366 0.19159 -0.33367 0.66268 -0.27724 -0.065702 -0.092032 -0.32639 0.013295 -0.40618 0.5739 0.40851 -0.096819 0.087009 -0.93229 -0.42478 -0.38444 -0.083451 -0.22174 -0.20958 0.21672 -0.40394 -0.22581 0.16658 0.0077905 -0.25866 -0.42461 0.52642 0.21446 -0.23286 0.13929 0.33895 0.17342 -0.19405 0.29159 -0.40204 0.17765 -0.19944 0.057563 0.1624 -0.75826 0.24378 0.24884 -0.21107 0.31785 -0.28324 -0.076239 -0.45568 -0.11928 0.11481 0.25831 -0.1287 0.64648 -0.26588 0.068094 0.088482 -0.012339 0.0032776 0.59013 -0.37706 0.070246 0.18547 -0.061602 0.18333 -0.29945 -0.14055 -0.18469 -0.015662 -0.41096 -0.12466 -0.2743 -0.08502 0.10479 -0.018603 -0.18316 -0.092946 -0.18514 0.11231 0.64229 -0.46814 -0.062047 -0.15859 0.22507 0.35887 0.72966 0.28192 0.35383 0.22387 0.16092 0.15542 -0.022658 0.15926 0.51296 -0.30223 -0.23345 0.03058 0.51312 -0.086032 -0.25122 -0.44968 -0.21821 -0.10037 0.35106 0.02112 -0.21914 0.18215 -0.070668 -0.13122 0.054451 0.42324 -0.26893 -0.1611 -0.10147 -0.024244 0.089611 0.13109 -0.3058 -0.27557 0.232 -0.32436 0.36504 -0.084774 -0.065878 0.3446 -0.32642 -0.24216 0.11379 -0.23374 0.2925 0.20107 0.15402 0.019004 0.15976 0.1663 -0.325 -0.3723 0.35838 0.021576 -0.11469 0.14285 0.15968 0.3538 +no -0.2643 0.034339 0.0466 0.1818 0.077419 -0.31439 -0.0055325 -0.16168 0.010331 -0.070391 -0.0293 -0.013119 0.14472 0.10077 0.15029 0.11151 0.12948 -0.078568 -0.038936 -0.069117 -0.02862 0.19472 -0.018243 -0.05659 -0.21891 0.42935 -0.19713 0.020947 0.12544 0.061052 -0.085741 0.23646 0.047816 0.12213 -0.14506 -0.27841 -0.036634 0.052511 0.00044411 -0.24736 0.2888 0.17881 -0.15564 -0.10495 0.10472 0.081415 0.32859 0.081788 0.1091 -0.18074 -0.15581 -0.31819 -0.11834 -0.0038618 -0.38857 0.082629 -0.17706 -0.0015596 -0.19932 0.37683 -0.35489 0.044217 0.46263 -0.047725 0.047667 -0.28284 0.18534 -0.027313 -0.052813 0.18889 -0.049962 0.18343 -0.028636 -0.049944 0.14916 -0.10098 0.21242 0.16436 0.26371 -0.10826 0.077146 -0.039786 0.25458 -0.1046 -0.079576 -0.019773 -0.30416 0.13349 -0.1003 -0.069873 -0.189 0.072886 0.12898 -0.18529 -0.052076 -0.17322 -0.1696 0.24536 -0.14722 0.18812 -0.040378 -0.43597 -0.044428 0.18643 0.16435 0.008577 0.0029248 -0.18135 0.10601 -0.21964 -0.4862 0.090768 0.01968 0.25073 0.018652 -0.15171 0.47005 0.14804 -0.10247 0.14386 0.68539 -0.027273 0.17492 0.086974 0.15731 0.026635 -0.14577 0.21314 0.05424 0.23508 -0.029212 -0.35641 0.024078 0.31589 0.16009 -0.013141 0.019247 -0.33484 0.092813 0.035008 -0.19227 -0.090595 0.01931 0.28161 0.13771 0.21892 -0.1286 0.16683 -0.021937 0.13536 -0.27862 -0.020338 0.024459 -0.18298 -0.24355 0.06391 0.16413 -0.14908 -0.13719 0.27537 -0.20374 0.24959 -0.13618 0.17088 -0.41502 -0.13784 -0.11341 -0.12433 -0.13826 0.32331 0.23585 0.075066 -0.58236 -0.1011 -0.15315 -0.18672 -0.15112 -0.16722 0.12736 0.015317 0.070823 -0.079822 0.018665 0.43254 -0.3767 0.20951 0.098743 -0.29383 0.21868 0.27414 -0.18188 -0.3688 -0.29828 -0.13399 -0.3173 -0.18554 0.0018321 0.17532 -0.70552 0.15625 0.059171 -0.0079576 0.26087 0.034321 -0.098771 -0.486 -0.35527 -0.039002 0.075376 0.34163 0.48625 -0.53015 0.064528 -0.35176 -0.27263 -0.082661 0.082817 -0.35417 -0.1888 0.0075962 -0.044557 -0.20698 -0.017113 0.14535 -0.13753 0.10438 -0.17524 0.028008 -0.047275 -0.12366 0.28077 0.19532 -0.13123 -0.049223 -0.096767 0.56907 0.26118 0.0877 -0.2188 -0.1295 0.1385 0.03949 -0.00012694 0.30245 -0.069872 0.40636 0.21411 0.093625 0.10418 -0.069236 -0.048681 -0.30863 -0.088241 0.062921 0.33313 0.18371 -0.49342 -0.16211 -0.17221 -0.037731 0.079831 0.063734 -0.1324 -0.046848 -0.20139 0.12814 -0.13614 0.0047057 0.037959 -0.10353 -0.1395 0.19528 0.36036 -0.049478 -0.17034 -0.14192 -0.027111 0.08613 0.034346 -0.16021 0.12881 -0.13749 -0.34138 -0.2616 0.345 -0.20288 0.23539 0.40727 -0.27571 -0.0046924 0.19462 -0.18622 -0.30724 0.084037 -0.15362 -0.54617 -0.13526 -0.051155 -0.090351 0.05143 +you -0.14926 0.21572 0.18823 0.060467 -0.16004 0.081722 -0.11272 -0.2495 -0.0991 0.17575 0.14676 0.020036 -0.24832 -0.099823 0.17819 -0.18441 0.0034034 0.12738 0.0044833 0.0189 0.059595 -0.034684 -0.096218 -0.1155 -0.16384 -0.079494 -0.063366 -0.037051 -0.31197 0.036276 -0.17995 0.028729 -0.22288 0.068523 -0.27248 -0.16194 -0.047037 -0.074107 -0.11411 -0.27279 -0.14149 -0.1819 0.049754 -0.040176 0.10649 0.27621 0.020151 -0.046383 -0.19623 -0.0090757 0.056723 -0.35709 -0.093485 -0.058048 -0.090262 0.29478 -0.21296 -0.19898 -0.021059 0.42529 -0.2842 0.059192 0.14928 0.082141 0.081786 -0.20462 0.16487 0.21021 -0.0079651 -0.06322 0.022311 -0.061235 0.16665 -0.081486 -0.21084 0.29053 0.21792 0.10419 0.066359 0.20361 0.0058033 0.33518 0.098701 0.13497 -0.045183 0.095704 0.031015 0.0062269 -0.10564 0.075817 0.23904 0.089361 0.11111 -0.17585 0.2697 0.24838 0.072762 -0.12871 0.12033 0.29181 0.16135 -0.057687 0.1148 -0.16434 -0.34884 -0.089657 -0.017261 0.0355 0.12192 -0.018161 -0.0568 -0.026025 -0.020209 -0.027063 -0.24497 -0.086863 0.14692 -0.11877 -0.2132 0.12687 0.22907 0.17375 0.031288 0.6295 0.13077 0.10494 0.010939 0.059313 -0.036097 0.40596 0.097957 0.15766 -0.27526 0.16212 0.052394 -0.29225 -0.0031506 -0.0088115 0.57996 0.16109 -0.12084 -0.035637 0.027943 -0.083463 -0.32062 0.042923 0.026398 -0.27274 0.032771 0.035626 0.43356 0.13449 0.35889 -0.091434 0.12423 0.06327 -0.02851 0.037847 -0.051596 0.057026 -0.21843 0.28021 -0.55111 -0.17753 -0.042664 -0.015736 -0.29045 -0.18981 0.14331 0.14611 -0.5666 -0.23695 -0.41243 0.0030795 -0.036383 0.27025 -0.020164 0.19496 0.037875 -0.44485 0.2022 -0.1458 0.061848 0.0315 -0.32115 0.24994 0.017794 -0.4718 0.1929 -0.22511 -0.010451 -0.18739 -0.061101 0.16788 -0.16174 -0.11634 -0.15998 0.024648 -0.44889 -0.0060595 0.56559 -0.011015 0.39797 -0.15973 -0.067796 -0.10597 -0.36092 0.091726 0.19276 0.096221 0.19963 -0.038562 0.096973 -0.2475 -0.018474 -0.2174 -0.14971 -0.21159 -0.20265 0.050573 -0.27651 -0.19033 0.029003 -0.094018 0.0051184 0.29676 -0.28251 0.15488 -0.07178 0.0099408 -0.0012008 0.11359 -0.08789 -0.018188 0.056809 0.05057 -0.038582 0.024707 -0.10994 0.12803 -0.062006 0.062169 0.21328 0.12365 -0.25733 0.28885 0.30688 -0.019757 0.1401 -0.088862 0.069914 -0.21663 -0.28538 0.28921 0.25058 -0.19068 -0.073818 -0.22429 0.076213 0.035377 -0.16019 0.15335 -0.18592 -0.1623 -0.06816 -0.14475 -0.21013 0.26626 -0.11165 -0.17628 -0.18955 -0.15504 0.21453 -0.10902 -0.14164 0.026173 0.30544 0.021876 -0.14254 -0.37952 0.065484 0.086204 -0.35292 -0.051159 0.073312 -0.18833 0.27411 0.32466 -0.26751 0.29403 -0.11763 0.41755 -0.13553 -0.38416 0.12977 -0.01527 -0.32165 0.32328 0.38224 -0.086828 +they 0.011692 0.11158 -0.15517 0.2397 0.001333 0.16949 0.2118 -0.1211 0.016811 0.19858 0.031513 -0.048707 -0.10157 -0.13255 -0.011433 -0.20104 0.14669 -0.04656 -0.031949 -0.097005 -0.084464 -0.10446 -0.061355 -0.21277 -0.12353 0.0081873 0.14986 -0.023631 -0.060642 -0.069951 -0.14559 -0.10824 -0.20978 0.052859 -0.014248 -0.11086 -0.035697 0.075892 0.073082 -0.21082 0.087626 0.12786 -0.012736 0.11 0.0049951 0.18668 0.1675 0.11868 -0.045669 -0.14681 0.05544 -0.19966 0.077428 0.24323 -0.23443 -0.036019 -0.098782 0.29555 -0.19549 0.19649 -0.26849 -0.15973 0.10533 -0.069128 0.13753 -0.22219 -0.20939 0.25629 -0.19427 0.085076 -0.21863 0.031262 -0.083517 -0.40865 -0.17838 0.10146 0.24578 0.13218 -0.050354 -0.14911 -0.11367 -0.057818 -0.10198 0.22363 -0.11553 0.05735 -0.051279 0.042011 0.11563 -0.057654 -0.22652 -0.10451 0.10616 -0.15652 0.14962 0.16096 0.17957 -0.18526 0.058269 0.074962 0.070254 -0.0059412 0.14291 -0.32395 -0.29087 -0.081794 0.0075591 0.018076 0.099817 -0.018327 -0.022612 -0.16863 0.079299 0.089942 -0.011633 -0.073527 0.19285 0.11245 -0.20461 0.056416 0.036064 0.13425 -0.092469 0.32123 0.17184 -0.1811 0.20825 -0.020182 0.053391 0.33208 -0.10423 0.040727 -0.057244 0.022769 -0.18192 -0.12176 -0.043532 0.17403 0.0090458 0.0008529 0.073905 0.17705 0.0068493 -0.089645 0.07759 0.24634 -0.0071185 -0.14213 0.13309 -0.040683 0.10647 -0.22222 -0.01168 0.11632 -0.15885 -0.25939 -0.11116 0.19698 0.41329 -0.15419 -0.12563 0.29743 -0.29696 0.21828 0.044268 0.077094 -0.10614 0.0018781 0.2745 0.12095 -0.14752 -0.14184 -0.23053 0.038347 -0.058515 0.30806 -0.09998 0.064684 -0.090735 -0.15115 0.15639 -0.10176 0.11441 0.063421 0.0053369 -0.098623 0.10074 -0.041852 0.17853 -0.093273 0.076425 -0.32315 -0.025846 0.16625 -0.15878 0.0032325 0.042728 -0.0030261 -0.18063 -0.1121 0.1835 0.020397 0.07478 0.063549 0.012672 -0.21275 -0.032176 0.070672 0.30274 0.19403 0.15948 0.06162 0.071292 -0.022572 0.030547 0.010065 -0.032019 -0.11013 -0.15264 -0.017596 -0.25373 -0.18649 0.12997 -0.014768 -0.093668 0.17403 -0.17209 -0.018659 -0.11371 0.057783 0.11459 0.092727 -0.17607 -0.032631 -0.24071 0.079038 -0.048108 0.0013213 -0.047806 0.090104 0.028607 0.0084475 0.033609 0.04999 -0.12634 0.2445 0.08028 -0.009574 0.068611 0.019979 -0.013658 0.085524 -0.30875 -0.11951 0.14004 -0.028924 -0.085339 -0.2019 0.047855 -0.17116 -0.24662 0.075408 -0.282 -0.22474 -0.30327 -0.098362 -0.29202 0.1476 0.037455 -0.0090524 -0.17105 0.042401 0.079497 0.025789 -0.18195 0.016337 0.085997 -0.068473 0.026865 -0.10499 -0.045696 0.13818 -0.10552 -0.016427 0.061493 0.10936 0.10525 0.25517 -0.22034 0.13151 -8.7435e-05 0.17402 0.067917 0.073156 0.13097 -0.018703 -0.27613 0.048848 0.082782 0.19095 +had -0.061011 0.010058 -0.32809 0.092396 0.077896 -0.074404 0.027325 -0.24711 0.041686 0.36376 0.35095 0.29423 -0.11997 0.15142 -0.024691 0.045448 -0.07513 -0.059566 0.037441 0.07562 -0.017107 0.19917 0.052938 -0.31778 -0.27666 0.012372 -0.029857 0.17197 0.011413 0.063864 -0.013924 0.14229 -0.10703 0.22473 0.12469 -0.094732 -0.0056683 -0.064609 0.27862 -0.21153 0.37863 -0.094905 0.08367 -0.062527 -0.21712 -0.19702 0.14912 0.064912 0.090079 0.19501 -0.22187 -0.21876 -0.087046 0.36006 -0.17492 -0.067935 -0.049181 0.32526 -0.032316 0.093609 -0.045662 -0.11957 -0.0064419 -0.22971 0.23226 -0.071414 -0.12826 0.2421 -0.16111 0.074486 0.010463 -0.056933 -0.0915 -0.21807 -0.07052 0.20005 0.078136 0.2854 0.01052 -0.21247 -0.042688 -0.15003 0.11813 0.045613 -0.10047 -0.16224 -0.077305 -0.024148 -0.17841 -0.14778 -0.21352 -0.23945 0.058054 -0.32745 0.2449 0.20105 -0.045799 -0.2419 -0.15404 -0.10322 -0.13669 0.13554 0.1916 0.055884 -0.20864 -0.21649 0.011421 0.074247 -0.074617 0.064411 -0.022916 0.17333 0.16305 -0.03556 0.18725 0.010497 0.1716 0.18227 0.011231 0.19926 0.067768 0.2261 -0.13265 0.29135 0.15683 -0.22068 -0.11423 0.35239 0.015702 0.27533 -0.196 -0.0033808 -0.019336 -0.13076 -0.029763 -0.089218 -0.08591 0.017903 -0.061072 -0.1171 -0.0994 0.1007 0.03207 -0.049386 0.29804 0.2271 -0.12743 -0.23118 -0.10164 0.093309 0.036243 -0.015077 -0.034213 0.13656 -0.215 0.0071517 -0.11725 0.095421 0.41258 -0.12583 -0.067009 0.25806 -0.16428 0.22923 0.16807 -0.013319 0.1967 0.018716 0.19311 0.20619 0.041045 0.034263 -0.2587 0.10851 -0.14957 0.035486 -0.086389 0.19412 -0.28292 -0.12153 0.16414 -0.18647 -0.19356 0.26416 -0.13187 0.022635 0.030464 -0.28223 0.00356 -0.10424 0.12317 -0.29917 0.10044 0.14291 -0.22859 -0.15776 0.007948 0.019064 -0.17401 -0.17237 -0.094723 -0.085559 0.0053709 0.13346 -0.25342 0.056775 0.18015 0.054191 0.33902 0.25988 0.26561 -0.22873 -0.19818 -0.198 -0.062444 0.029075 -0.16799 -0.22731 -0.092907 0.13173 -0.25092 -0.086115 -0.0028387 0.028784 0.0019845 0.20323 0.069265 -0.017484 -0.069008 0.16074 0.015613 0.034536 0.010574 0.13477 -0.077238 -0.0061589 0.24216 0.10708 -0.013645 0.25305 0.11657 -0.017901 0.19301 0.15569 -0.22554 0.04049 -0.031989 -0.22953 0.041539 -0.011057 0.12676 -0.040454 -0.094416 0.024619 -0.068569 0.031699 -0.076244 0.20514 -0.16025 0.14737 0.037748 -0.076004 -0.04185 -0.18805 -0.37238 0.30261 0.10804 0.13789 0.091484 -0.05138 -0.10155 -0.045579 0.0775 0.030727 -0.23318 -0.21796 0.32142 0.35826 0.37295 -0.078928 0.14607 -0.12589 0.16444 -0.052781 -0.046721 0.12549 -0.12333 0.056958 0.066646 -0.026705 0.060562 -0.092281 -0.12031 0.2859 -0.051593 -0.039909 -0.068784 0.060296 -0.036769 -0.081526 +article -0.19484 -0.25781 0.074734 0.30936 -0.53333 -0.0034507 -0.28408 -0.47139 -0.17259 0.22078 0.09638 -0.22501 -0.065097 -0.098619 -0.012249 0.022184 0.025968 0.032922 0.084835 0.27744 0.00091942 0.23558 -0.06804 -0.049127 -0.028252 -0.39203 -0.1491 0.087022 0.36411 0.1768 0.0089704 -0.032694 0.017095 -0.0098417 -0.24813 -0.26272 -0.18639 0.11959 0.029033 -0.03187 -0.11867 -0.1965 -0.1604 0.0023741 0.18885 0.1208 0.055996 0.013848 0.39589 0.02607 0.32613 -0.27385 0.018989 -0.34079 -0.058834 0.070535 0.15765 -0.10814 -0.051752 0.068703 -0.0095383 0.3158 0.20771 0.095202 0.11373 -0.10667 0.10264 0.10504 0.22054 0.45565 0.19923 0.16751 0.028213 -0.12735 -0.14315 0.30489 0.21292 0.26121 -0.039596 0.13928 0.018696 0.36006 0.072499 -0.06338 0.38003 -0.14603 0.096935 -0.14983 -0.2022 -0.074128 0.08466 -0.069311 0.41959 -0.3692 0.13002 0.24023 0.15886 0.10486 0.083816 0.13714 0.058838 -0.44467 -0.093306 -0.012809 0.17936 0.23484 -0.21756 0.2205 0.13487 -0.048228 -0.43393 0.086656 0.02845 -0.0085932 0.16434 0.06756 0.23218 0.18332 -0.24891 0.034271 0.16093 0.28803 -0.03991 0.27858 0.14747 -0.074353 -0.078871 0.00018347 -0.00036125 0.13404 -0.038196 -0.10961 -0.023934 -0.20332 0.40041 0.26847 0.0649 0.15972 0.18134 0.53718 -0.2789 0.067847 0.28451 0.40038 0.051849 -0.11576 -0.0092854 0.43677 -0.20447 0.14346 0.16025 0.086152 0.48021 -0.2154 -0.23707 0.11371 -0.13944 -0.22741 0.31112 0.31751 -0.29874 0.59812 -0.22178 -0.18312 -0.074338 -0.35878 -0.0098884 -0.31093 0.23022 0.20448 -0.027582 -0.12797 -0.50302 -0.48345 -0.22991 0.23783 -0.32716 -0.16809 0.047807 0.050296 0.072429 0.16673 0.17296 0.22192 -0.42374 0.22401 0.3367 -0.28626 0.089167 0.30315 0.055827 -0.13332 0.16523 0.048936 0.013083 -0.36118 0.10012 0.025067 -0.5666 0.25612 0.10768 0.2433 0.13216 -0.091741 0.10924 -0.046029 -0.11008 -0.0096815 0.32672 0.13611 0.27605 -0.10756 0.27409 0.0018144 0.19602 -0.16108 0.22975 -0.25049 -0.052558 0.041897 -0.23199 0.05082 -0.16273 -0.195 0.1977 0.26203 -0.29299 -0.21003 -0.39179 -0.17639 0.2725 0.25077 -0.099151 -0.022226 -0.15606 0.057715 0.014136 -0.13818 -0.044941 -0.14227 0.039767 0.19135 0.7054 0.19974 0.27798 0.2819 0.30613 0.17933 -0.009568 -0.040708 0.24513 0.017751 -0.148 0.21938 0.11571 0.0084443 0.04122 -0.2741 0.12807 -0.18353 0.1816 0.30425 -0.10774 -0.071343 -0.080759 0.076705 -0.062214 0.25458 -0.28547 -0.20451 -0.064648 -0.34806 0.3093 0.11256 -0.045614 -0.11817 0.18528 0.11909 0.0025721 -0.16799 0.15081 0.21093 -0.046395 -0.28173 0.091904 -0.51839 0.14852 0.22094 -0.053831 0.074354 0.18546 0.17312 -0.22201 -0.17973 0.23097 -0.06359 -0.083247 0.2875 0.10027 0.095852 +t -0.27001 0.3269 0.05617 0.25075 -0.24543 -0.12047 0.2383 -0.16621 -0.4829 -0.079992 0.40554 -0.20861 -0.10291 0.087432 0.29329 -0.14011 -0.074318 0.36642 0.07643 0.30357 0.14576 -0.083093 -0.18256 -0.18416 -0.11709 0.21015 0.030059 0.081354 -0.21 0.048353 -0.2737 0.34123 -0.13605 0.2026 0.16534 0.15082 -0.00096376 0.09985 0.2357 -0.26821 -0.0072889 0.13344 0.019111 -0.07304 0.08292 0.29114 0.059945 -0.076046 0.053551 -0.42735 0.026388 -0.16867 -0.087621 -0.54223 0.0033364 0.13618 -0.083451 0.11381 -0.16916 0.39471 -0.24227 0.097374 0.398 0.25526 -0.19536 -0.061438 0.29801 0.16341 0.093299 -0.15879 0.25334 -0.063946 0.062739 -0.32977 -0.046173 0.33098 0.14704 -0.12818 -0.029185 0.2343 -0.17592 0.14627 0.010426 -0.071695 0.057722 -0.14105 -0.46612 -0.067586 -0.073369 0.095571 0.0086294 -0.066309 0.27761 0.048856 0.28911 0.40751 0.058737 -0.19109 0.17096 0.22856 0.20293 0.039091 -0.10951 -0.17358 -0.15721 -0.30945 -0.089978 -0.12901 0.3102 -0.171 -0.022282 0.29252 0.19407 -0.33125 0.32325 0.39229 0.15204 0.063896 0.34149 0.010666 0.31639 0.20902 0.1601 0.39138 0.013041 -0.12464 -0.078744 -0.16569 0.21098 0.28146 -0.11346 0.17732 -0.20271 0.14464 0.12787 -0.27098 -0.17942 -0.11533 0.28312 0.1314 -0.06355 0.11827 0.061267 0.21804 -0.13735 0.14427 -0.015967 -0.029817 0.12504 -0.42886 -0.044999 0.18722 -0.025355 -0.23286 0.0309 -0.1102 -0.13916 0.22567 0.19716 0.33239 -0.27148 0.17956 -0.26748 0.0041663 0.18407 -0.063485 -0.035241 -0.027268 0.24565 0.30383 -0.15152 -0.26332 -0.5779 -0.18383 0.041519 0.13934 0.045057 -0.26682 0.14327 -0.42192 0.28633 -0.019766 -0.077446 0.15512 -0.34164 0.10285 0.10672 -0.15215 0.25498 0.12619 0.012918 -0.25733 0.055302 0.092442 -0.3418 -0.14261 0.1635 -0.077083 -0.17725 -0.33404 0.30503 0.11161 0.298 -0.19646 0.13561 -0.34355 -0.21348 -0.080383 0.475 -0.15718 0.18099 0.063004 -0.0029775 0.021779 0.11077 -0.13109 -0.11303 0.048496 -0.074764 0.10218 -0.1741 -0.040275 0.22188 -0.24164 -0.025468 0.16647 -0.1062 0.053275 -0.19925 0.08654 0.057512 0.19205 -0.082107 -0.055764 0.064494 -0.076068 -0.035108 -0.011929 -0.27887 0.12271 -0.13003 0.3521 0.078793 0.0523 -0.3954 0.30795 0.054569 0.083192 -0.045319 0.084827 0.013948 0.21102 -0.3804 0.52227 0.17542 -0.35073 0.049836 -0.22227 -0.080704 -0.29779 -0.091286 -0.24551 0.073983 -0.12555 -0.31843 -0.012991 0.23976 0.2234 -0.049683 0.26894 -0.16809 0.13043 -0.15365 0.36449 -0.14463 -0.23218 0.10236 -0.21589 0.18333 -0.29316 0.064456 0.30226 -0.17705 -0.35736 0.074671 -0.13883 0.422 0.69961 -0.015826 0.046479 -0.24381 0.13153 0.16719 -0.12135 0.15499 -0.31444 -0.26408 0.1329 0.53046 0.18023 +who -0.16792 -0.024923 -0.15657 0.047392 -0.065025 -0.02318 0.10018 -0.091625 0.13494 0.33895 0.060199 0.018358 0.032187 -0.02267 -0.079796 -0.20589 -0.12461 -0.13514 -0.16761 0.12262 -0.10171 0.36091 -0.10119 -0.12834 -0.0041321 -0.081799 0.12746 -0.1733 -0.0055814 0.090521 -0.090363 -0.077901 -0.2465 0.046373 -0.042592 -0.058558 0.03797 -0.21448 -0.0096934 0.1296 0.077662 0.15814 0.060635 0.091421 0.21822 -0.22726 -0.023025 -0.016406 -0.053787 0.019855 -0.017372 0.044004 0.094729 0.077181 -0.33045 -0.1992 0.053772 0.12361 -0.037185 0.26504 -0.0079583 0.16325 -0.0025339 0.091653 0.020016 -0.24737 -0.15897 0.07071 -0.13512 -0.032715 -0.016628 -0.059538 0.13013 -0.29197 -0.10326 0.03052 0.35142 0.1128 -0.033843 -0.061764 0.031866 0.1934 0.080147 0.1915 -0.056946 -0.068144 -0.2574 -0.16393 -0.066092 -0.07198 0.07097 -0.24354 0.19716 -0.25208 0.21199 0.18246 0.42754 -0.15978 -0.38779 -0.055129 -0.1357 -0.039656 0.037395 0.036532 -0.18828 -0.017651 0.097255 -0.38872 0.40828 0.12044 -0.066261 -0.29734 -0.20016 -0.0018883 0.15011 -0.073388 0.26023 0.14372 -0.28465 -0.086279 -0.064048 0.22751 -0.11394 0.23502 0.02486 -0.17476 0.28497 0.13988 -0.25037 0.28427 0.078489 0.10535 -0.15855 -0.05862 -0.02513 0.13627 -0.0039802 -0.021213 0.093314 -0.1595 0.065229 0.29844 0.21805 -0.16583 0.12521 0.23212 -0.087139 -0.13501 0.054386 -0.17701 -0.0057424 0.1097 -0.065306 0.10202 -0.4721 -0.11116 -0.267 -0.033237 0.17942 0.068493 -0.28161 0.14238 -0.012774 0.18411 0.29382 0.071163 0.19561 -0.13619 0.35232 0.051042 0.046705 -0.028687 -0.26764 0.04339 -0.075495 0.16886 -0.055523 0.18667 -0.054889 -0.089161 0.14071 -0.081583 -0.10567 0.33868 -0.070249 0.28122 0.032236 0.017721 0.26766 -0.13606 0.15804 -0.30925 0.26096 0.36651 -0.12872 -0.33402 -0.11144 -0.099931 -0.16843 0.1229 0.067042 -0.088327 -0.12516 0.055453 -0.12429 0.098693 0.051058 0.15975 -0.0085387 0.16107 0.46582 -0.084398 -0.11996 -0.22717 0.12386 -0.10588 -0.035049 -0.2541 0.045503 -0.087727 -0.42588 0.016716 0.062944 0.20039 0.047548 0.20349 0.095759 0.0061315 0.15788 0.26281 0.10247 0.23179 -0.037631 0.0050632 0.26398 0.095955 0.1756 0.198 0.1103 0.010515 0.0099057 0.075089 0.065388 0.28206 -0.20086 0.086871 -0.068999 -0.072602 0.096617 0.14671 -0.2088 -0.36499 -0.0090067 -0.0428 -0.037449 -0.11141 0.23376 0.0093361 -0.014147 -0.27922 -0.056141 0.1563 0.13236 -0.15085 -0.11792 -0.046731 0.013425 0.021717 0.028933 -0.16086 -0.056507 -0.11121 -0.13587 -0.012569 -0.28719 0.068182 0.21153 0.10221 0.075415 -0.13827 0.19394 0.21873 0.090179 -0.044067 -0.147 0.028896 -0.074366 0.38834 0.11772 -0.022211 0.11484 -0.037925 0.21711 0.031849 -0.11788 0.17954 -0.043971 0.24394 -0.088494 0.069806 +? -0.17519 -0.072514 -0.3652 0.048249 -0.15999 -0.0003773 0.088057 -0.53121 -0.24097 0.32426 0.15647 -0.00033924 -0.14702 -0.18389 0.088317 -0.19785 -0.039917 0.0046675 -0.014113 0.2817 0.17345 0.35298 -0.12148 0.19978 -0.13104 -0.1289 -0.23658 -0.13854 -0.13431 0.092862 -0.27797 -0.091616 -0.15911 0.19992 0.038619 -0.15041 -0.10575 0.04453 0.053707 -0.2969 -0.30633 -0.41009 -0.026135 -0.041214 -0.1835 -0.17693 -0.15155 -0.33838 -0.15461 -0.13049 0.31741 -0.22587 0.022629 -0.17797 -0.20945 0.073847 -0.0014257 -0.059909 0.11547 0.26361 -0.011576 -0.24971 0.42054 -0.24115 -0.49511 -0.26286 0.39304 -0.122 -0.041751 -0.16589 0.43618 0.23285 -0.26819 -0.15971 -0.060578 0.21247 0.050261 0.11358 0.0070081 0.01978 0.096943 0.87822 0.11484 0.32747 0.15624 0.091463 -0.28561 0.074204 0.2752 0.013464 0.062276 0.17296 0.20939 -0.045015 0.17835 0.12367 -0.22818 -0.16781 -0.06847 0.13211 0.19492 0.11383 -0.39538 -0.19263 -0.050071 0.07998 -0.21195 0.1948 0.08911 -0.14263 -0.13523 0.11452 -0.11822 -0.019986 -0.2055 0.21532 -0.15605 0.019192 -0.32331 0.20854 0.29188 -0.32251 -0.27316 0.36031 0.23378 0.1495 -0.01284 -0.027845 -0.39566 0.39771 0.033166 -0.051125 -0.022702 0.26331 -0.30758 0.10086 -0.017884 -0.17162 0.17303 0.4597 -0.49968 0.067363 0.2475 0.16798 -0.10931 -0.16349 0.038199 -0.1015 -0.34919 -0.024499 0.039242 -0.022032 0.22289 0.085606 -0.065948 -0.065394 0.25424 -0.087111 0.37711 0.10055 -0.00064081 -0.084011 -0.39683 -0.36403 -0.19637 -0.19071 -0.18994 -0.28474 -0.12257 0.017596 -0.1625 -0.22418 -0.79747 0.088608 0.067142 -0.041942 0.1076 0.04777 0.42478 -0.39114 -0.080864 -0.25159 -0.027343 0.14931 -0.13421 0.08998 -0.068285 0.063285 0.064423 -0.21086 -0.00040278 -0.17278 0.17602 0.25703 -0.16872 -0.057281 0.21313 -0.074941 -0.38876 -0.26416 0.24174 -0.30244 0.094529 -0.089426 0.14677 0.096613 -0.62498 0.20746 0.10069 -0.039128 0.070092 -0.0011981 0.11348 -0.0095514 -0.11273 -0.23996 -0.099344 -0.14541 -0.31071 0.31612 -0.075377 -0.094789 0.15921 0.003976 0.050411 0.42235 0.063343 -0.098757 -0.14632 0.23308 -0.17375 0.28295 -0.49516 -0.0036848 0.40508 -0.23503 -0.16327 0.22314 -0.2455 -0.20865 -0.22202 0.0085346 0.072379 -0.10553 -0.091269 0.067068 0.21924 0.39532 -0.30634 -0.13163 -0.098442 -0.2065 -0.45396 0.54588 0.14171 -0.28257 -0.014702 -0.1339 0.098481 -0.14497 -0.053057 -0.16407 -0.13994 0.19239 -0.35545 0.12376 0.019699 0.14782 0.24582 0.20072 0.13425 0.053111 0.54769 0.088898 -0.11703 -0.20836 0.15755 -0.040329 -0.13491 -0.40331 0.1234 0.057737 0.040181 0.018324 0.07317 -0.2716 0.1592 0.25896 -0.31904 0.38814 -0.16251 0.21742 -0.11474 -0.40485 0.10846 -0.17078 -0.0042315 0.083689 0.10878 -0.080402 +all -0.42965 0.0088802 -0.20334 0.3175 0.046608 0.087144 -0.039991 -0.2754 -0.014379 0.16212 0.13356 0.053119 -0.019098 -0.12506 -0.024932 0.020046 -0.077413 -0.048549 -0.078301 0.023917 -0.30604 0.23914 -0.16549 -0.014935 -0.067174 0.092052 0.10943 0.077801 -0.0019634 0.17112 -0.023338 0.078832 -0.089082 0.24323 -0.10486 -0.12815 0.23938 -0.017536 -0.088876 -0.055258 0.023468 -0.18116 -0.12018 0.15627 0.020228 0.24384 0.058268 -0.19301 0.0061237 -0.1431 -0.12233 -0.23044 -0.06686 -0.03275 -0.28975 -0.031955 -0.15657 -0.0046447 -0.34629 0.16072 0.10008 -0.086969 0.37103 -0.35766 0.21389 -0.10356 -0.0033891 -0.032044 -0.18631 0.17904 -0.027564 -0.18208 0.045534 -0.28746 -0.13556 -0.064947 0.26073 0.11846 0.047528 -0.045252 -0.037418 0.18184 -0.27369 0.21925 -0.13466 0.18854 0.04712 0.17052 0.13561 -0.17757 -0.16426 0.18872 0.2 -0.2609 0.0073115 -0.070688 0.10376 0.056869 0.060297 -0.069054 0.20653 0.012256 0.14446 -0.081493 -0.32633 -0.26051 -0.19404 0.057902 -0.18123 0.093194 0.060564 -0.092249 -0.046576 0.016841 0.093002 -0.073175 0.40035 0.079836 -0.01474 0.17141 0.11818 -0.060034 -0.09074 0.19669 0.080111 0.062201 0.27632 0.023134 0.14159 0.28064 0.27237 0.14235 -0.16656 0.21778 0.20592 -0.021267 -0.069916 0.1658 0.26698 0.086414 0.083855 0.15162 0.18579 0.017757 0.18859 0.1688 -0.082017 0.0097354 0.038319 0.018847 -0.042382 -0.072064 0.0083685 -0.12679 0.0041041 0.12105 -0.040381 -0.15393 0.20437 0.28037 -0.17976 -0.215 -0.16445 0.27284 -0.094615 0.075256 -0.06525 0.050482 0.080204 0.075281 0.042197 -0.16842 -0.14679 0.061092 -0.26909 0.20269 -0.045017 0.046155 0.079746 -0.0035558 0.13033 -0.16793 -0.070565 0.2651 -0.17141 0.22394 -0.010464 -0.19645 0.058532 -0.18619 0.038604 -0.013632 0.10491 0.1001 -0.14533 -0.059982 -0.19854 0.078153 -0.30593 -0.15741 0.17248 -0.13547 0.017064 -0.041899 0.13739 -0.051294 -0.15157 -0.044107 0.28239 -0.0038653 0.24701 -0.3559 0.15038 0.073476 0.30945 -0.033385 -0.039795 -0.1738 -0.039525 0.019248 -0.095246 0.18088 0.020459 -0.0321 -0.05684 0.3275 -0.00089029 -0.22052 0.061158 -0.07099 0.28926 0.08613 -0.037341 -0.068044 0.11947 0.081472 0.036236 -0.089263 0.10454 0.050139 0.1052 0.0049095 0.0088752 0.12309 -0.06785 0.10891 0.26034 -0.0055677 0.16537 0.11733 0.072281 0.020446 -0.1384 -0.15131 0.042036 0.20698 -0.080284 -0.1019 0.075711 -0.10935 0.13224 -0.025915 -0.0080608 -0.10096 -0.0026213 0.059181 -0.16895 -0.046259 -0.18888 -0.11783 0.026414 0.10926 0.060116 -0.0052691 0.014903 0.0046529 -0.22772 0.082784 -0.045502 -0.048428 0.17518 0.04156 0.0088114 -0.14547 0.084435 -0.0042664 0.13117 0.35262 -0.45328 0.18638 0.2353 0.024114 0.31682 0.18082 0.22047 -0.019153 -0.16688 -0.17553 0.13171 -0.028725 +their 0.12108 0.050184 -0.1595 0.26758 0.0058531 -0.066766 0.12474 0.078573 -0.012852 0.24327 0.1679 -0.048491 -0.0053986 -0.11588 0.066364 -0.0091023 0.048438 -0.044797 -0.11963 -0.095881 -0.21745 0.0092893 -0.00079798 -0.25402 -0.085531 0.041114 0.16168 0.13571 -0.071569 -0.0075288 -0.20957 0.013117 -0.16595 0.12892 -0.23942 -0.11186 0.11593 0.052861 0.12475 -0.15452 0.29841 -0.041613 0.030492 0.10227 0.14782 0.10698 0.29219 0.21681 -0.032681 -0.21893 0.057776 -0.18071 -0.026903 0.26301 -0.26017 -0.045765 -0.054281 -0.0059784 -0.22835 0.10734 -0.25353 -0.24388 0.23217 0.062453 0.056728 -0.24474 -0.12223 0.12799 -0.32198 0.12994 -0.20929 0.10255 -0.23169 -0.44586 -0.23785 -0.055059 0.26633 0.15237 -0.037917 -0.25612 0.063225 0.15676 -0.1407 0.16957 -0.060944 -0.10031 0.018608 0.12792 0.039435 -0.073986 -0.094956 -0.062842 0.049721 -0.20236 -0.014727 0.046669 0.05937 -0.24429 0.10328 0.087579 0.095888 -0.10315 0.2728 -0.40314 -0.21764 -0.0663 0.079689 0.16685 0.053553 0.2104 0.10589 -0.22545 0.059085 -0.011398 -0.084907 -0.0027259 0.048359 0.16908 -0.040004 0.18869 0.10656 0.11193 -0.13592 0.15442 0.083623 -0.19724 0.1517 -0.046388 0.049671 0.2538 0.076565 0.18778 0.046143 -0.098137 -0.03891 -0.17658 -0.24566 -0.030542 0.0708 -0.07998 0.00069323 0.11517 0.083593 0.078065 0.12146 0.28809 0.027015 -0.040168 0.13851 0.14202 0.15303 -0.26339 -0.13026 -0.086854 -0.058488 -0.02097 -0.45058 0.21738 0.28727 -0.15329 -0.109 0.090674 -0.071088 0.21331 0.079669 0.17067 -0.0050916 -0.018396 0.3056 -0.0027602 -0.10436 -0.13435 -0.20715 0.17627 0.025517 0.34474 -0.13998 0.17193 -0.013195 -0.15875 0.15968 -0.032136 0.02181 0.053198 0.10221 0.0048228 0.30789 -0.21639 0.055483 -0.066302 0.1361 -0.18425 0.10121 0.2813 -0.11394 0.10893 -0.18798 -0.056759 -0.029395 0.051721 0.16168 0.096215 0.21522 -0.049861 0.14074 -0.048582 -0.067891 -0.043586 0.15442 0.12395 0.29884 0.31792 -0.029476 -0.22954 0.13503 -0.066817 0.077929 -0.15355 -0.077799 0.03399 -0.12008 -0.14979 0.034629 0.25705 -0.044134 0.28883 -0.28735 -0.31341 -0.063441 -0.073757 0.094711 0.036241 -0.047193 -0.18081 -0.37018 0.022323 -0.0041943 0.015069 -0.058319 -0.0016781 0.10064 0.008799 -0.019057 0.1298 0.10735 0.12715 -0.24744 -0.079153 0.11025 0.22733 -0.077809 0.03557 -0.00086855 -0.11368 -0.076684 0.14704 -0.13063 -0.20906 0.092649 -0.054276 -0.12189 0.13762 -0.231 0.021167 -0.32901 -0.11143 -0.16547 0.046944 -0.053264 -0.18892 -0.2617 -0.0086329 0.15429 0.25686 -0.12122 0.055378 -0.16159 0.22657 0.021818 0.12136 -0.027152 0.11339 0.069789 0.14235 0.16321 0.14271 -0.075703 0.12842 -0.36191 0.25606 0.023424 0.027158 -0.11381 0.13535 0.24351 0.014782 -0.047368 0.34908 0.049802 0.035011 +there 0.013689 0.14616 -0.020037 0.32463 -0.14837 -0.01296 0.0031785 -0.0045912 -0.023316 0.20372 -0.0028693 0.064148 0.024081 0.30042 0.15985 -0.034167 -0.046283 -0.11454 0.23148 -0.062146 -0.041946 0.141 -0.17776 0.029392 -0.19214 -0.047674 0.19028 0.016809 -0.12773 0.134 -0.01405 0.1967 -0.16411 0.22005 -0.081228 0.0058925 -0.02986 0.097874 0.048011 0.00509 -0.10262 0.0084757 -0.089191 -0.028915 0.079653 0.21242 0.22955 0.0068429 -0.10734 -0.12707 -0.035675 -0.34758 -0.014745 0.098664 -0.26677 0.15174 -0.070379 0.11741 -0.21856 0.14806 -0.34428 -0.092995 0.33721 -0.25579 -0.12442 -0.081491 -0.012542 0.10204 -0.08476 0.16592 -0.098669 -0.010756 0.061447 -0.068707 -0.25046 0.033093 0.038377 0.12674 0.029024 0.00030627 0.23159 0.01349 0.04606 -0.12942 -0.13805 -0.0040294 -0.17694 0.14187 -0.024653 -0.15579 -0.015882 -0.077564 0.55749 -0.32984 0.073338 0.050526 0.2151 0.12432 -0.018416 0.18043 0.21407 0.026809 0.12491 0.034459 -0.1664 -0.013394 -0.12745 0.094926 0.0098882 -0.16172 -0.17373 0.16779 -0.033516 -0.060354 0.13567 -0.1925 0.073883 -0.026626 0.02627 0.24957 0.33962 -0.025451 0.17727 0.25922 -0.015897 0.18869 0.18008 0.15822 0.13882 0.15156 -0.12936 -0.095485 0.13651 0.19109 0.051064 0.025392 -0.022263 0.079596 0.093802 0.051655 0.039181 0.029299 0.14719 0.012053 0.38006 0.087772 -0.16059 0.1168 -0.12383 0.073708 0.011269 -0.19968 0.053784 0.067892 -0.26106 -0.22814 0.20539 0.0032442 0.080051 0.097407 -0.18456 0.30216 -0.20749 0.08158 0.0082529 -0.12749 -0.21698 -0.038959 0.23559 -0.075517 -0.040899 0.045094 -0.5279 0.095606 -0.27215 -0.080209 -0.076886 0.22563 -0.13355 0.049687 0.096509 0.12826 0.13218 0.18036 -0.16039 -0.079016 0.051331 -0.20504 0.22081 -0.11359 -0.027723 -0.40002 -0.01707 0.089515 -0.18022 -0.22497 0.17763 0.17005 -0.25144 -0.13363 -0.007385 -0.047598 0.2405 0.12501 -0.14657 -0.037232 -0.139 0.012675 0.0066963 0.22678 0.18087 -0.10151 0.053858 -0.24692 0.024375 0.17947 -0.12393 -0.30308 -0.1203 0.01573 -0.12332 -0.17654 -0.028845 0.075684 0.03806 0.090058 0.12124 0.22865 -0.1017 0.095487 0.22654 -0.057054 -0.19671 -0.051846 0.065229 0.2773 0.1316 -0.21467 0.22619 0.15237 -0.12981 0.030462 0.1166 -0.19111 -0.21469 0.41953 0.29282 0.21589 0.00081175 -0.077017 0.059567 -0.0024375 -0.45537 -0.086308 0.0074062 0.058034 0.15511 -0.21714 -0.20471 0.021665 0.10662 0.13441 0.1459 -0.10707 0.021473 -0.0023633 -0.15888 0.17146 0.010775 0.12453 0.027792 0.090843 0.090885 -0.23816 -0.13538 -0.10069 0.072976 -0.043221 -0.012684 -0.13816 0.33124 0.011421 -0.2019 -0.064327 0.13483 0.23735 0.00090457 0.11574 -0.20922 0.14809 0.2078 -0.045272 -0.18763 0.066758 -0.11273 -0.19281 -0.30905 0.025198 -0.030905 0.0016205 +been -0.1477 -0.13477 -0.2475 0.02076 -0.13587 0.12788 0.10769 -0.34265 -0.14884 0.28341 -0.0099212 0.27009 0.028468 0.012028 0.12074 -0.11319 0.031134 0.13722 0.08244 0.090114 -0.039155 0.207 -0.17441 -0.46096 -0.13696 -0.0038776 0.11981 0.20182 0.080932 0.14176 -0.12591 0.21687 0.0010702 0.2635 0.066637 0.0011725 0.055957 0.095976 -0.03724 -0.17582 0.14216 -0.14061 0.14911 0.089605 -0.083772 -0.036891 0.11188 0.015942 0.047274 0.19163 -0.34174 -0.26671 -0.30332 0.15135 0.085256 -0.17965 -0.059018 0.2968 -0.14752 0.24992 0.00087438 0.15221 0.11701 -0.0017772 0.4922 0.14307 -0.28457 0.14576 -0.16481 -0.052588 -0.10354 -0.010191 0.06632 -0.30943 -0.058576 0.17096 0.28728 0.32305 -0.10497 -0.27314 0.040203 0.01941 0.058334 -0.11107 0.045268 -0.28341 0.0021492 -0.02673 -0.24905 0.03685 0.018437 0.043619 0.29779 -0.023423 0.067262 -0.021577 0.027047 0.14574 -0.1242 0.0057499 -0.22087 0.082406 0.19025 -0.22731 0.013923 -0.075359 -0.10851 0.26828 -0.27522 -0.03719 -0.11582 0.19715 0.0095723 0.030525 0.003465 0.034414 0.19314 0.14158 0.033836 0.31028 -0.026976 0.16816 -0.22094 0.44517 0.018906 0.063523 0.031337 0.25996 0.13026 0.29794 -0.12269 0.20463 -0.11847 0.12853 0.17572 0.10058 -0.074098 0.099432 -0.14375 -0.006641 -0.1282 0.029715 0.0078677 -0.014492 -0.025692 0.20441 -0.10205 -0.28795 -0.14402 0.2171 0.026392 -0.019398 -0.026873 0.031167 -0.23681 -0.095229 -0.17373 0.010928 0.62986 0.044692 0.1105 0.27522 -0.40513 -0.0082544 0.068675 0.1379 0.36785 0.020965 0.17326 0.25395 0.020348 0.065713 0.010664 0.027053 -0.15869 -0.23314 0.087733 0.10751 0.097722 -0.13846 0.024585 0.017132 0.025672 0.3863 0.16764 -0.008983 0.21617 0.068635 0.17933 0.0065194 -0.15408 -0.48797 0.013831 0.15091 -0.16832 -0.35222 -0.16744 -0.0014162 -0.20537 -0.0014328 -0.13127 0.1691 0.031576 0.026595 -0.23506 0.096983 0.20562 0.15854 0.26697 0.22913 0.29997 -0.16922 -0.22712 0.090185 0.011827 0.024106 0.0079038 -0.012663 -0.048562 0.24817 -0.073063 -0.24561 -0.10296 -0.19988 -0.073753 -0.072046 0.0083721 0.039906 -0.16167 0.05178 -0.12637 0.14349 0.0018635 -0.070317 -0.023958 -0.11765 0.19558 0.25143 0.13778 0.35231 0.066119 0.073639 0.18583 -0.10051 -0.095831 0.042474 0.21821 0.036443 0.13412 0.1169 0.072217 0.16399 0.075131 -0.17558 -0.017305 0.055556 -0.040382 -0.012062 -0.0040065 -0.086663 0.13453 0.21096 -0.14205 -0.18998 -0.30808 0.17079 -0.10165 0.30312 -0.25341 -0.11659 0.045643 0.10542 0.17127 -0.16073 -0.12051 -0.30933 0.40289 0.18351 0.14009 -0.16767 0.10839 0.010342 -0.015383 -0.075649 -0.068229 -0.073173 0.066303 0.097534 -0.01572 0.21127 -0.17418 -0.11655 -0.088314 0.025956 -0.11041 -0.072122 -0.15355 0.24966 0.11398 0.07525 +made -0.1607 -0.15512 -0.16367 0.15251 0.28545 -0.089589 -0.085886 -0.042271 0.044481 0.17389 0.052276 0.18053 0.19 -0.012547 -0.020536 -0.047085 0.13906 0.31214 -0.26683 0.040201 -0.13571 -0.18192 0.20091 -0.19316 -0.27992 0.080827 -0.024699 -0.4407 0.004629 0.12059 0.050521 0.20287 -0.32498 -0.080344 0.0020535 -0.099764 0.16449 -0.16448 0.1796 -0.35642 -0.0036997 -0.03232 -0.22326 -0.0087993 -0.063212 -0.047669 0.004822 -0.086263 0.19595 0.089789 -0.25139 -0.022407 0.13665 0.16436 -0.24884 0.21022 -0.3678 -0.12325 -0.11068 0.34695 0.068993 0.094693 0.22348 -0.54 0.065352 -0.52442 -0.010399 0.11741 -0.086235 0.14231 -0.044102 0.25507 0.0063577 -0.20154 0.086202 -0.16446 0.1808 0.10532 0.030927 -0.11688 0.13399 0.14195 0.13697 -0.066606 0.20211 -0.53664 0.012099 0.18373 -0.38062 -0.47262 -0.13657 -0.11716 -0.069509 -0.30032 -0.069818 0.38741 -0.30412 0.090496 -0.37882 -0.21545 -0.23895 -0.24152 -0.059071 0.22437 0.28948 0.22511 0.15225 0.13766 -0.14144 -0.11415 0.042245 0.18327 0.32289 -0.18588 0.080721 -0.060523 0.076963 0.21812 0.019744 0.12474 0.1822 0.25496 -0.21334 0.081183 0.43752 0.2781 -0.048984 0.17067 -0.074991 0.40426 0.10785 0.13576 -0.069448 0.081642 0.16985 -0.30936 -0.083486 0.00031132 -0.32089 0.031854 -0.22316 -0.15137 -0.17352 0.32026 0.045412 0.12836 -0.31505 0.26893 -0.4531 0.40112 0.12999 0.038981 -0.22968 -0.11053 -0.51142 -0.11542 0.23931 -0.20533 0.03168 0.002001 -0.13145 -0.0042372 -0.25358 0.17025 -0.005468 -0.20585 0.25619 0.1074 0.37034 0.029532 -0.34615 0.11243 -0.27023 0.067293 -0.26414 0.17343 -0.11997 -0.0055723 0.0011452 0.10664 0.14741 0.0055639 0.2753 0.50486 -0.21264 0.35812 0.4108 0.074424 0.017267 -0.049262 0.14322 -0.16379 -0.077156 0.1382 -0.12331 -0.15811 -0.26149 0.18855 -0.32902 0.3601 -0.41521 -0.31113 0.58768 0.19098 0.07964 -0.16781 -0.39613 0.31702 0.50609 0.29085 0.65181 -0.37568 0.23727 0.011391 -0.060317 0.18376 0.54529 -0.55282 -0.058984 0.22881 0.081654 0.068108 -0.014444 0.28761 -0.18975 -0.070589 -0.16044 -0.4832 -0.24823 0.017493 -0.042994 0.090457 -0.24163 0.17379 -0.25222 0.47961 0.29635 0.099308 -0.011285 -0.090779 -0.0065225 0.1824 0.28863 0.13457 -0.27696 0.41439 0.4077 0.018963 0.23776 0.16625 0.084062 -0.19881 -0.14081 -0.14042 0.21177 0.16746 0.1532 -0.12037 -0.24419 0.094116 -0.10622 0.094826 0.14233 0.19439 -0.076951 -0.24088 -0.092695 0.32017 0.0034527 -0.24074 -0.14391 0.027853 -0.39148 0.22096 0.022911 -0.22762 0.16342 0.20037 -0.0067606 0.16903 0.097819 0.14917 -0.26921 -0.1249 0.31143 0.067282 0.20321 0.41096 0.26096 -0.39748 0.083338 -0.071496 -0.21098 -0.13502 0.20615 -0.10549 0.04879 -0.067252 0.11251 -0.12855 +its -0.099943 -0.095374 -0.16955 0.2332 0.027917 -0.2469 0.079541 -0.015743 -0.064162 0.37166 0.0504 -0.12933 0.26108 -0.061921 0.10533 0.01289 -0.018616 -0.12783 0.078918 0.17501 -0.11267 0.13836 -0.11526 -0.50424 -0.15812 -0.29586 0.10105 0.10246 0.15037 -0.045676 -0.28695 0.34189 -0.055164 0.2685 -0.29481 -0.078944 0.14982 -0.1456 -0.057301 -0.01025 0.054853 -0.061068 0.030838 -0.020885 0.29063 0.26164 -0.018397 0.26998 0.10307 -0.10266 0.055627 -0.018202 -0.052353 0.21491 -0.16526 0.041641 0.010906 0.072301 -0.024331 -0.068326 -0.080224 -0.030317 0.3424 0.013642 0.0024587 -0.27487 -0.13917 -0.12068 -0.07459 0.13155 -0.22706 0.055504 0.0087149 -0.051825 -0.20111 -0.019131 0.045798 0.19713 0.12722 -0.23622 0.1217 0.11136 0.28612 0.1686 -0.16094 0.044673 0.12357 0.32941 0.099932 -0.042613 0.20693 0.15455 0.13922 -0.37855 -0.035108 -0.025928 0.17044 0.25218 0.051277 -0.024152 -0.041032 -0.017559 0.40249 -0.39724 -0.11576 -0.14655 -0.28519 0.3248 -0.05679 0.030534 -0.08874 0.0071727 -0.14484 -0.1129 -0.095761 0.061138 0.023838 0.11662 0.35584 0.17463 0.052115 -0.034274 -0.095426 0.28186 0.11581 0.099476 0.17887 -0.0027635 0.11502 0.018327 0.011297 0.17553 0.12653 0.053634 -0.15143 -0.15354 -0.12833 -0.0062628 -0.057793 0.11873 0.01342 0.0038952 0.22655 0.34041 0.1632 0.25613 0.016746 0.062438 0.11331 0.20081 0.11894 -0.25878 -0.07954 -0.04138 0.069708 -0.046969 -0.016395 0.18225 0.27116 -0.0076246 -0.20777 0.21339 -0.3384 0.29664 0.30422 -0.027936 -0.074645 -0.050666 0.20789 -0.1547 -0.13444 -0.16362 0.0075092 0.020599 -0.10769 0.15171 -0.028397 0.11531 -0.11472 0.097927 0.15989 0.06269 0.057852 -0.023723 0.1373 0.032406 0.12856 -0.45087 -0.094265 0.0011745 -0.020482 -0.064063 0.15759 0.2013 -0.26073 0.31537 0.10384 -0.028928 -0.020059 0.031401 -0.0033611 -0.041878 -0.062437 0.04403 -0.22855 -0.24718 0.19772 0.0054901 0.15843 0.22321 0.11864 0.36403 0.042914 -0.026939 -0.004724 -0.12658 0.12068 -0.12599 0.068229 0.078913 0.042069 0.10273 -0.27115 0.23578 0.12164 0.082186 -0.23721 -0.3815 -0.052169 -0.04982 0.17205 0.16805 -0.074104 -0.013826 -0.31626 -0.027091 0.011182 -0.16375 -0.080864 0.074682 -0.048148 -0.19462 0.13134 -0.13379 0.23713 0.0020027 -0.12394 -0.046406 0.00053912 -0.12535 0.069831 0.35514 0.037194 0.00799 -0.012723 0.075782 -0.099322 0.082945 -0.0029492 -0.076004 0.12589 0.055382 -0.16835 -0.039559 -0.19796 -0.031226 0.095901 0.037382 -0.004177 -0.36257 -0.50771 0.10456 0.19824 0.23786 0.015615 0.034666 0.031472 0.57877 0.16154 0.091154 0.027592 -0.017388 0.040783 -0.06976 0.31625 -0.18234 -0.055455 0.18401 -0.24267 0.12608 -0.045711 -0.1667 -0.19817 0.23516 0.085741 -0.084006 0.01074 0.29869 -0.12425 -0.044046 +people -0.18904 -0.0060955 0.17664 -0.1551 -0.31886 -0.19349 0.028729 -0.18951 -0.059563 0.18212 0.26391 0.26106 -0.19818 -0.10295 -0.23183 -0.034002 -0.33035 -0.20227 0.20207 0.049372 -0.066406 0.13397 -0.021476 -0.10524 -0.019948 0.049189 0.39666 -0.12545 -0.24825 0.31195 -0.15038 0.20861 -0.66122 0.17057 0.13622 -0.086348 -0.036075 -0.158 0.19955 0.36775 -0.35637 -0.018656 -0.03945 0.047299 0.33251 0.49576 0.011627 -0.12662 -0.19955 -0.13496 -0.031604 0.084278 -0.00088686 -0.021137 -0.042625 0.05959 -0.07074 -0.012893 -0.17834 0.23333 -0.26474 -0.1681 0.31222 -0.02476 -0.073097 0.012875 -0.02417 0.031449 -0.11147 0.19393 -0.10097 0.20565 0.44183 -0.34442 0.31633 -0.18494 0.24902 0.01189 -0.37678 -0.36856 -0.3234 0.10022 0.31117 0.23776 0.17438 -0.057654 -0.089945 0.29086 0.078267 0.029959 0.21061 0.13605 0.28215 -0.46272 -0.16089 0.2232 0.2343 0.050995 0.051689 -0.11358 -0.093533 0.38209 -0.21496 -0.52718 -0.44801 0.22312 -0.12194 -0.16079 0.17599 0.1325 0.57215 -0.045787 -0.39375 -0.02876 -0.18495 0.055877 0.38101 -0.010387 -0.30994 0.16415 -0.17603 -0.064731 -0.24216 0.1437 -0.0023777 -0.12474 0.14279 0.17737 0.27145 0.046148 0.096142 0.27569 -0.16928 -0.068955 -0.14369 -0.19753 -0.084424 0.10927 0.025963 0.3121 0.12074 0.30427 0.049774 0.037441 0.28976 -0.010688 -0.15236 -0.031899 0.13813 0.019419 -0.012435 0.047858 0.21456 0.034201 -0.20808 -0.49573 0.33692 -0.067651 -0.050387 -0.20308 -0.29392 0.62286 -0.34168 -0.062339 0.57835 -0.15267 -0.15429 -0.18918 0.68803 0.070699 -0.13678 -0.23595 -0.25227 0.23216 -0.56908 0.26069 -0.24 0.17192 0.033571 -0.10659 0.29385 0.34061 -0.09552 0.31066 -0.0078378 0.23933 0.00984 -0.021138 -0.1788 -0.046346 0.19833 -0.27223 0.1205 0.19981 -0.31488 -0.096613 -0.2177 0.24444 -0.34423 -0.17851 -0.207 -0.23557 -0.079816 0.24642 0.00070893 0.12106 -0.20982 -0.2207 -0.095824 0.34375 0.45887 -0.09032 0.21364 -0.32243 0.051047 0.025595 -0.03888 -0.36033 -0.049995 0.068956 0.02306 -0.33479 -0.10781 0.19563 0.042942 0.2409 -0.092082 0.20205 -0.028472 -0.049433 0.10717 0.069724 -0.15489 -0.24612 -0.1305 0.08178 0.11362 0.090137 0.077621 0.21475 0.013195 -0.27982 0.34427 0.24947 -0.19077 -0.011215 0.037879 0.1576 0.01079 0.055051 0.16133 -0.21535 -0.25201 -0.27721 -0.074579 -0.16421 0.096502 -0.39348 0.24881 -0.0029485 -0.045481 0.0029993 0.043741 -0.43711 -0.26041 0.012057 0.28825 -0.1843 0.026475 0.24676 0.14065 0.10368 -0.27005 -0.21365 -0.22759 0.5363 0.28187 -0.077291 0.23566 -0.23195 0.19219 0.14927 0.04829 0.33027 0.45874 -0.19561 -0.072188 -0.34129 0.10512 0.008399 0.11388 0.0085701 -0.13828 -0.11493 -0.22161 0.11269 -0.68484 -0.027416 0.32802 -0.092465 +may -0.1281 0.11622 -0.1766 -0.1788 -0.24574 0.013559 0.094366 -0.27989 0.07467 -0.042644 -0.15928 -0.10095 -0.077565 -0.046445 0.063462 0.026919 -0.278 0.10078 -0.12386 0.12633 -0.0559 0.13483 0.13824 -0.16584 0.047997 -0.049696 0.06493 -0.18064 0.023736 0.035298 -0.11303 0.10691 -0.19971 -0.10965 0.10989 0.06081 -0.20734 0.15336 0.15677 0.0026077 -0.03626 0.080751 -0.16879 0.0019382 0.0092692 0.041721 0.084704 0.15395 -0.12817 -0.22389 -0.18053 -0.0091861 -0.083469 -0.17693 -0.06959 -0.25896 0.15773 0.092564 -0.057691 0.16113 0.054333 -0.17219 0.24803 -0.078886 -0.12712 -0.099611 -0.33846 0.040201 -0.14857 0.13339 -0.2037 0.26244 -0.13218 -0.38882 0.14438 0.14761 0.37248 0.058287 -0.063674 0.13964 0.1806 0.32397 -0.043231 -0.12882 0.11246 0.064378 -0.016712 -0.040039 0.033283 -0.04152 -0.15424 0.039441 0.088131 -0.22506 0.053484 -0.046978 0.034448 -0.15505 -0.094368 0.3674 -0.1874 -0.097182 0.031259 -0.51324 0.11953 -0.065023 -0.075121 0.13838 0.20906 -0.067881 0.15865 0.29764 -0.10774 -0.18179 -0.10896 -0.040166 -0.037554 0.23005 0.071476 0.14132 0.10433 -0.15146 -0.13462 0.54403 -0.1644 -0.14705 -0.086271 0.080527 0.074534 0.32952 -0.065689 0.12402 0.27546 0.045918 0.11204 -0.20028 -0.1732 0.21601 -0.10553 0.1254 0.10037 -0.15991 0.091771 0.060991 -0.11855 0.4845 0.13214 -0.20783 -0.17782 -0.057865 -0.06103 0.063225 0.056823 0.024756 -0.027454 -0.16079 -0.11708 -0.019639 0.39605 0.04553 -0.077044 0.008143 -0.37277 -0.07205 0.24427 0.14173 -0.080408 -0.04853 0.16336 0.23024 -0.38325 -0.14976 -0.29596 0.086066 0.10046 -0.077654 -0.043165 0.020356 -0.15622 -0.14 -0.23401 -0.2175 0.065091 -0.017582 0.0090847 0.14202 -0.11031 -0.056833 0.20382 0.043655 -0.085542 -0.36912 -0.048674 -0.013265 -0.015587 0.037973 0.11359 0.11422 -0.27879 -0.091202 0.034331 -0.21125 -0.35898 0.080895 0.062445 -0.039032 -0.15083 0.040102 0.20751 0.2423 0.30196 -0.32137 -0.09406 0.099781 -0.042716 -0.10103 -0.09818 -0.23061 -0.085553 -0.30054 -0.019516 -0.28347 -0.18745 -0.059179 -0.11367 -0.028728 -0.067596 0.067616 0.17367 -0.039826 0.0042453 0.12594 0.030568 -0.098419 -0.17452 0.16847 -0.063715 -0.063695 0.17122 0.16309 0.10663 0.053643 0.12603 0.11223 -0.11047 0.217 0.01833 0.2542 0.092537 -0.040046 0.21966 -0.14843 0.060282 0.068879 0.076029 -0.085165 -0.044522 -0.050305 0.13074 0.0085751 0.23026 0.17303 -0.050384 0.038419 0.00024102 -0.025396 -0.29367 0.25275 -0.23461 0.022624 -0.27669 -0.011798 -0.0081916 -0.12315 -0.2124 -0.14725 0.099977 0.04448 0.053206 -0.03325 -0.052258 -0.11754 -0.21017 -0.16639 0.30818 -0.16077 -0.020212 0.22307 0.19837 0.082521 0.26291 0.0082545 -0.23046 0.0039818 0.18998 -0.034144 -0.14982 -0.032295 0.067883 0.15751 +after -0.02381 -0.13347 -0.099323 0.18576 -0.09063 -0.01901 -0.017136 -0.19994 -0.03215 0.19638 0.20083 -0.03299 -0.068473 0.088887 0.025086 -0.087506 0.081662 -0.18359 -0.13052 0.4695 0.020701 0.12677 -0.42526 -0.22049 -0.19864 -0.14351 0.044412 -0.085645 0.068079 0.00065869 -0.16506 0.26333 -0.041861 -0.0068456 0.17591 -0.088237 0.17138 -0.12413 0.18414 -0.075362 0.042134 -0.091953 0.032799 -0.19697 0.0021139 0.025462 0.15297 0.18938 -0.093815 0.13099 0.1133 -0.26342 -0.060955 0.053676 -0.015557 0.037087 -0.13589 0.10788 0.015482 -0.049748 -0.05699 -0.5012 0.024022 0.11203 0.073363 0.094816 -0.0010325 0.19499 -0.049417 0.018289 0.014312 0.10258 -0.17422 -0.21716 0.13874 0.078372 0.28409 0.15151 0.058753 -0.15125 0.25806 0.0064346 -0.14491 0.15146 0.035753 -0.099718 -0.2518 0.077202 0.027281 0.0148 -0.32185 -0.19973 0.26645 -0.022034 0.22838 0.18023 -0.17501 0.31774 -0.21449 -0.18692 0.060354 0.043683 0.27214 -0.017046 0.10917 -0.038514 -0.093555 0.21885 0.24409 0.22292 0.23795 -0.018903 -0.037171 -0.10287 0.11239 -0.17271 0.067486 0.11565 -0.044566 0.26892 0.39521 0.20493 -0.28793 0.3875 0.14814 -0.11139 0.28312 -0.028172 0.30891 0.064985 -0.25356 0.0028425 -0.23909 -0.23515 0.0084086 0.070237 -0.089971 0.043253 -0.135 -0.10582 0.046109 -0.1103 0.081581 -0.062136 0.0055225 0.29208 0.060016 -0.075344 -0.10711 0.096122 0.0067895 -0.176 -0.063068 0.26846 -0.2079 -0.046621 -0.0099679 -0.028861 0.095638 -0.030919 -0.10331 0.26062 -0.25952 0.29983 0.13703 -0.1213 -0.12396 0.10173 0.22469 -0.26712 -0.071385 -0.12106 0.010285 0.080605 0.068203 0.014649 -0.19149 0.25863 0.050205 -0.17061 -0.090931 -0.066977 -0.38715 -0.11005 -0.20213 0.15995 0.072924 -0.093986 0.067252 -0.012308 -0.19589 -0.12459 0.026278 0.12086 0.071179 -0.051619 -0.26104 -0.087131 -0.064114 -0.085221 -0.19941 -0.076755 -0.063048 -0.046931 0.053142 0.096564 -0.070828 0.062502 0.17359 0.16847 0.15346 -0.061157 -0.085192 0.008912 -0.083714 0.034392 0.067603 -0.11983 -0.26691 0.076166 -0.045276 -0.10477 0.11846 0.19733 -0.069763 0.16007 -0.25733 -0.0086714 0.1971 0.14137 0.12357 -0.034954 -0.34086 0.11762 -0.098647 0.024459 0.059482 0.030277 0.048182 -0.17786 0.14967 -0.2367 0.20631 0.026731 -0.038929 0.049806 0.086189 -0.0076831 -0.01505 0.0685 0.13626 0.012769 -0.14371 -0.15177 -0.047791 0.098528 -0.14076 -0.12515 0.0009927 0.14614 0.12226 0.19631 0.070392 -0.32198 -0.020638 -0.1294 0.2394 0.09384 -0.069987 -0.23969 -0.24248 -0.17795 -0.088668 0.060282 -0.3157 -0.026589 0.1686 0.24604 0.1197 0.074519 -0.023599 -0.010565 0.24928 0.32287 -0.054877 0.1355 0.041028 0.0683 0.081687 -0.11338 0.059686 -0.052655 0.14214 -0.16897 -0.10605 -0.028526 -0.04856 0.17569 -0.024529 0.05592 +% -0.34595 -0.099989 -0.45195 0.14494 -0.67913 -0.12342 -0.12161 -0.65677 0.10068 -0.30083 -0.083097 0.35491 -0.00066027 0.20335 -0.43612 -0.16698 -0.2613 0.11388 0.67893 0.1954 0.018472 0.23597 0.025022 0.89684 -0.55003 -0.20671 -0.659 -0.27406 -0.18194 0.45689 0.16644 0.23882 -0.25251 0.18689 -0.26386 -0.61533 -0.12633 0.020112 -0.49091 0.018793 0.21324 -0.37916 -0.15436 0.12611 0.71791 0.043793 -0.13866 -0.38003 0.13321 -0.29352 -0.29998 -0.23507 -0.20814 -0.26209 0.038159 -0.16692 0.070279 -0.046276 -0.22974 0.10836 0.022688 -0.38177 0.54448 -0.27652 -0.19122 0.32353 0.14507 0.20475 -0.013999 0.25133 0.41841 -0.030467 -0.63 0.36625 -0.47234 -0.15143 0.3606 0.10791 0.22987 0.28089 -0.15399 0.45954 0.23445 0.41754 0.059689 -0.67307 -0.21871 0.32886 0.56541 -0.063921 -0.25238 0.18952 -0.41196 -0.64352 -0.12855 0.45232 -0.021397 0.16441 0.35297 -0.0056197 -0.056661 0.11771 0.49606 -0.36182 -4.8399e-05 0.031244 0.22128 -0.29626 0.21516 0.56481 0.17392 0.4204 -0.38805 0.19879 -0.17618 0.37551 0.26922 0.64065 -0.48071 0.54982 -0.073206 0.057841 -0.10422 -0.32746 -0.036678 -0.1932 -0.63092 -0.36363 -0.24651 0.26277 0.19379 -0.078498 -0.15346 0.3151 0.027983 0.16243 0.39814 -0.15768 0.16831 0.43229 -0.068114 0.56968 0.35631 0.013081 0.088933 0.83076 -0.27779 0.1988 -0.30016 0.12859 0.31431 0.12652 -0.2919 0.48098 -0.40795 -0.021773 0.2113 -0.16392 0.28242 0.12109 0.36418 0.44416 -0.27821 0.0047798 0.7741 0.30292 -0.078799 0.25372 0.037243 0.52737 0.35868 -0.18463 -0.45473 0.50935 0.055312 -0.24136 -0.38552 -0.1297 0.013833 -0.25722 -0.17835 -0.3576 -0.41943 -0.1615 -0.30302 0.60682 0.12568 -0.10517 0.006273 0.024597 0.33765 0.3351 0.71938 0.67717 -0.070356 0.36305 -0.36126 0.62285 -0.34824 -0.28687 -0.33793 -0.14749 0.65983 -0.1391 0.33836 -0.09946 -0.75038 0.027116 0.75642 0.2419 -0.021156 -0.50507 0.22996 0.54194 -0.34584 -0.75338 -0.23758 -0.57873 -0.48143 0.19732 0.35088 0.36563 0.26608 0.12589 0.14343 0.5444 0.097154 -0.15934 -0.15195 0.29162 0.25976 0.19826 -0.082778 0.20404 0.27866 -0.32214 0.26683 -0.16996 0.065559 -0.033153 -0.37233 -0.14817 -0.70513 -0.29792 -0.43549 0.21966 -0.14124 0.063161 -0.1167 0.23056 0.17694 -0.46328 -0.4211 0.31795 0.06937 -0.13074 0.068277 0.014166 0.11788 0.25749 -0.27967 0.0071493 0.11028 0.14862 -0.39479 0.70441 0.068699 -0.030409 0.42079 0.016701 -0.15536 -0.091807 1.0344 -0.30369 -0.22631 0.6106 0.36308 -0.019935 0.096855 0.023815 1.0099 0.54708 0.44751 -0.44186 0.17654 0.31286 0.34237 -0.014783 -0.22935 0.24776 0.65014 0.14849 0.24625 0.35897 -0.43755 0.087611 0.084289 -0.092697 -0.1195 -0.28025 +other -0.06144 0.13907 -0.15251 0.15441 0.076244 0.14154 0.17104 -0.21644 0.21813 0.29309 -0.00095394 0.0029898 0.0055986 -0.055287 0.036586 -0.086746 0.12844 0.043027 0.015071 -0.061351 -0.067906 0.069628 0.044527 -0.071393 0.021024 0.031831 0.19265 0.0027777 -0.13024 0.081277 0.14577 0.10254 -0.16524 0.28039 -0.018377 -0.093898 0.093526 0.15219 0.13651 0.0073334 0.16772 -0.023001 0.12163 -0.022788 0.048725 0.050573 -0.12345 -0.20483 0.0084026 -0.2819 -0.041475 0.094374 -0.15813 -0.06799 -0.45109 -0.071498 -0.16556 -0.034215 -0.43026 0.25528 -0.0056669 -0.20065 0.31609 -0.051316 0.077715 0.21971 -0.32093 -0.0075352 -0.10382 -0.018169 -0.080878 0.0089464 0.051645 -0.21536 -0.21703 0.22639 0.20479 0.17501 0.10353 -0.062102 0.14903 0.0035497 -0.18489 0.065968 0.13212 0.0027676 -0.031666 0.13545 -0.0097185 -0.051893 0.17964 -0.026688 0.25952 -0.29137 0.043709 0.012291 0.043275 0.0095296 -0.019058 0.13288 0.080184 -0.091995 0.11834 -0.12496 -0.098992 0.030249 -0.093587 -0.02936 -0.012213 0.12523 -0.1506 0.13369 -0.072981 -0.095704 -0.014042 0.07759 0.27774 0.33178 -0.036571 0.050608 0.1577 0.10267 -0.093197 0.34011 -0.062091 0.1156 0.20672 0.18848 0.012482 0.37629 0.069247 0.02612 -0.16087 0.11409 0.10902 0.0098502 -0.1622 0.063179 0.0022694 -0.053578 0.036597 0.071441 0.064592 0.13408 0.039921 0.17445 -0.11835 0.037857 -0.055783 0.076999 0.03013 -0.34679 0.026288 -0.046679 -0.096556 -0.062937 -0.010126 -0.077202 0.19505 0.16586 -0.01868 0.22373 0.010541 0.080339 0.1743 0.010536 -0.17484 -0.18947 0.089363 0.069082 0.0054627 0.039536 -0.1587 0.11398 -0.19848 0.13628 0.19069 0.17036 0.3821 -0.044378 -0.077391 0.12628 -0.055254 0.097946 0.079165 0.18271 0.19934 -0.046055 0.26268 -0.027263 -0.014297 -0.078849 0.066682 -0.027352 -0.25097 -0.053086 0.057189 0.22181 -0.13553 -0.02557 0.026317 -0.21086 0.15813 -0.071769 0.069016 -0.010298 -0.078427 -0.044183 0.0010938 0.23331 0.23129 -0.026975 -0.075833 -0.091101 0.10878 -0.071617 -0.06223 -0.27325 -0.10158 -0.0093918 -0.14901 -0.16606 -0.089922 0.069322 -0.14251 0.077278 -0.20526 -0.24491 -0.10022 0.15759 0.1983 0.12484 -0.0010427 0.066791 -0.006821 0.22785 0.033546 -0.0048719 0.17765 0.018651 0.16746 -0.015371 0.036254 0.11168 -0.051836 0.28015 0.21673 0.08932 0.057131 0.36509 0.14307 -0.091283 -0.13284 -0.14707 0.0044101 0.068573 -0.058182 -0.11829 0.05998 -0.15455 0.17452 0.080535 -0.073275 -0.0039046 -0.27288 -0.14383 -0.30167 0.032485 -0.024228 -0.0073127 -0.12973 -0.12459 0.012493 -0.037983 -0.11108 0.0056298 0.066076 0.097808 -0.16598 0.21693 0.21728 0.046134 -0.0079405 0.032881 0.23987 0.061794 -0.10701 0.22387 -0.22527 0.40613 0.12123 0.072569 0.18289 0.31777 -0.015021 0.09148 -0.098281 0.24074 0.12595 0.034901 +should -0.1574 0.060096 0.12802 -0.0647 0.0073977 -0.10681 -0.18114 -0.39793 -0.12264 0.14537 -0.04591 -0.046891 -0.025864 -0.36477 0.2012 -0.00088587 0.1493 0.14734 -0.059671 0.075768 -0.046534 0.15698 0.07473 0.056786 -0.44776 -0.20732 0.016174 0.066466 0.37869 0.11554 0.079355 0.13391 -0.1575 0.10158 -0.069822 -0.20254 0.069083 0.43622 0.20451 -0.76888 0.022587 0.0026045 -0.51933 0.017892 0.11486 0.34741 0.059008 -0.15326 0.17966 -0.06785 0.021525 -0.35534 -0.14506 -0.32371 0.018787 -0.036814 0.081169 0.046927 -0.25154 0.097335 0.04722 0.14448 0.36331 -0.079142 0.046061 -0.15201 -0.0083216 0.13081 0.053325 0.23444 -0.11466 0.32178 0.10307 -0.36484 -0.080297 0.31483 0.16969 0.25225 0.091764 -0.17543 0.027876 0.06849 0.19697 -0.080172 0.017887 -0.28204 -0.11199 0.17862 -0.46596 -0.056966 -0.037339 -0.12912 0.040572 -0.62686 0.12255 0.18502 -0.011372 0.1382 0.020314 -0.12895 -0.034881 -0.35887 0.10112 0.0095346 0.23554 0.22838 -0.2472 0.022054 0.01542 0.07307 -0.24688 0.15393 -0.1555 0.11564 0.14831 -0.1016 0.32918 0.22461 -0.0030828 -0.088876 0.011739 0.041648 -0.23507 0.29888 0.24103 -0.22085 -0.033185 0.26711 -0.20005 0.38361 -0.1744 -0.013707 -0.11137 0.10985 0.13293 0.16762 0.10234 -0.0023813 0.17318 0.077176 -0.22565 -0.16748 -0.13873 -0.018536 0.023891 -0.1331 -0.11115 -0.074736 -0.20156 0.38026 0.21218 0.15669 0.20158 -0.056155 -0.25372 -0.1124 -0.18889 -0.019705 0.39269 0.054653 -0.13283 0.14885 -0.20738 -0.057547 -0.15208 -0.097722 -0.1017 -0.47307 0.32847 0.45484 -0.28028 -0.059472 -0.65521 -0.06996 -0.28482 0.081245 -0.28534 -0.27181 0.12442 -0.44059 -0.051716 -0.33861 0.12429 0.16512 -0.078012 0.2988 0.42086 -0.2024 0.24935 0.19606 -0.022058 -0.15264 -0.35725 -0.072546 -0.15277 -0.37035 0.13562 -0.01832 -0.61061 0.2132 0.3371 -0.22933 0.23893 -0.069693 0.037648 -0.23856 -0.327 0.21407 0.38387 0.054019 0.39545 -0.2041 0.34428 0.033856 0.34207 0.11701 0.15634 -0.5024 -0.17657 0.312 -0.082118 0.063361 -0.12527 -0.089991 -0.099469 0.35329 -0.18852 -0.17298 -0.24875 -0.45314 0.10131 0.10391 -0.28297 0.1238 -0.23541 0.33473 0.49792 -0.2709 0.027734 -0.1391 0.30889 0.21725 0.37277 0.083933 -0.016265 0.39424 0.34838 -0.15873 0.28669 0.3235 0.25157 -0.062489 -0.075019 0.011022 0.39892 -0.20386 0.060094 -0.3719 0.1618 -0.11329 0.048525 0.12359 -0.33061 0.099359 -0.34309 -0.23388 -0.17498 0.57636 -0.3587 0.030993 0.0058806 0.010174 0.18856 0.22952 -0.054493 -0.079994 0.25315 -0.013323 0.27414 -0.078256 -0.3771 0.20568 -0.078446 -0.097791 0.21115 -0.35054 -0.06222 0.40654 -0.023842 0.056236 0.23455 0.18944 -0.02831 -0.23683 -0.019103 -0.016021 -0.09614 -0.1469 0.40694 0.084852 +two -0.042787 0.021008 -0.010656 0.23691 -0.10914 0.11364 0.08104 -0.08963 0.028048 0.16725 0.32177 0.014753 -0.039365 -0.095328 -0.037779 -0.11079 0.0078022 -0.09653 -0.039211 0.019009 -0.14289 -0.067665 -0.34326 0.02377 -0.22682 -0.0052578 0.062593 0.10703 0.10139 -0.14003 0.047672 -0.055667 -0.027452 0.035716 0.14919 -0.256 -0.096558 -0.022735 0.14314 -0.10151 0.3243 -0.32188 -0.15951 -0.068555 0.2172 -0.018742 0.015399 0.012097 0.084811 -0.13626 0.17574 -0.034163 -0.097007 0.13696 -0.23878 -0.0048385 -0.20212 0.19474 -0.44843 0.033639 0.14343 -0.21568 0.37218 -0.061451 0.0052274 -0.016064 -0.46722 -0.063281 0.020195 0.0057661 0.017295 -0.054501 0.12815 -0.22245 0.17331 -0.015966 0.25723 0.18674 0.053006 0.085951 0.14655 -0.17434 -0.40286 0.031242 0.098365 0.0053966 -0.14235 0.12383 0.10627 -0.26348 -0.15905 -0.36249 0.42316 -0.052531 0.15393 0.19552 -0.044145 -0.087237 0.056422 0.041022 0.11276 -0.096793 0.25266 0.024655 -0.14485 -0.27368 0.025269 0.16717 -0.085138 -0.16551 0.071062 -0.071654 0.017143 -0.15519 0.059725 -0.31675 0.05084 0.25471 -0.076676 0.31278 0.19897 0.1971 0.015398 0.44906 0.025087 0.1328 0.13571 0.3868 0.039457 0.41141 0.25284 0.083078 -0.17362 -0.098972 -0.052513 0.044958 -0.014746 0.018752 -0.0074413 -0.17854 -0.055522 0.036895 0.18334 0.24002 0.070781 0.22418 0.12459 0.082402 -0.12498 0.043271 -0.042265 -0.30769 -0.085772 -0.12223 -0.059418 0.055032 0.12957 -0.060091 0.27064 0.090178 0.015734 0.11379 0.22206 0.13828 0.15071 -0.051125 -0.019157 0.16602 -0.099245 0.018354 0.15507 -0.036933 -0.15022 0.012889 -0.0063673 0.1328 0.065317 0.17652 0.21467 -0.11954 -0.047375 -0.064448 -0.28786 0.08574 0.00095687 0.011876 0.023093 -0.037074 0.14286 0.028145 -0.038296 -0.19369 0.20076 0.12741 -0.021669 -0.039393 0.19729 0.32449 0.0034347 -0.19453 0.083832 0.018411 0.23358 -0.042907 0.021384 -0.20332 0.053472 0.20244 0.19168 0.15364 0.22217 -0.23451 -0.17831 -0.0028738 0.043552 -0.075121 -0.11484 -0.31365 -0.1264 0.056606 -0.015147 -0.089829 -0.10168 0.19851 -0.15027 0.10947 -0.028821 -0.063026 0.16191 -0.03954 0.20144 -0.18327 0.012342 -0.30748 -0.017691 0.046173 0.070848 -0.18618 0.016241 0.01985 -0.010055 -0.11585 -0.00055453 0.0509 -0.017426 0.33063 0.056454 0.07248 -0.098034 0.10158 0.021076 -0.071201 -0.44674 -0.1579 -0.071079 0.14169 0.061102 -0.026971 0.0041137 -0.07955 0.048669 0.13761 -0.13862 0.16066 -0.046004 -0.064986 0.01452 0.036494 0.064753 -0.12347 -0.05979 0.11379 0.043553 0.048641 -0.20961 -0.13571 0.084118 0.11034 0.011665 -0.061593 0.18993 0.092665 0.052162 0.033093 0.21433 -0.032212 0.14639 0.11366 -0.28801 0.36854 0.060341 0.051004 0.1612 0.27889 0.13875 0.1754 0.15241 0.15995 0.13901 -0.028607 +score -0.15244 -0.27529 -0.27765 0.38097 0.15517 0.16141 -0.14116 0.37976 -0.65832 -0.509 -0.42425 0.16641 -0.26355 0.097255 0.23696 0.24004 0.088422 0.052997 0.089343 0.95312 0.20155 -0.634 -0.29676 0.065524 -0.36688 -0.15405 -0.20104 -0.24589 -0.079075 0.48575 0.095243 -0.14028 -0.69932 0.22044 0.17108 -0.19894 0.46685 -0.31989 0.034801 -0.47223 0.23132 -0.063132 0.046305 -0.1576 0.79259 0.077207 0.48955 -0.096814 0.057353 -0.27282 -0.33974 -0.7625 0.015645 -0.15836 0.3131 0.033505 0.22987 0.19108 -0.053603 0.32537 0.22351 0.017425 0.21126 -0.018413 0.30453 0.27641 0.32787 0.11434 0.068597 -0.053261 0.16973 -0.27317 0.53729 -0.63085 0.11855 0.57458 0.55615 -0.49422 0.061108 0.25928 -0.15387 0.33469 -0.028607 0.55928 -0.31189 0.18039 -0.022748 -0.6115 0.22774 -0.1785 -0.38669 0.41127 0.34511 -0.052867 0.098745 0.36626 -0.012764 -0.17242 0.49297 0.23868 0.30851 -0.15631 0.5534 0.057378 0.71497 -0.26304 0.54672 0.00041172 0.036102 -0.37503 -0.29804 0.15049 0.14891 0.31576 0.085442 -0.78308 0.47112 -0.026628 0.27585 0.18507 0.33677 0.16581 0.27025 0.26467 -0.069708 -0.8225 0.084741 0.38287 -0.35794 -0.093632 0.02135 -0.21103 0.089226 0.097074 0.37994 -0.012783 -0.41044 -0.15546 0.053927 0.31133 -0.46455 0.10374 -0.11721 0.10903 -0.067722 0.87756 -0.18155 -0.12693 -0.40676 -0.19251 0.52449 0.14946 -0.68449 0.39646 -0.10068 0.21368 -0.47018 -0.41106 -0.011169 -0.22183 0.061898 -0.050537 -0.018812 -0.57577 0.53488 0.05237 -0.14805 0.1115 0.26874 0.051865 -0.31778 0.053255 -0.33449 0.14802 0.12186 0.17197 -0.16884 -0.10342 0.23543 -0.22899 0.28597 0.055696 -0.30922 0.1901 -0.82077 0.3148 -0.20593 0.2323 0.18972 -0.42438 0.07963 0.23475 0.57722 0.23548 -0.20728 0.22006 -0.25884 0.66452 -0.0090658 -0.23196 0.25818 0.17255 0.044417 -0.14954 0.40784 -0.43706 -0.021882 0.21986 0.30607 -0.32779 0.79621 0.071647 -0.18791 0.22381 0.0035575 -0.118 0.23743 -0.53185 -0.077544 -0.042479 0.19495 0.37906 -0.22511 0.2132 -0.36474 0.42744 -0.40275 -0.34822 0.036713 -0.052918 0.11265 0.89897 0.47807 -0.27026 -0.76058 -0.056153 -0.05259 -0.36204 -0.23027 -0.019439 -0.092298 -0.089746 0.029104 -0.053944 -0.032578 -0.22983 -0.070208 0.023994 -0.94958 0.324 -0.019517 0.17176 0.11694 0.36474 0.19375 0.57564 -0.10682 -0.069977 -0.042213 -0.025878 -0.050978 0.62817 0.27831 0.52425 -0.15368 0.50552 0.065328 0.46116 -0.41793 -0.26485 0.072308 0.75526 -0.68267 -0.019154 -0.43057 -0.65924 -0.061633 0.31031 0.36775 -0.1816 0.3677 0.37244 -0.078389 -0.21082 -0.062693 -0.36108 0.32221 0.43014 -0.50453 0.0068484 0.25323 -0.16632 0.17728 -0.30879 0.16046 -0.091196 -0.59368 -0.023938 -0.24539 -0.024996 +her 0.23168 0.048626 -0.27836 0.31056 0.094327 0.14188 0.073438 0.19866 -0.045887 0.18989 0.34318 0.079454 -0.26854 0.13666 -0.17619 -0.34595 0.34614 -0.13207 -0.1439 0.1975 -0.16547 0.05566 -0.26081 -0.33426 -0.10472 0.37043 0.26517 0.066349 -0.07826 0.12103 -0.029805 0.46365 -0.032161 0.00015458 -0.23173 -0.44874 -0.19774 -0.1909 -0.023242 -0.18589 0.12138 -0.045957 -0.037689 -0.047382 0.24576 -0.17454 0.29004 0.27198 0.057758 -0.090163 0.27872 -0.10864 -0.15795 0.18786 -0.073483 0.018435 -0.028126 0.017418 0.17884 0.14666 -0.10476 -0.12279 0.14288 -0.17318 -0.02388 0.014719 -0.071712 0.35701 -0.084154 0.021109 -0.10371 -0.14549 -0.13569 -0.046792 -0.1764 -0.21526 0.35283 0.45244 -0.19806 -0.14743 0.064685 0.068432 0.13259 0.24881 -0.13337 0.27474 0.04191 -0.11492 -0.1849 -0.091393 0.49665 -0.23468 0.33394 -0.08042 0.11096 0.21692 0.019759 0.044479 -0.091696 -0.099026 -0.08681 0.13417 0.12942 -0.042014 -0.001752 -0.080921 -0.10472 0.01599 -0.088915 0.28181 0.36017 -0.21028 -0.049297 -0.083729 -0.1627 -0.2557 0.16847 0.11451 -0.010631 0.04583 0.14361 0.21059 -0.0042987 0.26214 0.22781 -0.063781 0.022282 -0.2673 0.08283 0.24219 -0.009934 0.1352 -0.014719 -0.12923 -0.025173 -0.047187 -0.26877 0.2545 -0.113 -0.089821 0.0024383 0.19072 0.24396 -0.029729 -0.18403 0.14591 0.17107 -0.18988 0.32828 0.0071863 0.23766 -0.030801 -0.15465 0.15913 -0.17915 0.23688 -0.36471 -0.18214 0.30074 -0.0060663 -0.11913 0.18105 0.0027631 0.04508 -0.047158 0.055689 0.12207 -0.22696 0.055885 -0.070663 0.096064 -0.18138 -0.37981 0.13921 0.13014 0.090286 -0.052579 0.18358 -0.16532 -0.22086 0.28209 0.12862 -0.070395 0.19476 0.033969 0.074122 0.1784 -0.17575 0.052372 0.14591 -0.012021 -0.070865 0.10914 0.41749 -0.48453 0.11691 -0.12289 -0.012057 -0.19648 0.012806 0.32625 0.22425 0.055804 -0.0050075 -0.023336 -0.067192 -0.20549 -0.05042 0.24066 0.06186 0.39495 -0.037596 -0.19763 -0.3068 0.15054 -0.1453 -0.064558 -0.04327 0.053494 0.0013418 -0.23319 -0.27838 0.16989 0.26187 -0.18329 0.067096 -0.30195 -0.33059 0.13896 -0.18142 0.23695 0.17742 -0.049569 -0.14249 -0.27681 0.3414 -0.012318 0.07445 -0.13647 -0.12272 0.059218 -0.049649 0.11954 0.29204 -0.13232 0.13495 -0.17712 -0.064902 -0.23919 0.05341 0.12762 -0.17479 0.11005 -0.043489 -0.0061177 0.030253 0.056088 -0.12052 0.49684 -0.025425 -0.078749 0.018028 0.17026 -0.18412 -0.15622 -0.11463 -0.087827 0.039816 0.16748 -0.38259 -0.12233 -0.22917 0.0033313 0.31758 -0.36227 -0.16464 0.11697 0.1842 0.11025 0.15003 -0.021707 0.16233 -0.22992 0.34437 0.085817 0.27209 -0.14768 0.054135 0.093703 -0.13224 0.107 -0.32351 -0.24226 -0.10018 0.12772 0.077929 0.11739 0.41014 0.05776 0.29077 +can 0.11065 0.24669 -0.18658 0.012708 -0.1912 0.12181 0.16393 -0.33029 0.084313 -0.020997 0.15255 0.097954 -0.16992 0.0054158 0.25897 -0.16895 -0.062122 0.21176 0.16084 -0.11794 0.066001 0.056471 0.071429 -0.17448 -0.22712 -0.18137 0.22941 0.0022489 -0.090471 -0.10937 0.022603 -0.029754 -0.081913 0.20394 -0.05883 0.38965 0.0083053 0.4147 0.084542 -0.27487 0.18505 -0.20228 -0.12477 0.057965 -0.098893 0.22262 0.17805 -0.034665 -0.031314 -0.15987 -0.12464 -0.16906 0.049108 -0.33044 0.00835 0.10887 0.14148 0.15831 -0.096215 0.22528 -0.12001 0.018285 0.21598 -0.049153 -0.21384 0.16079 -0.25483 0.20341 0.11601 -0.0030113 -0.3156 0.20171 0.023238 -0.40907 -0.30345 0.40636 0.27004 0.039163 -0.10858 0.050155 0.074451 -0.0020345 -0.20087 -0.41376 -0.15055 0.10753 0.051928 -0.02967 -0.24054 0.078136 -0.012462 0.056985 0.24968 -0.43275 0.181 0.075832 0.12553 -0.012543 0.071581 0.020161 0.22433 -0.042835 0.15356 -0.045929 0.019526 -0.29031 -0.01736 -0.11194 0.075381 0.037163 -0.052185 0.09066 -0.35524 0.12666 -0.013537 0.056748 0.024969 0.15978 0.06091 0.25759 0.085401 -0.025078 -0.13521 0.59584 0.004185 -0.080007 0.074427 0.016724 0.045648 0.27417 -0.26426 0.24649 -0.068903 0.19791 0.09642 -0.086243 0.071497 0.13084 0.06851 0.064502 -0.088842 -0.093422 0.091265 -0.1271 -0.14387 -0.015616 0.067212 -0.15321 0.20156 -0.06085 0.052899 -0.18268 0.13799 -0.14256 0.13308 -0.099 0.044192 0.0080196 0.31332 -0.0045778 -0.028154 0.0065353 -0.33537 -0.20521 0.23822 -0.13861 -0.10279 -0.2428 0.26514 0.26082 -0.14723 -0.3098 -0.26263 0.17739 -0.14622 0.071931 0.062088 -0.008664 -0.014127 -0.31914 -0.076162 -0.047676 0.28151 0.021578 -0.11013 -0.037121 0.19977 -0.057439 0.33638 -0.15844 -0.14586 -0.21924 -0.18021 0.19421 -0.29355 -0.27361 0.041138 0.23472 -0.34556 -0.1953 0.44968 -0.049309 -0.16264 0.0069003 -0.095944 -0.18031 -0.49247 0.14616 0.13988 0.21808 0.096164 0.23812 0.17263 0.2811 0.26554 0.016168 0.00015303 -0.42821 -0.21857 -0.03789 -0.15536 -0.03722 -0.083077 0.0036336 -0.060149 0.01032 -0.097668 -0.15132 0.039746 -0.15866 -0.022003 0.043917 0.090389 0.12373 -0.14639 0.08397 0.017056 -0.11436 -0.058325 0.010183 0.052068 0.17992 0.13454 0.052547 -0.15264 0.49412 0.1057 -0.093464 0.32841 0.10233 0.034091 -0.053778 -0.12315 0.11066 0.27002 -0.081935 -0.0033055 -0.19624 0.038855 -0.18385 -0.13684 -0.081275 -0.022542 -0.064055 -0.3923 -0.26847 -0.21035 0.12206 -0.049324 0.13168 -0.23663 -0.0017769 0.10158 -0.00020394 0.034525 0.041206 0.16784 0.075352 0.25813 -0.14187 0.038739 -0.011329 -0.24511 -0.21127 0.20413 -0.059722 0.070428 0.30894 -0.13573 0.30826 0.053552 -0.0022851 -0.14715 -0.042718 0.20904 -0.10093 -0.092434 0.10166 0.37379 -0.066493 +would -0.1718 0.20407 -0.12805 -0.1194 -0.0034713 0.00022528 -0.11997 -0.30657 -0.070831 0.2322 0.057163 0.11556 -0.053151 -0.034177 0.0025553 0.055073 -0.10492 0.13993 -0.18622 0.1877 0.14211 0.0030121 0.10997 -0.27424 -0.10383 -0.07769 0.028688 0.22005 0.19349 0.1277 -0.053632 -0.059123 -0.3424 0.10901 0.32244 -0.13964 0.0030524 0.13552 0.12488 -0.26144 -0.019336 0.015202 -0.15297 0.062568 -0.18349 0.22477 0.2246 -0.01921 -0.13234 -0.031977 0.16539 -0.35277 -0.12854 -0.076865 -0.0075283 0.05238 0.13383 0.11366 -0.081689 -0.012893 -0.0038592 -0.21045 0.14448 -0.011442 0.097586 -0.039269 -0.12712 0.013049 -0.030297 8.1278e-05 -0.031521 0.15778 -0.090088 -0.33383 -0.091986 0.32864 0.14892 0.14448 0.21453 0.18254 -0.064034 0.25497 -0.19675 0.071908 0.069495 0.036295 -0.13558 0.061978 -0.28345 -0.090305 -0.02061 0.029704 0.26926 -0.22899 0.031815 0.16741 0.15813 -0.072325 -0.074449 0.041872 0.035609 -0.13304 0.053424 -0.13628 -0.13362 0.022172 -0.024234 -0.033105 -0.037873 0.18874 0.025206 -0.071016 0.10463 -0.020763 0.18851 -0.12185 0.22628 0.15603 -0.044197 0.011843 -0.027987 0.064883 -0.2027 0.55114 0.22254 -0.11485 0.095411 0.21308 -0.16598 0.36874 -0.26465 0.033875 0.15542 -0.068211 0.016409 -0.048438 0.04114 0.19157 0.0098185 0.018522 -0.077304 0.049997 -0.12394 -0.049041 -0.031528 0.15075 -0.12005 -0.1258 0.063948 -0.13458 -0.13339 -0.089657 0.089925 0.12788 0.12403 -0.16948 0.051084 0.11324 0.2164 -0.20488 -0.056652 -0.044194 -0.17219 0.033535 0.23014 0.087979 -0.054478 -0.047862 0.22183 -0.007892 -0.30675 -0.12868 -0.41419 0.031451 -0.15704 0.35029 -0.033362 0.13841 -0.24918 -0.26627 0.032605 -0.13319 0.085732 0.025478 -0.1801 0.092891 0.044088 -0.13969 0.25573 -0.061456 0.02729 -0.37501 -0.13812 0.076751 -0.074056 0.13306 -0.024076 -0.15642 -0.22507 -0.0041005 0.11596 -0.19264 -0.068257 -0.013052 0.054455 -0.14762 -0.16913 -0.062224 0.1269 0.061291 0.24146 -0.098803 0.039748 0.047804 0.10001 -0.014418 -0.081111 -0.37818 -0.054069 0.082554 -0.2394 -0.096796 -0.077977 -0.017959 0.093907 0.2128 0.059378 0.047211 -0.075715 -0.20152 0.14307 0.17057 0.10708 0.1395 -0.02966 -0.0048402 -0.0039836 0.11083 0.062217 0.096046 0.29485 0.12527 0.068873 0.25638 -0.17534 0.20731 0.25223 -0.0035628 0.080299 -0.068458 0.19821 -0.10773 -0.25867 0.22313 0.10636 -0.087242 -0.096388 -0.088481 0.093948 0.21059 -0.04129 -0.20084 0.037923 -0.16166 -0.46664 -0.048007 -0.17123 0.18594 0.011757 0.0387 -0.35408 -0.12095 0.22127 0.35784 -0.018704 -0.14621 0.051415 0.088779 0.15871 -0.1393 -0.043972 0.09362 -0.0075644 -0.13335 0.099203 -0.099608 -0.066301 0.24826 -0.14839 0.16702 0.035673 0.11024 -0.18093 0.19755 0.17225 -0.17392 0.065118 -0.0087422 0.12922 -0.12771 +more -0.062265 0.054583 -0.34177 -0.072886 0.069498 0.17591 0.13537 -0.47121 0.15526 0.28342 -0.17485 0.0409 0.1426 -0.10473 -0.038845 -0.23327 -0.040348 0.096259 -0.085723 0.0010881 0.14577 0.060935 0.031038 -0.24428 -0.20203 0.097133 0.079528 0.13634 0.096165 0.16899 -0.03801 0.15155 -0.48666 0.24273 0.069751 -0.11185 -0.26778 0.021719 -0.3374 0.047032 -0.29859 -0.18702 0.078464 -0.12861 0.15224 0.056118 0.19066 -0.083514 0.054266 -0.65416 0.0080456 -0.10417 -0.02777 0.03847 -0.23184 -0.11388 -0.20609 0.085911 -0.39717 0.18368 -0.099497 -0.46526 0.028331 0.15011 0.065685 -0.031211 -0.24155 0.0072738 -0.038002 0.09869 -0.084207 0.14412 0.03799 -0.11766 -0.074207 0.23905 0.25249 0.21561 -0.067703 0.14611 -0.033213 -0.068822 -0.12538 0.016897 -0.14153 0.039518 -0.022735 0.092429 -0.0015664 -0.10173 -0.18981 -0.093919 0.17465 -0.25521 0.038248 -0.085836 0.0063147 0.31928 -0.14131 0.058558 -0.08535 -0.30144 0.43935 -0.0063806 -0.15512 -0.26053 -0.023682 0.12039 -0.045526 0.055767 -0.094706 -0.049216 -0.22913 -0.10579 -0.073095 -0.20922 0.090216 0.10465 -0.086462 0.11605 0.031051 0.016164 0.11152 0.34764 -0.020391 0.2244 0.11667 0.18661 -0.0035405 0.15297 0.066898 0.18764 -0.13053 0.047214 0.035867 -0.082279 0.038933 0.18259 -0.11664 -0.0072299 -0.10614 0.028215 0.23751 0.034961 -0.10312 0.12699 -0.094866 0.17719 -0.082439 -0.25039 0.002859 -0.1702 0.0453 -0.18327 -0.10215 -0.25624 0.1135 0.041328 0.16561 0.11672 -0.044776 0.1507 -0.070618 0.14486 0.25621 0.067111 -0.0027355 -0.096868 0.17279 0.041157 0.091273 -0.064576 -0.2636 0.17159 -0.0092151 0.053611 -0.094215 -0.16783 0.073684 -0.34343 0.19844 -0.0030726 0.053475 -0.011546 -0.20708 0.1515 -0.065465 -0.087974 0.34137 0.005492 0.011758 -0.16623 0.18 0.048066 0.051461 0.11385 0.13081 0.26563 -0.072114 -0.047465 0.17949 -0.097362 0.2648 0.04005 -0.023518 -0.15128 -0.36072 0.16394 0.19598 0.24771 0.14462 -0.093194 -0.091987 -0.20417 0.097881 -0.2197 -0.13437 -0.37148 0.044689 0.068207 0.034891 -0.25809 0.0040472 0.023805 -0.038203 0.12325 0.038626 -0.16515 -0.16713 0.16252 0.32116 0.21913 0.11432 0.039666 -0.0081866 0.088642 0.11672 0.10059 -0.069806 0.0843 0.07772 0.045912 0.30107 -0.013712 -0.10357 0.26482 0.22652 -0.03292 -0.060853 0.22898 0.14885 -0.10172 -0.087208 0.15748 0.28746 0.2757 0.11958 -0.08932 0.020088 0.25733 0.11594 0.17577 -0.053464 -0.11426 -0.18997 -0.24783 -0.11861 0.16175 -0.07467 -0.13321 -0.28561 0.088002 -0.18125 -0.044171 0.086122 -0.0088807 -0.10745 0.089452 -0.18647 -0.20805 0.4019 -0.0011913 0.14924 0.035179 0.070987 -0.24171 0.21177 0.058404 0.03807 0.24775 0.10885 -0.020788 -0.2616 0.11742 0.010237 -0.27443 0.051525 0.20817 0.51341 -0.1416 +if -0.12616 0.22499 -0.037107 0.12213 -0.18742 -0.05672 -0.11921 -0.38085 -0.12349 0.22238 -0.086186 -0.1249 -0.07589 -0.071779 0.13988 -0.083694 -0.17797 0.23753 0.07153 0.20399 0.096339 0.069289 -0.070968 -0.1491 -0.14367 -0.23984 0.079839 0.10207 0.017729 0.075825 -0.17449 -0.045256 -0.26928 0.11753 -0.16427 -0.11129 0.12492 0.15406 0.035314 -0.22533 -0.016771 -0.011433 -0.16572 0.043499 0.12072 0.085306 0.27966 -0.011938 0.049507 -0.047958 0.00029264 -0.43705 -0.006693 -0.17654 -0.12585 0.15614 0.067953 0.004918 -0.31274 0.088161 -0.32166 -0.031172 0.21421 -0.14849 -0.070395 0.03522 -0.020869 0.051751 0.21955 -0.088108 -0.027017 -0.020411 0.096381 -0.18986 -0.11994 0.3591 0.2508 -0.010006 0.038699 0.24614 0.25881 0.080285 0.12193 0.028502 -0.32296 0.019352 -0.044835 0.068242 -0.050521 -0.12305 0.11744 -0.031646 0.22274 -0.10507 0.088955 0.14392 0.35377 0.16241 -0.13563 0.012796 0.011897 -0.33567 0.098678 -0.27397 -0.1502 -0.08556 0.095251 -0.19293 0.094187 -0.039037 -0.20571 -0.12335 -0.13202 0.050304 0.20653 -0.26544 0.20521 -0.17092 0.057569 0.089343 0.20328 0.069316 0.023845 0.62272 0.025728 -0.12045 0.27762 -0.051973 -0.074864 0.251 -0.11419 0.1044 -0.13759 0.14796 -0.012139 0.059226 -0.00721 -0.10776 0.17191 0.045543 -0.19136 -0.28336 0.13276 -0.10874 -0.13938 -0.0058364 -0.088917 -0.14509 -0.12095 0.0077211 0.16916 0.034059 0.092245 -0.077555 -0.22604 0.035186 0.031959 0.17725 0.13987 0.18107 -0.17751 0.13049 -0.22287 -0.08821 -0.029787 -0.014991 0.0021661 -0.32947 0.17164 0.12099 -0.1554 -0.41531 -0.36204 0.080142 -0.28251 0.21688 0.002996 0.057012 -0.052235 -0.11665 0.032845 -0.093121 0.12415 0.065068 -0.23843 0.17181 0.098351 -0.074536 0.26568 -0.081406 -0.013541 -0.23585 0.012417 0.1036 -0.23169 -0.28153 -0.068329 -0.040742 -0.46197 -0.034316 0.44892 -0.10007 0.10757 -0.05324 0.002615 -0.024433 -0.26507 0.15952 0.028571 -0.050901 -0.078532 0.029727 0.24103 0.079303 0.093389 -0.0586 -0.098049 -0.39889 -0.12801 0.22079 -0.25557 -0.17188 0.079853 -0.026602 -0.065453 0.38231 -0.35298 0.035204 -0.014982 0.11602 0.1844 0.11308 -0.27927 0.15167 0.11879 0.11681 0.083238 -0.26974 0.097656 -0.014023 0.10805 -0.011265 0.095326 0.046024 -0.039706 0.46449 0.29367 0.026597 0.013715 -0.0039747 -0.12344 -0.19045 -0.15088 0.14995 0.17483 0.010291 0.03331 -0.32922 -0.1241 0.0081297 -0.051847 -0.16308 -0.1175 -0.30872 -0.059714 -0.094624 -0.01242 0.1133 -0.13078 0.016961 -0.39329 -0.1387 0.28426 0.095757 -0.38252 -0.083695 0.22287 -0.097667 0.14177 -0.075183 0.12376 0.23737 -0.34419 -0.16441 0.0081563 -0.27079 -0.033009 0.36906 0.028833 0.16592 0.16683 0.23614 -0.034455 -0.088944 0.015679 -0.27553 -0.22669 0.00049742 0.27207 -0.20315 +she 0.088637 -0.0041191 -0.2539 0.32839 0.13474 0.21099 0.15887 0.13855 0.0084253 0.21534 0.30048 -0.064144 -0.052371 -0.11812 -0.12325 -0.4025 0.30414 -0.29539 -0.091729 0.24486 -0.042637 -0.017132 -0.28279 -0.37561 -0.1136 0.31833 0.27959 -0.097287 0.0099161 0.075482 -0.092898 0.34215 0.01188 0.070913 -0.079244 -0.46072 -0.16607 -0.32089 -0.067372 -0.10502 -0.097204 0.10914 -0.15526 -0.049404 0.092036 -0.26817 0.14362 0.26702 -0.04449 -0.10933 0.18751 -0.12888 -0.042224 0.21953 -0.014486 -0.13708 0.0061556 0.27584 0.27403 0.2365 -0.059322 -0.026784 0.043424 -0.2899 -0.0091051 -0.11771 -0.22181 0.26172 -0.19857 -0.0011452 -0.17981 -0.29999 -0.031459 0.14812 -0.1499 -0.087872 0.28076 0.30934 -0.23802 -0.16786 0.14296 -0.035512 0.26491 0.24909 -0.26859 0.13965 -0.12523 -0.087567 -0.14256 -0.15192 0.46855 -0.31569 0.42575 -0.064321 0.14631 0.29015 0.17018 0.16241 -0.21218 -0.13002 -0.051941 0.21202 0.11423 0.069989 -0.090881 0.0091649 -0.20809 -0.090646 -0.11007 0.19675 0.20297 -0.30239 -0.00785 -0.045531 -0.2349 -0.31942 0.28778 0.14415 -0.13988 -0.098262 -0.024856 0.28631 0.072734 0.31169 0.17349 -0.094652 0.19358 -0.078619 0.041911 0.29315 -0.14378 -0.0032431 -0.17262 -0.11287 -0.14833 0.052479 -0.12002 0.21177 -0.23899 0.046967 0.034401 0.15859 0.19077 -0.13028 -0.1057 0.050739 0.076116 -0.28666 0.27083 0.027517 0.078062 -0.17299 -0.23644 0.31155 -0.35043 0.010832 -0.25374 -0.19897 0.39576 0.14564 -0.16733 0.35596 -0.1486 0.010577 0.077298 -0.10801 -0.02522 -0.27463 0.035758 0.0087457 0.30075 -0.1506 -0.37348 -0.00014688 0.080223 0.039295 0.024266 0.12489 -0.18261 -0.15411 0.25599 0.13696 -0.075897 0.23621 -0.11996 0.059082 0.0045113 -0.0265 -0.15862 0.14833 -0.13717 -0.075295 0.0036068 0.3343 -0.47609 -0.10999 0.0025772 0.20641 -0.30106 -0.14034 0.30545 0.22107 -0.17733 0.14956 -0.10698 -0.041806 -0.15489 -0.09282 0.34236 0.24458 0.41244 -0.22156 -0.19863 -0.11431 0.048688 -0.038552 -0.093706 -0.13012 0.14795 -0.025128 -0.18354 -0.16991 0.16199 0.0065366 -0.38862 -0.11147 -0.27128 -0.15628 0.16608 -0.07611 0.27857 0.32981 -0.077059 -0.17226 -0.060446 0.18249 -0.14718 0.078722 -0.023768 -0.10865 0.025488 0.010844 0.25315 0.19115 -0.35454 0.14154 -0.0076163 -0.065071 -0.36534 0.0032655 0.12861 -0.17817 -0.041918 -0.042774 -0.063015 -0.081107 -0.051664 -0.10624 0.38855 -0.078108 -0.0071574 -0.069308 0.21146 -0.38771 -0.068994 0.024726 -0.12444 0.018235 0.17583 -0.20191 -0.13731 -0.083628 -0.13808 0.1071 -0.37167 -0.16071 0.24343 -0.013551 0.13299 -0.044403 0.017013 0.15802 -0.28619 0.17508 -0.082188 0.12236 0.017264 0.03408 0.068108 -0.12794 0.15692 -0.33882 -0.099046 -0.10486 -0.0048754 0.12953 -0.17471 0.1239 0.046296 0.27141 +about -0.02117 -0.19597 -0.17566 0.068444 -0.10362 0.25931 -0.19705 -0.1071 -0.037362 0.24331 0.1144 -0.073582 -0.1752 0.083303 -0.044602 -0.042278 -0.093841 -0.26415 0.13791 -0.17512 -0.080789 0.16483 -0.18894 -0.18477 -0.033257 0.012606 -0.03464 0.13875 -0.12464 0.042962 -0.12061 0.29217 -0.4056 0.31941 0.24523 -0.21372 -0.12665 0.083957 0.087132 -0.11844 0.049932 -0.33478 0.01125 -0.051822 0.19283 0.21699 0.12328 -0.37568 -0.11486 -0.44125 -0.058069 -0.10104 0.014334 -0.18094 -0.14433 0.20694 -0.0027149 0.01634 0.0035786 0.047189 -0.028162 -0.34049 0.27681 -0.059386 0.076087 -0.14837 -0.1629 0.19988 0.016894 0.12956 0.012359 0.080496 -0.077657 0.20362 -0.3258 -0.015109 0.13674 0.24215 -0.035731 0.10067 -0.060621 -0.058521 0.15173 0.016624 0.14005 -0.0086683 -0.13888 0.068091 0.27311 -0.3558 0.15976 0.01025 0.2026 -0.14608 0.22621 0.17506 0.092277 0.16467 -0.015469 0.016435 0.035638 0.11681 -0.0031958 -0.15474 -0.18961 0.10261 -0.063694 -0.049136 -0.13714 0.091628 -0.2165 -0.012953 -0.051439 -0.20766 -0.11394 0.015306 0.042476 -0.099484 -0.022252 0.29262 0.3231 -0.11997 0.10106 0.24496 0.28685 0.21644 0.23544 0.012333 0.04538 0.048762 -0.19626 0.2574 -0.0082096 -0.1688 0.075443 -0.060146 0.0096855 -0.10363 0.11203 -0.039349 0.036326 0.2952 0.26943 0.079253 0.25954 0.095624 -0.019848 0.03334 -0.020207 0.12494 0.034105 -0.095289 0.0063355 4.9114e-06 -0.11855 -0.33407 0.18545 -0.20634 0.1389 0.25303 -0.34299 0.16345 -0.060712 -0.024768 0.061532 -0.01166 -0.040821 -0.24711 0.059865 -0.074688 -0.1537 -0.15449 -0.35479 0.082513 -0.15572 0.33163 -0.29826 0.27127 -0.083518 -0.21417 0.23025 -0.022065 0.01273 0.21493 -0.20771 0.012134 0.0060677 -0.020164 0.32774 -0.027613 0.29355 -0.25445 0.15754 -0.20599 -0.065063 -0.18885 0.05489 -0.20909 -0.10499 0.060729 0.15194 -0.11733 -0.015553 0.27421 0.017147 0.18327 -0.086887 -0.067685 0.24103 0.036526 0.46748 0.15011 0.089018 -0.018038 -0.024523 -0.1317 -0.046702 -0.29199 -0.18877 0.094677 -0.062552 -0.17198 0.0094479 0.13493 -0.086165 -0.096536 0.054055 -0.11857 -0.089862 0.43743 0.071039 0.10439 -0.22311 0.13751 0.056511 0.13718 0.19523 -0.092006 -0.13229 -0.14534 0.032469 -0.074011 0.43693 -0.026786 0.14359 0.28937 2.8598e-05 -0.0741 -0.0082564 0.083453 -0.0027697 0.16148 -0.28854 -0.048033 0.19265 -0.10285 0.23689 0.047605 -0.14256 0.097135 0.028295 0.17282 -0.07189 -0.40373 0.045206 -0.23179 0.020785 0.31354 -0.1719 0.18374 0.024841 0.16757 0.28526 0.074034 0.035083 -0.0011852 0.3365 0.34824 -0.0022259 -0.015025 0.17573 0.010512 0.15606 -0.078563 0.0042496 -0.064414 0.083727 -0.043555 0.18772 0.27135 0.14738 0.037969 -0.037352 -0.20263 0.10002 -0.18698 -0.10187 -0.050635 0.20937 0.14377 +when -0.079192 0.051937 -0.073137 0.22574 -0.040992 0.081891 0.05592 -0.16604 0.12364 0.12599 0.050597 -0.097229 -0.040986 -0.049584 0.12142 -0.094617 -0.025135 -0.19609 0.0045745 0.30816 -0.12535 0.10154 -0.22607 -0.22216 -0.13464 -0.03449 0.13343 -0.077697 -0.12128 -0.022091 -0.22263 0.09045 -0.04126 0.19687 0.0097724 0.029227 -0.0024994 -0.048418 0.18661 0.023984 -0.010036 0.032983 -0.14538 -0.088083 0.080524 -0.094768 0.18928 0.17808 0.05114 0.025251 -0.0048035 -0.20645 -0.038928 -0.0032834 -0.070349 0.091013 -0.021867 0.11712 -0.046408 -0.0066714 -0.0025313 -0.18644 0.060189 0.0069031 0.057839 -0.22415 -0.053748 0.19452 -0.062946 -0.072071 -0.20787 0.042111 -0.04319 -0.2338 -0.047608 0.13866 0.26609 0.23457 0.036274 -0.077756 0.19782 -0.029642 -0.014698 0.13516 -0.21204 0.06746 -0.067529 0.08547 0.10538 -0.19402 -0.072265 -0.075448 0.1511 -0.052235 0.20347 0.053472 0.086102 0.1264 -0.304 -0.013469 -0.015231 -0.13691 0.21319 -0.10472 -0.11937 -0.34622 0.068538 -0.10805 0.16844 0.066641 0.081309 -0.16294 -0.090998 -0.039426 0.028866 -0.21873 0.11943 -0.084581 -0.14489 0.082191 0.22951 0.33993 -0.15326 0.41029 0.03822 -0.13179 0.29583 -0.11452 0.1091 0.25458 -0.20241 -0.074556 -0.21303 0.025859 -0.18118 0.1218 -0.013 0.060915 -0.036947 -0.024474 0.080968 0.076762 0.070246 -0.24321 0.0094205 0.1966 0.017077 -0.087365 -0.030978 0.020497 0.1496 -0.039391 -0.11123 0.19104 -0.093399 -0.12989 -0.052082 -0.11003 0.25784 -0.0037732 -0.11944 0.21392 -0.12597 0.15279 0.044907 0.069257 -0.0162 -0.07313 0.063035 -0.01174 -0.14247 -0.12437 -0.18466 -0.10271 -0.032356 0.15672 -0.052928 0.070907 -0.14252 -0.21541 0.082489 -0.22774 -0.051416 0.059824 -0.16668 0.155 -0.037062 0.050439 0.16892 -0.11746 -0.068364 -0.13143 -0.033546 0.17683 -0.13915 -0.078444 -0.10178 -0.032779 -0.31915 -0.073979 0.042498 0.050356 -0.22595 0.034351 0.14558 -0.096116 -0.04606 0.04266 0.12621 0.17711 0.11921 -0.041557 -0.038073 -0.028597 0.025634 -0.047897 0.0044187 -0.13033 -0.097969 0.21369 -0.23849 -0.12311 0.10717 0.037259 -0.1653 0.037315 -0.18959 -0.066907 -0.065743 0.15921 0.24763 -0.13213 -0.088821 0.18956 -0.03396 0.23713 0.16423 -0.10951 0.13717 -0.10103 -0.022793 -0.15407 0.054171 -0.058853 0.036986 0.12509 -0.0037783 -0.031217 0.066279 -0.07492 -0.02585 -0.046586 -0.13731 0.0024207 -0.093833 -0.038427 -0.16655 -0.29927 -0.24765 0.031964 0.029605 0.00046473 -0.07312 -0.33074 -0.0984 -0.21829 -0.084855 0.061619 -0.064418 -0.023993 -0.3056 -0.17084 -0.012347 0.15398 -0.27505 -0.12766 0.37464 0.065888 0.27589 -0.094503 0.12573 0.014114 0.050861 -0.036783 0.04245 -0.015647 0.062081 0.2796 0.071021 -0.11854 0.03015 0.075829 0.23557 -0.051882 -0.043097 -0.060912 -0.05152 0.086042 0.041766 -0.0097737 +time -0.098853 0.085878 0.081227 0.0060538 0.053763 0.082205 0.056332 -0.064007 0.077535 0.24336 0.13731 -0.041984 -0.072882 0.019551 0.091529 0.071828 0.088423 -0.012137 -0.02592 0.40074 -0.13524 0.14085 -0.23255 -0.28288 -0.14529 -0.19126 -0.076804 -0.090844 0.11687 0.091688 -0.067823 -0.017835 -0.25803 0.32064 -0.0061298 -0.068384 0.27628 -0.16547 0.058737 -0.03926 0.096325 0.063284 0.064625 -0.036501 -0.1264 -0.056104 0.086553 0.059131 -0.11705 0.063255 -0.331 -0.1638 0.15415 0.026053 -0.038725 0.082045 0.19577 0.087718 -0.072145 -0.042519 -0.004571 -0.10167 0.096091 -0.32968 0.070644 -0.011796 -0.036185 0.13546 -0.1799 0.11332 -0.013678 0.10512 -0.20419 -0.34031 0.10067 -0.10259 0.4134 0.24273 -0.024205 -0.10657 0.37068 0.17766 -0.20318 0.093132 -0.091021 0.13592 -0.17554 -0.13114 0.069529 -0.093941 -0.092939 0.011419 0.27746 -0.036033 0.097347 -0.13661 0.16296 0.13232 -0.40358 0.20427 0.18472 -0.072923 0.15663 -0.0011849 -0.38536 -0.213 -0.1043 0.082757 0.026915 0.054655 0.2265 -0.13565 -0.069691 -0.065142 0.14828 -0.12326 0.21315 0.17508 -0.087254 -0.025956 0.084014 0.26203 -0.11964 0.16929 0.15828 -0.032353 0.26372 -0.030364 0.189 0.052159 0.14333 0.20369 -0.19383 -0.12759 0.024925 -0.0308 0.029004 -0.016596 0.063208 0.18862 -0.010563 -0.11352 0.11039 0.21663 0.13684 0.2198 -0.22453 -0.31191 0.0644 0.14003 0.21781 -0.12942 -0.037692 -0.10347 -0.050457 -0.056158 -0.12084 0.047517 0.023001 0.037065 -0.16958 0.18613 -0.14835 0.1517 0.1074 0.11638 0.044715 -0.022865 0.033388 -0.027744 -0.14668 -0.066816 -0.08047 0.061668 -0.037452 -0.084882 -0.15615 0.05489 -0.13312 -0.40098 0.049256 -0.067677 0.030799 0.17709 -0.25783 0.10226 0.043235 -0.145 0.17913 -0.16006 -0.094504 -0.015269 -0.045712 0.050356 -0.042752 -0.10333 -0.070811 -0.026794 -0.22519 -0.2829 -0.010017 -0.13 0.039291 -0.081257 0.13079 -0.02125 0.1643 -0.011918 0.27238 -0.029841 0.41964 -0.17665 0.07423 -0.093924 -0.15099 -0.064315 0.023076 -0.27046 -0.11245 0.088511 0.063565 -0.16609 -0.14994 0.14697 0.1669 -0.023483 0.012004 -0.11835 0.11025 -0.17928 0.060118 0.082756 -0.070005 0.13414 -0.12867 -0.16912 0.20379 0.088675 0.036372 -0.12614 0.15561 -0.042898 0.087396 -0.098318 -0.0089613 0.21252 0.089623 0.037438 0.012131 0.16955 -0.01486 -0.024982 -0.070166 0.085275 -0.074443 -0.014739 -0.05063 -0.19453 -0.14548 0.068449 0.090577 0.10299 0.21393 -0.07683 -0.11359 0.12907 -0.034517 -0.037995 -0.11578 -0.2823 -0.27787 -0.11544 -0.087073 0.18893 -0.16036 -0.076131 0.15249 0.14793 0.25227 -0.021144 0.14848 0.084297 -0.091556 -0.35141 0.0085903 -0.0031398 0.1118 0.10066 -0.09904 0.079178 -0.05699 -0.062982 0.012735 0.020347 0.031725 0.059233 -0.18578 0.16508 0.27065 0.32405 +team -0.65398 -0.16966 -0.34981 0.39667 -0.42664 -0.075153 0.059407 0.045785 -0.29527 -0.2451 0.12017 -0.028032 0.20108 -0.029071 0.25253 -0.31646 -0.15195 0.17076 0.31405 0.43681 -0.10074 -0.11138 0.082594 0.13266 0.044793 -0.17278 0.061196 -0.11738 -0.17216 0.31848 0.27359 -0.013458 -0.23732 0.059553 -0.0029666 -0.35684 0.50161 0.31745 -0.050448 -0.12704 0.39116 0.32415 0.13797 0.033228 0.43631 -0.13866 0.077202 0.29273 0.21816 0.42386 0.029208 -0.34362 -0.018073 -0.045898 0.034509 -0.40266 0.20486 0.33692 -0.082034 0.26243 0.15231 -0.30651 -0.12579 -0.23959 -0.12593 0.090745 -0.010624 -0.25832 -0.4844 0.098986 0.3393 0.13819 -0.0086807 -0.59506 0.037135 0.18085 0.23985 -0.30967 -0.10148 -0.17618 -0.32082 0.096802 -0.24591 0.057463 -0.077628 -0.10064 -0.23154 -0.19826 0.16165 -0.29922 -0.22913 -0.1272 0.3657 0.39751 0.16954 0.078879 0.094865 -0.0064163 -0.13524 -0.27822 0.33415 0.073928 0.038107 -0.038782 0.28445 0.013273 0.34513 -0.016024 -0.055387 -0.18233 -0.030241 -0.0568 0.080688 0.41306 -0.069433 -0.11593 0.18148 0.57579 -0.35439 -0.14954 0.22949 -0.021401 -0.22574 0.032983 0.28496 -0.2444 0.56428 0.27931 -0.081341 -0.029487 -0.16763 0.23146 -0.51285 -0.16312 -0.10144 -0.086669 -0.14645 -0.35756 0.0044937 0.54596 -0.27604 -0.026918 0.45539 0.069067 0.53201 0.1788 0.33365 -0.046265 0.03755 -0.25689 0.091694 0.23297 -0.046139 0.14183 -0.48041 -0.089476 -0.087632 -0.46163 0.077675 0.090215 0.12426 -0.33985 -0.17751 -0.30674 0.79849 0.15644 -0.41451 0.59923 0.11277 0.035359 0.12009 -0.1047 -0.058756 0.10232 -0.11901 0.79351 -0.20289 -0.15511 -0.1215 -0.19642 0.060591 0.13933 -0.046517 -0.25958 -0.39926 0.12661 0.10226 -0.52038 0.44324 -0.4443 -0.12426 0.27222 0.10362 0.29432 -0.33162 -0.16706 -0.19466 0.3228 -0.084685 -0.41875 0.19601 0.097001 0.14635 0.11507 0.079829 0.011428 -0.0020601 0.081876 0.38116 -0.077098 0.50947 -0.26865 -0.18447 -0.18381 -0.076132 -0.15705 -0.148 0.14413 0.14905 0.10396 -0.4 -0.074567 -0.29085 0.44991 -0.071661 0.15135 -0.29063 -0.25159 0.0077423 0.49336 0.26623 0.10775 -0.14479 -0.089161 -0.20153 0.074814 0.13382 0.12208 0.1235 0.01031 0.064102 0.1244 0.26921 0.14946 0.47981 0.11891 0.072451 0.23521 -0.66894 0.026628 0.025449 0.050326 0.31396 -0.24424 0.20225 0.011259 0.12181 -0.41117 0.15232 0.14716 0.087064 -0.0080595 0.50214 -0.0084723 -0.47949 0.24652 0.35515 0.36791 0.053035 -0.37553 0.23588 0.044528 -0.43712 0.084474 -0.35697 -0.052381 -0.057837 0.26952 0.23565 -0.021268 -0.010105 0.24131 0.064086 -0.39949 0.057556 0.21088 0.41121 0.3957 -0.31234 -0.25644 0.073138 -0.65492 0.27123 -0.21063 0.054193 -0.2357 -0.0061772 -0.21022 -0.015745 0.085533 +american -0.17814 0.021955 0.15505 -0.099185 -0.27303 0.2069 -0.078039 -0.10141 -0.1762 0.25109 0.14317 0.12695 0.013783 -0.32117 -0.18242 0.24378 0.03081 -0.24322 -0.20234 0.089927 -0.42863 0.26754 -0.30416 -0.25869 0.28481 0.01224 0.27936 0.23353 0.50181 0.21834 0.064719 -0.012249 -0.4692 -0.086933 -0.10333 0.074404 0.002556 -0.094726 0.3412 -0.0021412 -0.054657 -0.22297 -0.29429 0.19442 -0.33078 -0.34079 -0.1432 -0.2667 -0.10396 -0.32391 0.029696 -0.014755 0.069155 -0.28558 -0.47641 0.049965 0.2327 0.15873 0.27182 0.69888 0.23516 0.01731 0.5599 -0.059756 0.12832 -0.065076 -0.17365 0.07315 -0.26237 -0.076697 0.14156 -0.37231 0.077497 -0.17971 0.011276 0.063538 0.19445 -0.25374 0.0031444 0.10546 0.017845 0.056909 0.042267 0.09863 -0.30088 -0.11199 -0.16839 0.10943 0.15437 0.29943 -0.011852 -0.19011 0.27708 -0.27608 0.15134 -0.25962 0.035183 0.21864 -0.42442 0.29946 -0.068205 -0.028959 0.31467 -0.073441 0.17675 -0.0109 0.068566 0.12738 -0.016132 0.1053 0.17893 -0.22539 -0.18286 -0.039407 -0.10367 0.38248 0.088434 0.18616 -0.067612 -0.08458 0.217 -0.23181 -0.17957 0.16475 -0.090403 0.010813 0.058231 0.19045 -0.0037158 0.061612 0.19022 -0.011215 -0.091676 0.01718 0.10128 0.17365 -0.12937 -0.22261 0.13682 0.084329 0.11779 -0.0010732 0.29977 -0.029216 -0.22304 0.43209 -0.0029062 0.014512 0.0084956 -0.26431 -0.1414 -0.27934 -0.39745 -0.2306 -0.44517 0.070579 -0.10163 0.0029622 0.35362 0.39292 0.20384 0.18424 -0.094832 0.14235 0.38118 -0.031478 0.25874 0.00025493 0.26868 -0.41585 -0.10672 0.38325 -0.074869 -0.0609 0.05302 0.20744 -0.23796 -0.028788 -0.17704 -0.095766 0.01635 -0.029296 -0.16783 0.039242 -0.25568 0.52242 -0.28106 -0.15574 -0.072394 -0.097651 0.11953 -0.17638 0.037532 -0.043097 0.08715 0.23321 -0.10217 0.38121 -0.094865 0.13887 0.26207 0.044105 0.14945 0.029885 -0.068417 -0.27626 -0.1516 -0.69775 0.55712 0.062967 0.59965 -0.14932 0.23032 -0.020874 -0.19812 -0.20424 -0.08505 -0.47102 -0.34162 0.19458 -0.23252 -0.30705 -0.10517 0.49428 -0.19124 0.11929 0.045211 -0.20592 0.082783 0.26686 0.38932 0.30137 0.027935 0.076626 0.080591 -0.17228 0.13917 -0.045914 0.13949 0.17192 -0.10865 0.42163 0.13456 -0.028841 0.077871 0.13395 -0.3189 -0.080554 0.31202 0.13109 0.31024 0.27055 0.1501 -0.10647 0.13359 0.41551 0.34962 0.19734 0.20257 0.55784 -0.28603 -0.042326 0.2778 -0.21109 -0.3705 -0.092742 0.0038481 0.50462 0.42018 -0.16981 -0.094061 -0.18785 -0.23779 -0.077147 0.010325 0.090652 -0.18029 0.17065 -0.047728 -0.035796 -0.11494 0.63033 0.10139 0.067471 0.30453 0.22438 -0.22147 0.34278 -0.10598 0.47833 0.14666 0.10379 0.42018 0.083425 -0.43787 -0.10404 0.15555 0.26603 -0.17047 -0.20729 +such -0.12798 0.13145 -0.22197 0.0058357 0.1651 -0.095917 0.32568 -0.10462 0.24523 0.13012 -0.08226 0.026979 0.060964 -0.073824 0.12574 -0.08641 0.096926 0.18688 0.069761 -0.088073 -0.10784 -0.031234 -0.036162 -0.042651 -0.062318 0.087131 0.010365 -0.063926 -0.022637 -0.075545 0.21122 0.31282 -0.044729 0.13682 0.066594 0.011819 0.18471 0.10879 0.15241 -0.29594 -0.09772 0.23172 -0.21611 -0.13671 -0.013262 -0.014378 -0.13024 0.0080328 0.35638 -0.079463 -0.25034 0.1264 0.0020699 0.11761 -0.23886 -0.011504 -0.00098982 -0.074777 -0.46857 0.32139 -0.015333 -0.093332 0.18131 -0.13096 -0.089179 0.098706 0.15193 -0.12278 -0.086615 -0.010303 -0.27971 0.32589 -0.038619 -0.19531 -0.077503 0.064999 0.35983 -0.11269 0.066492 -0.19467 0.2417 -0.012765 0.014683 -0.17104 0.21524 -0.19643 -0.0090294 0.30212 -0.38072 -0.13592 -0.050039 -0.055755 0.14237 -0.42884 0.13645 0.12215 0.19613 0.29564 -0.0075488 0.059612 -0.010777 -0.29674 0.094169 -0.055127 -0.080118 0.21585 -0.080327 0.23227 -0.059557 0.025002 -0.32508 0.10213 -0.2598 0.021646 -0.068955 0.17479 0.17808 0.12207 -0.11701 -0.030567 0.18592 0.087021 -0.14391 0.020522 -0.073918 0.045444 0.20172 0.38159 -0.18689 0.48186 0.02098 0.019888 -0.15551 0.22838 0.2685 0.018227 -0.28857 0.079363 0.091208 -0.0098216 -0.058257 0.0071114 -0.073559 0.0096323 -0.038589 0.22841 -0.12771 0.33464 -0.27901 0.32457 -0.054715 -0.14574 0.056218 -0.1324 -0.34856 0.001773 0.11528 -0.086062 0.065331 0.13759 -0.20087 0.25974 -0.31245 0.021545 0.027365 -0.30158 -0.12007 -0.22888 0.10119 0.33733 -0.17767 0.15087 -0.216 -0.097118 -0.2722 0.031288 -0.12359 0.034923 0.22925 0.086194 0.10833 0.038424 0.27415 0.04379 -0.0709 0.2374 0.30458 -0.1651 0.1768 0.048894 0.010031 -0.099322 -0.050672 -0.11999 -0.047515 -0.22037 0.079071 0.18324 -0.42455 0.21304 -0.12204 -0.10204 0.30397 0.031754 0.042074 -0.34014 -0.35375 -0.14484 0.12462 0.17177 0.53553 -0.047845 0.28198 0.095491 0.058297 0.11064 0.31361 -0.30141 -0.21036 -0.080112 -0.28644 -0.17227 -0.19908 0.16042 -0.27719 -0.17992 -0.30815 -0.40998 -0.17022 -0.038969 -0.0087258 0.11784 -0.00432 -0.033765 -0.30243 0.48239 0.2683 -0.16684 0.0037789 -0.086896 0.1411 -0.023405 0.17642 0.040334 -0.088099 0.27778 0.24708 -0.075953 0.092084 0.34464 0.25284 -0.083241 -0.028076 -0.0025143 -0.052113 -0.089247 -0.16833 -0.21701 0.07541 -0.075677 0.0074818 -0.017865 -0.26286 0.090639 -0.24263 -0.39908 -0.29575 0.21118 -0.027031 -0.15267 -0.23026 0.011922 -0.066869 0.002248 -0.032791 -0.029063 0.096041 0.091891 -0.054472 0.43026 -0.11029 0.099507 -0.11779 0.12021 0.20565 0.02117 -0.032115 0.24554 0.075349 0.12594 0.067713 0.12544 0.11347 -0.10109 -0.19682 -0.29269 -0.083196 0.071931 0.24568 0.21901 +th -0.60675 -0.26853 0.096468 -0.048241 0.26699 0.15182 -0.25658 -0.17626 -0.16416 -0.18269 0.39767 0.066007 -0.17054 -0.33731 0.063323 -0.25809 -0.16717 0.054174 0.22244 0.40686 0.1744 0.011669 -0.15513 -0.38136 -0.081405 -0.024574 -0.28842 -0.21135 -0.16654 0.27858 -0.37471 0.1456 0.22931 0.35022 -0.0049302 -0.18581 -0.15644 -0.062995 -0.12768 -0.18818 0.17348 0.16634 -0.28225 -0.04404 0.1505 -0.41638 -0.12505 0.19712 -0.11901 -0.10796 0.18368 -0.24143 -0.11053 0.23607 -0.17163 0.083874 0.022472 0.30103 -0.11479 0.29774 0.06631 -0.11098 0.22351 0.021083 -0.0068601 0.041653 -0.2429 -0.3892 -0.4693 0.081678 -0.10183 0.28888 0.17179 -0.18717 -0.00081653 -0.018413 0.28121 0.4347 -0.098611 -0.027773 -0.24644 0.17357 -0.095818 0.034583 -0.22983 0.34187 -0.52803 -0.26306 -0.18711 0.17777 -0.26382 0.14235 0.26154 0.10764 0.33518 0.10576 -0.085594 0.15286 0.20943 0.019608 0.028166 -0.13091 0.23785 -0.027679 -0.03487 -0.11343 -0.07688 0.57732 0.12993 0.064244 0.07886 0.063248 -0.075539 0.066661 0.31472 0.12931 0.09467 0.12092 -0.048563 0.19786 0.13953 0.21392 0.16018 0.09481 -0.19021 0.16787 0.49052 0.17242 0.28908 0.1131 -0.17204 0.083921 -0.071823 -0.062542 0.19028 0.12568 0.062313 0.0325 -0.38644 0.097389 -0.079135 0.24346 -0.0033357 -0.016455 -0.11594 0.73385 -0.039272 0.068011 -0.34625 -0.057409 0.31008 -0.31365 -0.53361 0.39384 -0.31864 0.19514 0.22963 0.18612 -0.096096 -0.39553 0.14445 0.15417 0.15447 -0.24247 0.22757 -0.091387 0.22624 0.28213 0.47223 0.049463 -0.2732 0.40629 -0.24785 -0.088749 0.19076 0.43947 -0.31226 0.097205 0.15083 0.21795 -0.0087249 0.20098 -0.12404 0.11786 -0.11614 0.41239 -0.27663 -0.02218 -0.034705 -0.31327 0.40509 -0.084104 -0.1466 0.204 -0.25857 -0.13222 -0.013789 0.022034 -0.14575 -0.052714 -0.017593 -0.23816 -0.023857 -0.20569 0.37269 -0.17236 0.3702 0.010675 0.24429 0.36163 0.52705 -0.22285 0.029202 -0.13756 0.010739 -0.54299 -0.072329 -0.46061 -0.28558 0.012109 0.0085302 0.03059 -0.48537 0.054715 -0.31827 0.17051 0.33193 -0.19108 0.029543 0.1544 0.37158 0.023459 -0.21653 0.033273 -0.27755 0.077209 -0.069873 -0.17393 -0.040661 -0.28627 -0.14953 0.045912 0.41947 -0.13159 0.020909 -0.30792 -0.27904 0.17887 0.066537 -0.10931 -0.33191 -0.055951 0.0044215 -0.034251 -0.20743 0.18025 -0.16206 -0.27857 -0.025899 -0.0076564 -0.22972 -0.0775 0.0018984 0.28624 0.18766 0.13699 0.19437 -0.2004 0.051916 0.11504 -0.29875 -0.00037054 0.043479 -0.083922 -0.047696 -0.19229 0.12154 0.43983 0.29518 -0.24427 -0.38256 0.23031 -0.30828 -0.11142 0.36977 -0.15719 -0.32228 -0.083783 -0.063298 0.23107 0.14878 -0.38352 0.058238 -0.18181 -0.47019 0.33904 0.069788 0.078821 -0.27151 0.28172 +do -0.059967 -0.081823 -0.0056981 -0.14542 0.23516 0.067349 -0.0028626 0.08485 -0.4862 0.21191 -0.23553 -0.2202 -0.027258 -0.36629 0.074565 -0.27233 0.25396 0.49206 -0.11224 0.066095 -0.21424 -0.19757 0.0084842 -0.078745 0.00064474 -0.050737 -0.081943 -0.086791 -0.04997 -0.041197 0.24949 -0.02166 -0.28929 -0.04045 -0.17709 -0.28892 0.053601 0.00099314 0.10312 -0.3512 0.099789 0.046349 -0.029464 -0.24252 -0.17158 0.46145 0.22567 0.0065456 0.066029 -0.36638 0.0081423 -0.17546 0.13507 -0.083518 -0.17404 0.14661 -0.029917 0.23957 -0.30962 0.15455 -0.15061 -0.05068 0.32602 -0.29668 -0.067087 -0.38634 0.27957 0.019139 -0.14308 0.003658 -0.19603 -0.0083962 0.026586 -0.39534 -0.29117 0.32293 0.25185 0.18005 -0.15321 0.34453 0.16128 0.31987 -0.17828 0.071872 0.024957 -0.12243 -0.16399 0.13075 -0.15276 -0.08834 -0.15767 0.28876 0.23342 -0.4366 0.37324 0.37744 0.12084 0.077547 0.14779 -0.085973 0.023916 -0.33152 -0.12026 -0.16092 -0.080209 -0.012295 -0.15525 -0.32014 0.31115 0.11649 0.23685 0.23204 0.13351 -0.041479 -0.053513 0.075937 0.6738 -0.19178 -0.11756 -0.02215 0.13988 0.14792 0.032308 0.10286 -0.017684 -0.042036 -0.48374 0.070077 0.072057 0.63417 -0.0738 0.27205 -0.42079 -0.04715 0.028436 -0.040252 0.2531 0.14238 0.3893 0.055351 -0.066347 0.056898 0.060943 -0.19446 0.0018102 0.11559 -0.08629 -0.034242 -0.33377 -0.0235 0.25667 -0.13184 0.33271 0.21022 0.10855 0.15977 -0.056262 0.064112 0.1842 0.14715 0.040855 0.13859 -0.155 -0.37085 -0.051199 -0.22263 -0.38561 -0.45969 0.19492 0.51745 -0.096986 -0.070765 -0.46455 0.11917 0.071507 0.30963 -0.14782 0.17794 0.048722 -0.19075 0.035238 -0.29139 -0.10693 0.0084896 -0.0017804 0.1694 0.047842 -0.058594 0.24439 0.23714 -0.10227 -0.12158 -0.31455 0.13319 -0.011462 -0.14195 -0.13043 -0.12702 -0.60214 0.3814 0.074861 -0.28105 0.2825 0.012061 0.084645 -0.16669 -0.51595 0.10599 0.47781 -0.014559 0.39681 -0.046629 0.5323 -0.092162 -0.071815 -0.09175 0.30924 -0.43353 0.047393 0.096578 -0.27652 -0.065501 0.03346 0.023483 0.083389 0.11966 -0.21969 -0.29482 -0.013441 0.18045 0.21844 0.12373 -0.22268 -0.0118 0.16638 0.028737 0.10145 0.047869 -0.34403 0.092467 -0.031047 0.3481 0.33325 -0.0083112 0.14139 0.31026 0.50531 -0.077792 0.038025 -0.089494 0.13382 0.040453 -0.40636 0.20099 0.29619 0.027622 -0.0015309 -0.29558 0.50778 0.0058456 0.11392 0.32841 -0.37077 0.079654 -0.22285 -0.075119 -0.34271 0.66903 -0.21986 0.056074 0.066898 0.075743 -0.089369 0.21932 -0.072386 0.085074 0.16978 0.14485 -0.094814 -0.2547 0.11721 0.027759 -0.15985 0.061823 0.10966 -0.27901 0.2113 0.31464 0.051646 0.3197 -0.058232 0.041493 -0.18241 -0.098015 -0.057821 -0.053247 -0.23659 0.17532 0.31388 -0.29767 +discussion -0.26084 -0.43859 -0.097308 0.05468 -0.15924 0.058762 -0.16579 -0.24778 -0.087823 0.18509 -0.23787 -0.25805 -0.25208 -0.20909 0.44569 -0.14891 -0.18278 -0.052295 0.35736 0.065587 -0.2232 0.51596 0.011627 0.12479 -0.41068 -0.70696 -0.21797 0.19052 0.40837 0.042157 0.44506 0.5531 -0.15399 -0.12412 -0.10171 -0.65606 -0.55172 0.17546 -0.064015 -0.71936 -0.68804 -0.66215 -0.47949 -0.27738 0.072431 0.54152 0.32796 -0.14491 0.052282 -0.057596 0.0055305 -0.33909 0.010973 -0.21143 -0.73504 0.0085312 -0.071432 0.16853 0.18482 0.68602 -0.17503 0.42582 0.41421 -0.33126 0.050662 -0.2837 0.5466 0.37883 -0.59414 0.38208 0.0085385 0.13351 0.64641 -0.24276 0.28373 0.48611 0.21215 0.55252 -0.18047 0.1121 0.44308 0.47985 0.14249 -0.038064 0.32883 -0.30254 0.20936 0.034213 -0.3962 -0.0086424 -0.21452 0.063135 -0.018276 -0.74294 -0.15125 0.14107 -0.37968 0.22578 0.39788 0.087505 -0.4161 -0.34333 0.41225 -0.32472 0.32728 0.35028 -0.45105 0.39442 0.44659 -0.40474 -0.29326 0.092591 -0.43845 0.038681 0.16738 -0.39707 0.078914 0.57214 0.0010729 -0.1909 0.19087 0.25687 -0.10228 0.36607 0.25514 0.1554 -0.56618 0.45427 -0.24712 0.52421 -0.025724 -0.10638 -0.095697 0.065508 0.33916 0.20757 0.13203 -0.11756 0.29802 0.42715 -0.31292 -0.60287 -0.15821 0.17851 -0.43668 -0.30624 0.32857 0.70142 -0.3648 -0.011064 0.38754 0.34774 0.17563 -0.01693 -0.63089 -0.04063 -0.20083 -0.10394 0.50783 0.30302 -0.39965 0.02893 -0.10166 0.00090823 -0.2596 0.060532 -0.20883 -0.8698 0.2146 0.38666 -0.23512 -0.075248 -0.42229 0.04118 -0.1935 0.39545 -0.29781 -0.23658 0.30883 -0.19596 -0.043607 -0.044991 -0.14982 -0.26102 -0.43373 0.56915 0.51519 -0.2049 0.22194 0.57032 -0.037738 0.22773 -0.23408 -0.16963 0.30931 -0.48653 0.1703 0.069078 -0.36781 0.22654 0.23744 -0.021966 0.28629 0.30349 -0.078973 -0.38389 -0.20266 -0.258 -0.14079 0.078848 0.85712 -0.28459 0.30943 -0.12381 0.33248 -0.15023 0.58101 -0.75187 0.15823 0.43795 0.031069 0.040053 -0.18207 0.0061945 0.34633 0.062981 -0.2688 -0.38931 -0.56852 -0.002491 0.34907 -0.26371 0.090541 0.27999 0.078414 -0.20275 0.77341 -0.015091 0.10246 0.38322 -0.35226 0.057976 0.51931 -0.094074 -0.34616 0.44514 0.47448 0.10859 -0.33876 -0.082712 0.16501 -0.30634 -0.24531 -0.058237 0.21892 0.082378 -0.24401 -0.87644 0.45857 -0.07632 -0.043505 0.33546 -0.41284 -0.14825 0.093618 -0.36941 -0.077514 0.60082 -0.67596 0.12747 -0.12545 -0.030414 0.029517 0.012939 -0.28502 -0.16153 0.0033977 -0.058952 0.1519 0.15566 0.22359 0.43836 -0.12711 0.069377 -0.14711 -0.29421 0.25089 0.45225 0.83196 0.097383 0.38762 0.17161 0.14305 -0.46584 -0.1209 -0.3316 -0.59506 0.50913 0.34921 0.18931 +links -0.27749 -0.28933 0.33167 0.29965 -0.20354 0.093935 -0.13954 -0.50498 -0.28901 0.091049 0.013615 -0.49264 -0.012208 -0.04581 -0.013746 -0.54531 0.064218 0.26807 0.30349 0.075379 0.022224 0.10166 -0.14936 -0.14102 -0.7536 -0.31988 -0.13229 -0.12669 0.1555 0.42117 -0.069006 0.26913 -0.21187 -0.0053395 0.054433 0.19394 -0.019227 0.14352 0.044156 0.099382 0.019174 -0.14924 0.57902 0.21887 -0.017079 0.26866 -0.45234 -0.93843 0.29043 -0.078555 0.15963 -0.33392 -0.091577 0.18946 -0.24388 0.20148 0.30221 -0.15278 -0.32642 -0.25348 0.076736 0.32017 0.74159 -0.23109 0.13795 -0.18567 0.28312 0.095069 -0.31263 0.41474 0.18221 -0.37776 0.55402 -0.39255 -0.36033 0.058391 -0.076592 0.31554 -0.30084 -0.33737 -0.54834 0.30248 0.02769 -0.033921 0.038033 -0.40353 0.26493 -0.028178 -0.29401 -0.26078 0.23559 -0.28252 0.036618 0.063144 0.21201 -0.11569 0.10319 -0.00046561 0.14389 0.051738 0.20783 0.081079 0.025026 -0.17039 -0.0012885 0.30973 -0.52404 0.24485 0.20563 -0.12026 -0.16812 -0.10028 0.11187 0.14665 -0.18197 0.049589 0.67763 -0.22459 -0.22838 0.075526 0.73408 -0.16059 -0.34067 0.50763 0.25977 0.18045 -0.12478 -0.21471 -0.30782 0.055147 -0.15179 -0.23992 -0.084911 0.11675 -0.018983 0.38668 -0.1248 -0.25131 0.32422 0.23608 -0.30807 0.30196 0.27391 -0.2257 0.34383 0.061618 0.014743 0.18362 -0.5787 0.044126 0.37049 -0.071709 0.038466 -0.35322 0.33702 -0.18415 0.23649 -0.079108 -0.24644 -0.094335 0.42473 0.24503 -0.10231 -0.2965 0.2838 -0.34788 -0.61685 -0.30738 0.11989 -0.29692 0.16354 -0.19719 -0.23562 0.21924 -0.00051989 -0.32122 0.22849 -0.11614 0.00038817 -0.7646 -0.14039 0.019178 0.010886 0.41389 -0.41947 0.54745 -0.025778 -0.46135 0.057809 0.02033 0.30749 0.19056 0.31202 0.030437 -0.064174 -0.20355 0.016375 0.29364 -0.34437 -0.17062 0.45783 -0.22231 -0.17273 0.15463 0.24173 -0.33402 0.086328 0.12246 -0.11252 -0.49165 0.26323 -0.67558 0.15114 0.1522 0.34274 -0.0059516 0.40905 -0.20736 -0.11214 -0.29375 0.21611 -0.10309 0.3995 -0.69982 -0.17351 -0.058268 -0.13168 -0.35288 0.45879 -0.064465 -0.10805 -0.069126 -0.020047 -0.14233 -0.22427 0.071939 0.51276 0.22974 -0.099294 -0.14616 0.2822 -0.093446 0.17527 -0.14597 -0.47697 0.079552 0.63791 0.27966 -0.16389 -0.18201 0.62773 -0.31841 -0.98861 0.21872 0.097616 -0.56414 -0.15032 -0.2046 -0.0073912 -0.04622 0.21442 -0.041402 -0.36313 -0.045671 -0.17578 0.18216 0.32047 0.11363 -0.14618 0.022229 0.29825 -0.14684 0.41838 0.12826 0.086219 0.023431 -0.28017 -0.091905 -0.23622 -0.23884 -0.0433 0.29023 0.36765 -0.21901 0.27101 -0.0013437 0.34704 0.24939 -0.67596 0.009184 0.31138 -0.24334 -0.37687 0.10781 0.27825 0.060194 -0.16634 0.17116 0.2496 0.12647 +only -0.15906 0.14809 -0.087573 0.15128 -0.066258 -0.067022 -0.086443 -0.1616 0.11609 0.13939 0.047771 0.022413 0.10448 0.17269 0.031716 0.0053919 -0.089087 0.099216 0.070124 0.053753 -0.04261 0.026661 -0.26466 -0.18506 -0.094516 0.077165 -0.015846 0.12001 0.0074917 -0.0545 -0.12534 -0.077107 -0.13157 0.20992 0.024376 -0.23003 0.15691 0.0097185 0.053754 -0.040893 0.096524 -0.19632 0.025837 0.089478 0.05702 0.31574 0.16315 0.016696 0.060723 0.0024819 0.091089 -0.16559 0.14567 0.067502 -0.12275 -0.039173 -0.053219 0.15321 -0.22701 0.17364 -0.0019247 -0.071888 0.2315 -0.13551 0.032188 -0.17151 -0.32896 0.045003 0.22778 0.051344 -0.033665 -0.027701 0.15189 -0.14757 -0.11736 0.10167 0.25155 0.27647 -0.0035028 -0.0018311 -0.0035076 0.045586 -0.096837 0.021565 -0.028482 -0.046827 -0.17311 0.07101 0.0094512 -0.20737 -0.063359 0.083307 0.30308 -0.15507 0.018957 -0.13878 -0.16097 0.085181 -0.10667 0.051914 0.078567 -0.12925 0.25416 -0.090592 -0.023769 -0.19953 -0.067151 -0.1528 0.17349 0.054004 0.056664 -0.038726 0.015699 -0.096784 0.070768 -0.17623 0.19225 0.04551 0.045555 -0.023886 0.14975 0.10929 -0.071563 0.4805 0.11468 -0.007665 0.36264 0.15352 0.072933 0.057075 -0.15205 0.032859 0.022869 0.02742 -0.10133 0.066236 0.073805 -0.04183 0.016585 -0.091437 0.050731 0.18672 0.19019 -0.06957 0.085706 0.22939 -0.072447 -0.022841 0.010845 -0.12921 -0.043577 -0.076266 -0.048253 -0.11247 -0.13791 0.011871 0.14004 0.11014 0.20733 0.10345 -0.27352 0.025576 -0.0090305 0.16798 0.10511 0.19086 -0.02732 0.010641 0.11533 -0.025481 0.14493 -0.19454 -0.21079 0.02669 -0.051815 0.0050164 0.0073442 0.13537 0.071968 0.048253 0.061523 0.03662 -0.10555 -0.055751 -0.24306 0.065449 0.051918 -0.011406 0.092866 -0.15792 0.067191 -0.35585 0.15808 0.15181 -0.12981 -0.050787 -0.049853 0.089271 -0.14911 -0.095266 0.13753 -0.038161 0.0085413 0.028761 0.11458 -0.011769 -0.10758 0.25052 0.14654 0.045445 0.26169 -0.1726 0.13518 -0.064068 0.0366 -0.04534 -0.095521 -0.20135 -0.14809 -0.0096427 0.07307 0.01751 -0.050613 -0.12348 -0.040582 0.006155 -0.13754 -0.047531 0.060562 -0.059819 0.10945 0.16802 -0.14631 -0.040302 -0.104 0.14179 0.10253 -0.19554 -0.068862 -0.020133 -0.050928 0.051869 0.054462 -0.11187 0.10908 0.31932 0.085235 0.071356 0.0033062 -0.030618 -0.045608 -0.18537 -0.32734 -0.087081 0.11351 0.14116 -0.096899 -0.11627 -0.01955 -0.09668 -0.0031123 0.043306 -0.058312 -0.066643 -0.072086 -0.089377 -0.10663 0.092593 -0.1871 -0.15602 -0.29967 -0.030985 0.18006 0.046247 0.0088959 -0.17242 0.097567 0.05999 0.0385 -0.12629 0.056603 -0.048314 0.043715 -0.10048 0.12018 -0.037846 0.11677 0.35567 -0.18145 0.23512 0.18557 0.01865 0.099215 0.12251 0.04995 -0.23208 0.10142 0.093482 -0.032706 -0.065889 +some -0.10259 0.035129 -0.27205 0.058004 -0.0056773 0.10825 0.063587 -0.15558 0.1267 0.26728 0.02989 0.14701 -0.097785 -0.028888 0.12173 -0.1267 -0.062553 0.20528 -0.03202 -0.01069 0.028507 -0.092208 -0.17408 -0.094889 -0.14336 0.0090343 0.11859 0.11745 -0.21757 0.22911 0.13321 0.12549 -0.20468 0.31996 0.001532 -0.03917 0.18086 -0.074827 -0.0091022 -0.051964 0.007508 0.057379 0.041398 -0.060201 -0.013982 0.10431 0.18055 -0.23406 -0.24967 -0.23239 0.081355 0.061411 -0.075189 0.096334 -0.31583 -0.033809 -0.050904 0.0089098 -0.35847 0.27552 -0.093732 -0.2178 0.13224 -0.043404 0.18206 -0.018396 -0.2694 -0.10302 0.028364 -0.029874 -0.095828 0.049047 -0.062228 -0.13718 -0.23222 0.14618 0.2103 0.13877 0.0075502 -0.11579 0.055264 0.0915 -0.12487 0.030414 -0.020593 0.10754 0.059374 -0.044495 0.095436 0.10418 0.080895 -0.010017 0.38154 -0.25386 0.069355 0.026156 0.041555 0.016503 -0.11239 0.13511 -0.035684 0.086571 0.15105 -0.17939 -0.06164 -0.28054 -0.056921 0.12882 -0.026563 0.019554 -0.18434 0.025801 -0.1754 -0.014896 0.12717 -0.043347 0.21616 0.0080513 0.037775 0.097875 0.097109 -0.057762 0.069869 0.36304 0.060163 0.059501 0.084385 0.042682 -0.025057 0.44372 0.0069646 0.15606 -0.18339 0.049648 0.093692 0.015881 -0.11843 -0.025678 0.19763 -0.14278 0.17558 0.078549 -0.02908 0.021105 0.25916 0.17298 -0.14705 0.18447 -0.10639 -0.078388 -0.040532 -0.28532 0.16953 -0.1906 -0.072978 -0.17978 0.051613 -0.037614 0.215 0.066944 -0.17914 0.18687 -0.27441 -0.03191 0.072356 0.10846 -0.21846 -0.26791 0.20523 -0.04834 0.069503 0.14628 -0.35052 0.072428 -0.31021 0.15678 0.067768 0.26126 0.060228 -0.079528 0.099533 0.063709 0.054064 0.064872 0.058472 0.17235 0.16412 -0.1364 0.38018 -0.067375 -0.18138 -0.28091 0.035333 0.15544 -0.072803 -0.087458 0.034689 0.1415 -0.25274 -0.035459 0.025444 -0.065046 0.081268 -0.0042313 0.088707 -0.2762 0.053266 -0.0021693 0.032784 0.2264 0.17978 0.11026 0.024135 -0.11224 0.19694 -0.053345 0.055212 -0.22497 -0.17776 -0.069061 -0.027795 -0.27258 -0.030586 -0.010703 -0.10299 0.018793 -0.088313 -0.21044 0.072315 0.30453 0.063224 0.08811 -0.032367 -0.058272 -0.16633 0.21331 0.10058 -0.146 0.1074 0.065085 0.11677 -0.079865 0.09124 -0.18506 -0.18743 0.28953 0.21916 0.067925 -0.042576 -0.041126 0.17284 0.0027499 -0.080358 -0.18702 0.095815 -0.046811 0.11732 -0.15755 0.10424 0.05554 0.096629 0.19081 -0.11087 -0.022282 -0.2124 0.0070987 -0.26128 0.16266 -0.25841 -0.067286 -0.19836 -0.11061 0.20247 -0.019565 0.038612 0.058056 0.074382 0.14241 -0.013589 0.066706 0.16881 -0.15352 -0.17546 -0.069344 0.12135 -0.020611 -0.088055 0.097388 -0.15136 0.35622 0.12834 0.030983 0.022804 0.0090433 0.089243 0.0093499 -0.1469 0.17704 0.0031543 0.06439 +up 0.050746 -0.10465 -0.11645 0.35393 -0.12675 0.096301 -0.054381 -0.26301 -0.2099 0.28288 0.34059 -0.0087929 0.015238 0.048556 0.33515 -0.2547 0.14344 0.097152 0.061149 -0.029115 0.013637 -0.037526 0.099212 -0.28668 -0.089125 -0.012166 -0.29433 -0.47918 0.018074 0.12776 0.10105 0.31096 -0.17989 0.037449 0.038537 0.027665 -0.14308 -0.29851 -0.1668 -0.17571 0.26495 0.1444 -0.23602 0.42433 -0.0020282 -0.083376 0.16971 0.056822 -0.21485 -0.14441 -0.043001 -0.16818 0.024433 0.16601 -0.061748 0.39179 -0.056878 -0.091802 0.15553 0.25604 0.0085222 -0.28412 0.427 -0.15729 -0.28023 -0.16682 0.094079 0.22534 -0.12254 0.24432 -0.084133 0.097703 -0.0013774 -0.02722 -0.11715 -0.17758 0.30882 -0.049614 0.14009 0.14011 0.052514 -0.084242 -0.098793 0.09093 0.097124 0.096042 -0.08917 0.00014265 0.30589 -0.04607 -0.13584 -0.248 0.17472 -0.23987 0.15738 0.23197 0.058664 -0.23271 -0.0462 -0.24716 0.049899 0.029229 0.28816 -0.064107 -0.12036 -0.26565 0.045865 0.078788 0.11818 0.10476 0.099003 0.019882 0.20637 0.1584 -0.067908 -0.12516 -0.23174 -0.1027 -0.17582 -0.029133 0.038022 0.057464 -0.46738 0.37752 0.0039075 -0.18071 0.0013832 0.098791 0.144 0.042338 0.22923 -0.01215 -0.088185 0.3776 -0.032589 0.12344 0.032409 0.17313 -0.060322 0.31423 -0.0044634 0.14237 0.30797 0.23713 0.22841 0.3669 -0.11109 0.11761 -0.032454 0.14252 0.12229 -0.18333 0.046065 -0.35734 0.03968 0.048082 0.1686 -0.35911 0.22741 -0.23785 -0.056716 0.10403 -0.19803 0.20722 0.12045 -0.13193 -0.021354 -0.25307 -0.11498 -0.12141 0.12532 -0.3992 -0.19674 -0.19756 -0.04219 0.23571 0.060021 0.11503 -0.22009 -0.32069 0.23902 -0.087489 -0.24181 0.32901 -0.018359 0.019503 0.0030157 0.18843 0.071496 -0.34561 0.018668 -0.20879 0.097647 0.16018 0.065607 -0.10103 0.01134 -0.30712 -0.15941 -0.11366 0.15301 -0.15178 0.20537 0.0003623 0.018635 -0.13672 -0.20462 0.068105 0.085121 0.15109 0.25925 0.0084185 0.12888 -0.026041 0.17811 0.094287 -0.066252 -0.24214 -0.083132 0.12362 -0.32525 0.30129 0.04271 0.24263 -0.16674 -0.0049737 -0.054934 -0.11031 -0.070728 0.25159 0.35229 0.29824 0.044761 0.10997 -0.090429 -0.16943 0.24223 0.098267 -0.067278 -0.071913 0.31586 -0.075775 0.24381 0.12795 0.0036591 0.33459 -0.076598 -0.16319 -0.10426 0.033822 0.18074 -0.018719 -0.023605 -0.31635 0.15751 0.14504 0.053406 -0.13118 -0.12424 0.18307 -0.19952 -0.0011685 -0.15421 -0.093023 -0.053396 -0.22407 -0.00011687 0.15784 0.10014 0.075517 -0.11324 0.057721 0.1582 0.18678 -0.24766 -0.058054 0.1668 0.26698 -0.007678 -0.16806 0.34027 -0.21668 -0.14847 -0.17406 0.15964 0.092536 0.22502 0.12448 0.15117 0.062378 0.14372 -0.19707 0.045638 -0.0068417 -0.0055782 0.18371 -0.19345 -0.045529 0.072816 -0.0077457 +see 0.065606 -0.20778 0.078292 0.26746 -0.44002 0.12833 0.142 -0.14664 -0.21651 0.061481 0.037764 -0.098068 0.039605 0.15554 0.25207 -0.10135 -0.27408 0.14177 0.079111 -0.055953 0.11227 0.40378 -0.17173 -0.25968 -0.14666 -0.12127 -0.043952 -0.088812 -0.11801 -0.0055776 0.026664 0.17143 -0.064154 0.13713 -0.022575 0.13751 -0.30394 0.22493 -0.11938 -0.024765 -0.07806 0.065861 -0.18514 -0.10426 0.098893 0.0019134 0.24819 -0.24006 -0.1443 -0.26582 -0.01163 -0.14499 0.058747 -0.48813 -0.31219 0.12985 0.12634 0.0067255 -0.202 0.14519 -0.13505 -0.025903 0.17894 -0.078037 -0.19862 0.068398 0.12556 0.040752 -0.13791 -0.1718 0.090205 0.10914 -0.041686 0.080871 -0.23166 0.2464 0.20115 0.12834 0.16604 0.12042 0.34799 0.27769 -0.12724 0.060566 0.019956 0.12603 0.038511 -0.15342 0.035314 -0.27182 0.044523 0.31707 0.40946 0.098558 0.054922 -0.142 -0.10756 0.18376 0.1553 0.053896 0.065432 -0.23395 -0.067211 -0.25157 -0.078368 -0.094436 0.1068 0.1517 0.27513 -0.062291 0.038053 0.023074 -0.0012364 -0.087223 -0.19969 -0.15942 0.34232 0.090148 0.10787 0.29018 0.30764 0.084018 0.2238 0.24153 0.048191 0.014305 -0.062208 -0.20488 0.22731 0.02313 -0.064369 0.00033755 -0.34618 -0.0093523 0.13452 0.085074 0.10803 -0.075464 -0.076526 0.27606 0.046524 -0.03786 0.45028 -0.085808 0.15754 -0.039694 -0.27675 -0.073855 -0.020877 -0.011633 0.030616 -0.069789 0.3653 -0.076294 -0.085663 -0.14427 -0.16945 0.007729 0.32145 0.16343 0.01042 0.29496 -0.33592 -0.23572 -0.0013809 -0.19098 -0.095623 -0.37932 0.2241 0.10488 -0.62712 -0.078144 -0.25156 0.11853 -0.30085 -0.052537 0.32731 -0.074559 -0.00040936 -0.3031 0.11625 -0.1523 0.025847 0.067382 -0.183 0.24124 0.2631 -0.0043184 0.13733 -0.014973 -0.075383 -0.35768 0.0023652 0.0054615 -0.04175 -0.21974 0.24582 0.082989 -0.32646 -0.12335 0.16285 -0.079608 0.10057 0.14865 0.22523 0.10368 -0.34559 0.19931 0.024427 -0.019086 0.26853 -0.13887 -0.10147 -0.079289 0.24512 -0.09211 -0.14084 -0.077391 -0.053525 -0.0055776 -0.10184 -0.17063 -0.24186 -0.32622 0.02821 0.27233 -0.063724 -0.18258 -0.020903 -0.0071454 0.02461 0.37082 -0.11077 0.095047 0.15974 0.31148 -0.14492 -0.12066 0.063117 0.12564 -0.27152 0.0027756 0.43786 0.31141 0.065738 0.21583 0.1666 0.19119 0.037278 -0.074201 0.24833 -0.13415 -0.076522 0.21304 0.22779 0.15897 -0.091805 -0.21986 0.063914 0.007702 0.014062 0.092196 -0.067908 0.01917 -0.16616 -0.092109 -0.20818 0.13692 0.066552 0.088639 -0.11435 -0.16138 0.0743 -0.38724 0.11309 -0.39142 0.12729 0.17795 -0.13674 -0.45063 -0.10522 0.096817 -0.074096 0.0041708 0.16486 -0.088158 -0.19859 0.097139 -0.00179 0.12473 0.077368 0.058236 -0.027758 0.049618 0.10201 -0.0062674 -0.15436 0.054054 0.092565 0.011033 +united 0.046365 -0.31769 0.31222 0.42728 -0.052017 -0.20568 -0.13054 -0.35544 -0.045493 0.11983 -0.14213 0.31608 -0.17941 -0.18543 0.18359 -0.15808 0.072664 -0.0014783 0.16622 -0.14543 -0.2524 0.27216 -0.32267 -0.10664 -0.29708 0.18807 -0.098525 -0.18365 0.31272 0.28361 -0.18903 -0.088701 -0.35652 0.035704 -0.1088 -0.050323 0.023336 -0.26352 0.30818 -0.22825 0.058236 -0.41506 -0.026763 0.046349 0.19959 -0.39861 -0.17375 -0.30119 0.22293 -0.038184 0.068501 -0.097479 0.015807 -0.21986 -0.37589 0.17285 0.0040284 0.32552 -0.0011404 0.32761 -0.013105 0.015247 0.15712 -0.26045 -0.12494 0.28136 -0.26716 -0.46102 -0.41073 -0.32228 0.16545 -0.014996 0.35118 0.061423 -0.11643 0.43137 0.092377 0.029948 -0.085856 -0.41104 0.068817 0.29297 -0.21212 -0.1218 -0.26955 -0.24207 -0.18802 0.18362 0.18549 0.18589 -0.1702 -0.039048 0.11551 -0.19736 0.14122 -0.057884 0.20881 0.072587 -0.48411 0.26856 0.16303 -0.16069 0.27502 -0.059509 -0.18507 -0.12898 -0.30991 0.46534 0.23927 -0.13232 -0.13909 -0.13108 -0.26525 -0.12356 0.059133 0.23275 0.47667 0.12626 0.11883 -0.17368 -0.063973 0.053502 -0.2536 0.31042 0.080435 -0.30128 0.089277 0.36817 0.12852 -0.14209 -0.019825 0.25518 -0.17265 -0.30792 -0.46263 0.024073 -0.080779 -0.035585 -0.14509 0.046528 0.091075 0.23933 0.25347 0.33774 -0.25254 0.37824 0.4848 -0.054182 0.29476 0.086524 -0.093276 0.055876 -0.37799 -0.18548 -0.29252 -0.19583 -0.099003 -0.43942 0.087635 -0.012459 -0.29098 0.5147 -0.18545 0.13965 0.50519 -0.098732 0.25575 0.1304 0.55445 -0.021427 -0.029507 0.02117 -0.1621 0.014808 0.049758 0.036056 -0.062304 0.63642 -0.43644 -0.076776 -0.39182 -0.1376 -0.24394 -0.22731 0.06657 0.14438 0.38478 0.15374 -0.12172 -0.090816 0.045915 -0.10554 -0.073628 -0.19175 -0.29218 0.26795 0.50897 0.050782 -0.21657 -0.08597 -0.26223 0.022173 0.13127 0.24968 0.1859 -0.10647 -0.3341 -0.41956 0.48287 0.5315 0.41377 -0.17839 0.21919 -0.17591 0.27181 0.069603 0.10326 -0.33973 -0.055301 0.19001 0.1406 -0.18336 -0.2006 -0.17187 0.28915 0.14723 -0.1442 -0.15559 -0.24569 -0.2394 0.12558 0.027606 0.10914 -0.16858 -0.010481 0.025268 -0.40896 0.40354 0.25462 -0.15377 0.382 0.34362 -0.12514 -0.050515 0.14687 -0.034993 0.066918 0.18203 -0.18247 -0.0515 0.46348 -0.058206 0.017133 -0.089766 -0.43008 0.25566 -0.092503 0.3139 0.26187 0.29525 0.14112 0.11211 0.077465 -0.081054 0.027246 -0.35908 0.24731 0.23647 0.018267 -0.0976 0.18494 -0.073755 -0.080984 -0.13992 -0.1203 -0.024845 0.14001 0.11345 0.3576 0.018279 -0.34892 0.10736 -0.13512 0.17277 0.6192 0.078815 -0.12064 0.054381 -0.26726 0.15411 0.1107 -0.15565 0.20006 0.036532 -0.051931 -0.1327 0.06487 0.022226 -0.013277 -0.28403 +years 0.075839 0.042674 0.020181 0.050867 -0.010625 0.15256 -0.088586 -0.096088 -0.063122 0.65162 0.22232 0.19545 -0.10945 0.062671 0.032953 0.016797 -0.18758 -0.19251 0.034215 0.33518 -0.3219 -0.10498 0.023273 -0.38186 -0.17623 -0.17392 0.061267 -0.30791 0.063356 0.055992 -0.10579 0.16749 -0.13468 0.064846 0.24515 -0.16702 0.44616 -0.20769 -0.18541 0.045151 0.077928 -0.20744 0.06486 0.067822 0.4156 -0.27067 0.087404 0.15533 0.31861 0.047395 -0.053867 -0.43069 -0.10587 0.20187 -0.20761 -0.25294 -0.14523 0.42044 0.0049966 0.020707 -0.0042913 -0.16576 0.23027 -0.14021 -0.054268 -0.20378 0.096095 0.24053 -0.10842 0.30731 0.13651 -0.19265 0.084534 -0.093015 0.28022 -0.029079 0.39512 0.12934 0.16239 -0.022006 0.084606 0.27857 -0.16885 0.13995 -0.21116 -0.010157 -0.28055 -0.12798 -0.21519 -0.078518 -0.11085 -0.20858 0.47532 -0.28862 0.164 0.10424 0.11024 0.094779 -0.45725 -0.11355 0.14393 0.073126 0.20336 -0.13865 -0.27787 0.097976 -0.19101 0.39317 0.14608 -0.0097416 -0.0014398 -0.093993 -0.050344 0.19831 0.20188 -0.0065755 0.21589 0.0808 -0.11077 0.2792 0.27903 0.48508 -0.051715 0.23971 0.12164 -0.085404 -0.19077 0.27718 0.10276 0.29623 0.089316 0.19728 0.12027 0.085375 -0.34401 0.1915 -0.052665 0.10285 -0.12393 0.21668 0.0093345 -0.0556 -0.019853 0.16558 0.026664 0.27562 -0.16399 -0.33786 -0.17883 0.1218 0.073249 -0.024106 -0.064733 0.10199 -0.13762 -0.076979 -0.16217 -0.10043 0.21147 -0.003504 -0.0052409 0.16211 -0.18061 0.21571 0.39604 -0.16448 0.57379 -0.041948 0.15636 -0.18096 0.17468 -0.36554 -0.021891 0.21715 0.081093 -0.073907 -0.23223 0.32473 -0.26352 -0.19283 -0.25924 -0.093396 0.062183 -0.050842 -0.33023 -0.021627 -0.014505 -0.034812 0.4233 0.1613 -0.14166 0.18726 0.46601 0.11784 -0.035099 -0.045209 -0.082905 -0.060987 -0.031336 0.061925 -0.23274 -0.16959 -0.010284 0.031523 -0.0017703 0.27248 -0.025149 0.026061 0.17094 0.20044 0.30198 -0.14288 -0.090483 -0.035605 -0.084917 -0.068693 -0.16427 -0.2356 -0.070981 0.10475 0.30685 -0.03542 -0.15132 0.12895 0.38356 -0.00070255 0.20369 -0.31525 0.22899 0.13642 0.1792 0.234 -0.16045 -0.025321 0.0021374 -0.014873 0.36991 -0.15555 -0.29311 0.030527 0.031127 -0.18474 0.26607 -0.18104 -0.12037 -0.076602 0.15357 0.089392 -0.12486 0.27501 0.098842 -0.12278 -0.22455 0.041924 0.19719 -0.12148 0.054537 -0.091217 -0.25127 0.21292 4.5927e-05 0.38748 0.40215 -0.38429 -0.096875 -0.13293 0.30871 0.076813 0.1575 0.12342 0.27486 0.031692 -0.072002 0.005184 -0.20524 -0.12741 0.23838 -0.18301 0.33221 0.092258 0.44441 -0.035389 0.12411 0.053624 0.20656 0.20692 -0.10051 0.2851 0.05511 0.38232 -0.0056542 -0.029827 -0.087783 -0.11102 -0.14356 0.1626 0.08745 0.12232 0.099695 0.093542 +into 0.34768 -0.18301 -0.18374 0.17449 -0.11678 0.05353 0.2013 -0.063307 -0.042738 0.3143 -0.1538 -0.20722 -0.10654 -0.23009 0.083785 -0.1063 0.018538 0.17408 0.083412 0.21498 -0.00065944 0.037429 -0.32165 -0.026789 -0.05936 -0.054312 0.16073 -0.043368 0.1469 0.34231 -0.13652 0.35949 -0.14909 0.12 0.11815 -0.036557 0.01866 0.040918 0.28245 -0.31489 -0.032506 -0.11192 -0.015091 0.093158 -0.019388 0.34582 -0.13944 -0.01657 0.14834 -0.13085 -0.063624 -0.1593 -0.0067366 -0.27097 0.082271 0.2267 -0.3059 0.28004 0.035051 0.10519 -0.14024 -0.35287 0.09799 0.17613 0.03689 -0.1557 -0.39833 -0.053975 -0.057356 0.27995 -0.13391 0.10882 -0.11528 0.0057538 -0.21252 0.11017 0.28675 0.089503 -0.22875 0.021362 0.14077 0.10379 -0.22423 0.059292 -0.22971 0.18392 0.16652 -0.038267 -0.21817 0.1093 -0.58092 -0.19338 0.30391 -0.14916 0.21285 0.14896 -0.021155 0.33504 0.0041895 -0.012333 -0.12319 -0.35666 0.16627 0.34811 0.05825 -0.17838 -0.22366 0.28413 -0.23417 0.014204 0.031265 -0.26941 0.23086 0.022466 -0.22682 -0.43217 -0.11432 -0.22773 0.10484 0.2114 0.26848 0.12776 -0.59997 0.42818 0.17349 -0.22267 0.041764 -0.097523 0.40219 0.33736 0.1079 -0.16823 -0.0706 0.28274 0.016632 0.060905 -0.0064263 -0.01452 -0.27613 0.042014 0.14971 -0.19843 -0.089107 0.047591 0.027608 0.33357 -0.30224 0.15721 0.050677 0.2872 0.092645 -0.16366 -0.082375 0.31504 -0.14338 -0.047443 -0.087692 -0.27621 0.13379 0.013171 -0.10672 -0.0025352 0.0028819 0.24832 0.063671 -0.38832 0.13841 -0.21445 0.18896 -0.045585 -0.12747 -0.14709 0.27171 -0.39122 -0.52803 0.52118 0.13217 0.19373 -0.12833 -0.077883 0.35282 -0.064329 -0.18832 0.066166 0.069386 0.14396 0.15335 0.26762 0.29207 -0.026261 0.12546 -0.3424 0.015212 0.36355 0.15621 -0.29739 0.033645 0.040381 -0.081248 -0.26464 0.11797 -0.20161 -0.14048 -0.084735 -0.21277 -0.10718 0.035666 0.047764 -0.016448 0.078006 0.079905 0.21249 -0.22072 0.1626 0.19665 0.15009 0.24736 -0.37362 -0.044406 0.11318 -0.3778 -0.38509 0.12491 0.16944 -0.19092 -0.050139 -0.042326 -0.10134 -0.084649 0.23181 0.11532 -0.085061 0.12366 0.18886 -0.1119 0.27884 -0.011567 0.03009 0.074174 0.011531 0.004713 -0.07456 0.13581 0.0047321 0.19415 0.08412 -0.20343 0.16068 -0.16568 -0.18684 0.11888 0.14485 -0.1393 0.16933 -0.23593 -0.068552 0.16504 -0.032924 -0.17583 0.14028 0.048741 -0.024942 -0.13366 0.025903 -0.27872 -0.062801 -0.035876 -0.18877 0.11958 0.045169 -0.27372 -0.082779 0.017666 -0.020521 -0.41158 0.0041723 0.019554 0.37294 0.064214 -0.31056 0.50026 0.1451 0.080847 0.25609 0.17866 -0.1145 0.24704 0.093726 -0.2143 -0.10244 -0.025642 -0.024296 0.071712 0.10922 -0.10548 0.11922 -0.011184 -0.018843 0.17916 0.0042012 +/ -0.014258 -0.30462 0.28373 0.1851 0.046303 0.44111 -0.11513 -0.092893 -0.30788 -0.2812 -0.012369 0.0010053 0.24368 -0.05857 -0.16366 -0.14147 -0.06117 0.53059 0.11204 0.11767 0.46164 -0.025331 -0.10238 0.16827 -0.31067 0.034411 -0.24189 -0.4842 0.027328 0.5291 -0.38596 0.24237 -0.058165 0.015226 -0.33173 0.073705 -0.20051 -0.20967 0.35094 -0.21589 -0.26331 0.20564 0.28022 0.20334 0.40152 0.47095 -0.10259 -0.2074 0.098816 -0.048928 0.15128 -0.17568 -0.010976 -0.26898 0.25062 0.0054663 -0.2595 0.20167 0.30158 0.18431 0.19219 -0.16947 0.21348 -0.048 0.099897 0.12883 0.29279 0.37141 -0.24043 -0.5847 -0.14316 -0.099099 -0.040051 -0.25161 0.064307 0.23795 0.24965 0.14896 0.042686 0.52851 0.16964 0.14712 -0.29284 0.15657 0.42737 -0.21109 0.023191 0.23033 -0.04745 0.27154 -0.01657 -0.082681 -0.37165 0.13493 0.084044 0.28484 0.022851 -0.098493 0.10653 -0.15732 0.20354 0.091567 0.034782 0.236 0.064735 0.016267 -0.085658 -0.021286 -0.12741 -0.05269 0.2856 -0.008002 -0.43656 -0.16063 -0.38213 -0.25526 0.26923 0.21076 -0.29088 0.36863 0.56086 0.32946 0.39728 0.31775 -0.16081 -0.32495 0.091922 -0.086332 -0.49444 0.10045 -0.066926 0.067345 0.13961 0.46939 0.22744 0.0050036 -0.048599 -0.45075 0.54124 0.33883 -0.52585 0.15031 0.17678 -0.12429 -0.08918 0.47669 0.21934 0.24983 -0.089043 0.033151 0.0911 -0.11045 -0.28486 -0.069924 0.1155 0.036532 0.21339 0.099686 0.18386 0.3329 -0.2436 0.52067 0.028179 0.12453 0.1044 0.18913 -0.09839 0.25459 -0.3051 0.068261 -0.042702 0.0010945 -0.46086 -0.12266 -0.0095622 0.16247 -0.40412 -0.45167 -0.43043 -0.65586 0.20948 -0.32213 0.06307 -0.21243 -0.38168 0.4449 0.0076538 -0.36694 0.12226 -0.091153 0.12169 0.012705 0.072424 0.0065783 -0.24181 -0.016246 0.019913 0.4425 -0.44006 -0.027852 -0.09028 -0.16866 -0.15291 -0.12223 0.03705 0.086734 -0.12287 0.12118 0.38338 0.1032 0.33368 -0.13516 0.21665 -0.10152 -0.032325 -0.061582 -0.11824 -0.25082 -0.39177 -0.19368 -0.05892 0.37131 0.18077 0.013755 -0.28276 -0.24894 -0.14531 0.017124 0.3341 0.36421 -0.055136 0.34678 -0.22398 -0.48497 -0.36863 -0.17603 0.12263 0.22867 0.077009 -0.16923 -0.12496 0.16409 -0.13856 0.17236 -0.050772 -0.1741 -0.21244 0.14494 -0.099898 -0.034955 -0.37403 0.0097706 -0.063309 -0.26638 0.12265 -0.049024 -0.10421 -0.177 -0.19008 0.40117 0.2179 0.13711 0.17258 0.13303 -0.23296 0.1817 0.015836 -0.29464 0.12452 0.036893 0.020751 0.15712 0.48448 -0.3163 -0.016973 -0.074844 0.2711 0.63583 0.13755 -0.069565 -0.10698 -0.063679 0.21927 -0.21831 0.64384 -0.12821 0.26235 -0.032293 0.18311 0.098621 -0.27872 -0.44858 0.54312 0.48648 0.086906 0.28035 -0.25262 -0.092285 0.13599 -0.10298 +school 0.22869 -0.028009 -0.085097 0.24309 -0.26317 -0.11202 0.039456 -0.28124 0.30743 0.17091 0.22821 -0.074532 -0.14216 0.0074727 0.22099 -0.28197 0.3143 -0.084497 -0.098618 0.49764 0.10058 0.41745 0.12981 -0.23762 0.06865 0.23092 -0.19101 0.31252 0.033131 0.21395 -0.48624 0.31525 -0.3059 0.0049942 -0.049818 -0.078912 0.38837 0.10109 -0.081014 -0.29326 0.45915 -0.023954 -0.30263 0.46563 -0.025378 0.12146 -0.075863 0.13385 -0.12211 -0.40954 0.37466 -0.31341 0.22262 0.10399 -0.10581 -0.28576 0.016809 0.13574 -0.16435 0.35275 -0.16555 0.17956 0.080846 0.27856 -0.17459 -0.3546 0.16616 -0.28542 0.045847 0.082316 -0.072671 0.34245 0.22845 -0.033578 0.13721 -0.47394 0.33248 0.13369 -0.16712 -0.15695 -0.24327 0.30842 -0.23262 -0.05941 -0.10467 0.068933 -0.49366 0.49679 -0.066409 -0.081599 0.057622 -0.13286 0.50645 -0.39212 0.18089 0.32451 0.35698 0.26969 -0.067222 -0.18543 0.20487 0.013419 0.04359 -0.1235 -0.26041 -0.094033 -0.18862 0.22934 -0.11248 0.034285 -0.48659 -0.032477 -0.12568 -0.083626 -0.12629 -0.33144 0.30312 -0.16933 -0.1418 0.22216 0.41686 0.24273 -0.16214 0.10395 0.53591 0.027088 -0.21948 -0.21237 0.38657 0.17376 -0.21233 -0.11442 0.13554 -0.12886 -0.46518 0.38517 0.095843 -0.37739 0.070177 0.10336 -0.046608 0.0048551 -0.012481 0.21233 0.52061 0.36687 0.47144 -0.055217 -0.29614 -0.073691 0.12355 -0.13563 -0.11267 -0.2026 -0.18016 0.02181 -0.11769 -0.32574 0.31155 0.16532 0.35864 0.35299 -0.056351 0.017639 0.5587 0.056945 0.082128 0.064561 -0.0043055 0.253 -0.26588 -0.11758 -0.15983 0.25661 -0.017241 0.19402 -0.41857 -0.11006 0.20889 -0.14091 -0.011836 -0.0057944 -0.3357 0.15189 -0.16835 -0.03914 0.059314 0.0042839 0.20252 -0.10732 0.40503 0.059054 -0.1481 0.092425 -0.070491 -0.0001241 -0.0016259 0.72782 -0.22663 -0.43043 0.02191 -0.15601 -0.37599 0.16893 -0.18846 -0.058359 -0.0014713 -0.35734 0.15577 0.10934 0.69167 -0.32724 0.16009 -0.40792 -0.11439 -0.030013 -0.12524 -0.027639 0.063727 -0.14089 0.013969 0.41208 -0.36629 0.02648 0.20469 -0.2759 -0.070599 0.006753 0.14241 0.2103 0.3727 -0.0062525 -0.0084329 -0.27378 -0.089864 -0.02836 0.0015354 0.45145 -0.18245 0.20555 0.054421 -0.025571 -0.032553 -0.018942 0.097465 -0.18188 0.091925 -0.055566 -0.1843 -0.05103 -0.06108 0.069601 -0.045432 -0.049843 0.006233 0.045287 -0.00021775 -0.14776 0.076178 -0.17957 0.0078284 -0.060164 0.4239 -0.12532 0.10443 0.075369 0.050524 0.12161 0.11281 -0.057907 0.05202 -0.11776 -0.31597 -0.42454 -0.096316 -0.25219 0.26053 0.31455 -0.20336 0.0079374 -0.19716 0.078221 -0.028117 0.19894 -0.34614 0.024755 -0.21811 -0.14425 -0.05119 -0.33597 0.32747 -0.03847 0.40644 -0.19799 -0.023426 0.10254 -0.03794 -0.14674 -0.13088 -0.18213 +so -0.13876 0.19795 -0.17866 0.025196 -0.057717 0.17428 0.050262 -0.17875 -0.044467 0.31205 0.0054485 -0.11575 0.043132 -0.12426 0.11097 -0.33065 0.05547 0.055605 0.0032198 0.14209 0.045309 0.11784 -0.088498 -0.11306 -0.209 -0.033766 0.02461 0.054905 -0.036109 0.20889 -0.18131 0.15424 -0.23355 0.086936 -0.18024 0.04247 -0.14205 0.065776 -0.10339 -0.12291 -0.1374 -0.066735 -0.16207 -0.1181 -0.11262 0.24891 0.2308 0.1507 -0.012344 -0.10494 -0.011185 -0.36278 0.20072 -0.10977 -0.26811 0.15207 -0.21305 0.11993 -0.31291 0.04385 -0.18034 -0.21894 0.078447 0.048618 0.041356 -0.19324 0.08263 -0.038096 -0.017106 -0.12048 -0.051861 0.21462 -0.090842 -0.31433 -0.20281 0.21938 0.24084 0.1209 -0.048795 0.052489 0.092435 -0.035181 -0.056189 0.058179 -0.12874 0.076431 -0.0016604 0.08846 0.019571 -0.11157 0.026898 0.19388 0.11744 -0.10727 0.11326 0.12562 0.12955 0.071034 -0.15378 0.033196 -0.026469 -0.22647 0.22492 -0.20341 -0.14455 -0.23348 -0.12604 0.054282 0.071263 0.017155 -0.015162 0.05998 -0.072731 0.14712 0.19606 -0.25031 0.051569 0.17115 -0.054961 0.19255 0.15445 0.12191 0.0047315 0.48098 -0.094198 0.037771 0.082164 0.0020702 -0.0077461 0.25117 -0.15283 0.07453 -0.12795 -0.024251 0.038364 0.0035498 0.11854 0.052221 0.17121 0.1575 -0.031279 -0.06475 0.2821 -0.11162 -0.014155 -0.14122 -0.053681 -0.048946 -0.037284 -0.11207 0.10877 0.0020626 -0.0095018 0.074902 -0.17482 -0.061947 -0.070881 0.10493 0.12086 0.011539 -0.12448 0.22621 -0.1975 0.15172 0.0090491 -0.10927 -0.12677 -0.089284 0.12008 -0.037246 -0.23478 -0.25616 -0.27381 0.081569 -0.20625 0.13588 -0.10092 0.042022 0.016035 -0.15939 0.09973 -0.20985 0.20619 0.01581 -0.1356 0.18691 -0.063003 -0.2148 0.25072 -0.1012 -0.073977 -0.26977 -0.030127 0.062034 -0.11133 -0.19449 -0.020197 -0.0093353 -0.27978 -0.17041 0.27489 0.12797 0.078962 0.10482 -0.11091 -0.070037 -0.15435 0.072273 0.17585 0.065539 0.27849 -0.0013867 0.071116 -0.047344 0.21544 -0.069844 -0.11321 -0.22116 -0.023346 0.13996 -0.17092 -0.12829 0.0051118 -0.053587 -0.083811 0.084021 -0.21998 0.009804 0.053682 0.13441 0.066206 0.23787 0.00083491 0.028816 0.0059404 0.076342 0.1054 -0.04614 0.070182 0.0022372 0.13904 0.070292 0.29026 0.029514 -0.098725 0.14229 0.2298 0.11194 0.074637 -0.18559 0.069305 -0.11542 -0.069762 0.048392 0.055977 0.085971 0.25094 -0.31674 0.019868 -0.017369 0.00043032 0.005874 -0.13219 -0.14709 -0.17125 -0.2358 -0.040862 0.27907 -0.10765 -0.047719 -0.30975 0.051394 0.14146 -0.049926 -0.071984 -0.13116 0.019164 0.0060272 -0.0029015 -0.24943 0.29035 0.024601 -0.16474 -0.020862 0.03052 -0.059954 0.044344 0.13539 0.029642 0.2097 0.024176 0.088455 0.031137 -0.092552 0.10547 -0.18755 -0.15719 0.11399 0.20889 0.013215 +world -0.32423 -0.098845 -0.0073467 0.16121 -0.25998 -0.0060076 0.0046041 -0.13021 0.25626 0.34078 0.28565 0.26202 0.1617 -0.34681 0.063853 -0.0057415 -0.21039 -0.15594 0.14924 0.12123 -0.31505 0.18454 0.067557 -0.064524 0.18522 -0.11179 0.0064246 -0.18092 0.046077 -0.094983 -0.2517 0.18452 -0.066575 0.36489 0.11338 -0.09776 0.30747 -0.023661 0.39178 -0.03507 -0.10813 -0.027539 0.43034 0.10358 -0.10806 -0.22422 -0.08929 0.12713 -0.28126 -0.0069467 -0.11128 -0.18842 0.29751 -0.11981 -0.078897 0.25913 0.3523 0.39657 0.024184 0.071092 0.17349 -0.32468 0.061097 -0.28061 -0.14277 0.0022942 -0.24633 -0.11668 -0.23279 0.12904 0.083629 -0.10669 0.25295 0.22212 0.33765 0.031227 0.15566 0.3809 -0.076791 0.13093 0.012789 0.38097 0.22645 0.10582 -0.13103 0.18499 -0.15408 0.39885 -0.18911 0.058628 0.026293 0.0096371 0.47597 -0.10347 0.227 -0.20193 -0.26306 0.20054 -0.46428 0.19976 0.19478 -0.096227 -0.090747 -0.072301 -0.201 0.050161 -0.53361 0.094732 0.1288 0.20945 -0.17726 -0.35653 0.14161 -0.080905 -0.016251 -0.0958 0.37587 0.52891 0.11805 0.065107 0.2019 0.060531 -0.14157 -0.0025388 -0.18896 0.0045249 0.21342 0.28812 0.17907 0.078547 0.13383 -0.020373 -0.064534 -0.33421 -0.3559 0.064769 -0.077711 -0.015207 0.3099 0.63486 0.066338 0.020168 0.29862 0.16501 -0.37229 0.27157 -0.021179 0.064131 0.22547 -0.44628 0.32969 -0.012753 -0.23219 -0.16027 0.20027 0.1033 0.025454 -0.097411 0.080349 0.08146 -0.32789 0.0040305 0.20591 -0.07277 -0.035319 -0.11317 -0.044998 0.20649 0.32991 -0.16076 0.38777 -0.039422 -0.060492 0.051966 0.007784 0.066656 0.10081 0.31054 -0.30312 -0.32962 -0.022858 -0.13672 0.20578 -0.024593 0.010505 0.046384 0.0116 0.078211 0.21753 -0.29905 0.2172 -0.1159 0.20545 0.16613 -0.16653 0.015691 -0.026983 0.21195 -0.20077 -0.046234 0.27736 0.023131 0.14588 -0.12859 0.17107 -0.50074 -0.29859 -0.10064 0.56272 0.30691 0.54501 -0.39113 -0.12554 0.17813 0.45996 0.018619 0.35831 -0.27745 -0.0046902 0.32791 -0.18364 0.31163 -0.32295 0.034618 -0.15645 -0.34456 -0.080383 -0.043575 0.042087 0.16559 0.024058 0.34987 0.27348 0.012231 -0.12685 0.0072742 -0.022134 0.083285 -0.017813 0.088638 0.2044 0.076185 0.27567 -0.13946 -0.14153 0.23889 -0.22143 -0.080292 0.002125 0.45858 -0.32851 0.47206 0.19678 0.077539 0.26018 0.1628 -0.2611 -0.2211 0.23609 0.31686 0.087248 0.54821 -0.1004 -0.26447 -0.35366 0.18926 -0.025612 0.0047776 0.18239 0.019577 -0.14313 0.026834 -0.024435 0.10197 -0.25018 0.14014 0.16461 0.23887 -0.10994 0.15154 -0.1888 0.05091 -0.2567 0.15235 0.23851 0.22879 -0.13311 0.12802 -0.13385 0.18834 -0.041262 -0.10447 0.099186 -0.011132 0.14804 -0.13535 -0.50431 0.14867 -0.16452 0.13953 +university 0.041453 -0.17245 -0.11003 0.13728 -0.21607 -0.18947 0.020979 -0.079464 0.25171 0.34705 0.070803 -0.067096 -0.0052297 -0.15262 0.15632 -0.27248 0.23585 0.13002 -0.24159 0.35073 -0.067959 0.26695 -0.43149 -0.42169 0.22754 -0.29609 -0.045533 0.19175 0.091689 0.23847 0.014621 0.34661 -0.34137 0.1878 0.23843 -0.27737 0.28383 -0.23551 -0.14485 -0.28813 0.14774 0.023565 -0.20509 -0.064663 0.23605 -0.11878 -0.15493 0.060583 -0.1392 -0.23136 0.30865 -0.057538 0.25537 -0.06635 0.0045521 -0.47641 0.098173 0.051067 -0.054406 0.77796 0.11129 0.06741 -0.15458 0.17729 -0.17746 0.30722 0.23242 -0.27439 -0.19194 0.1115 0.024878 -0.046219 0.56096 -0.21114 0.049921 -0.16304 0.42484 0.26172 0.25511 0.26335 0.071185 0.20423 -0.17984 -0.60543 0.031364 0.11908 -0.28081 0.09248 -0.13224 -0.43512 -0.45786 -0.40474 0.32971 -0.64401 -0.3299 -0.10025 0.22597 0.1418 -0.17161 -0.18121 0.16278 0.026016 0.39037 -0.01311 -0.19485 0.1817 -0.097151 0.11809 0.16565 -0.12453 -0.090578 -0.27001 0.19558 -0.019368 0.063503 -0.4107 -0.023209 0.27863 0.093141 0.23934 -0.091827 0.25287 -0.44133 0.2316 0.24816 -0.038631 -0.35123 -0.091982 0.29043 0.18975 0.041419 0.32777 0.26483 -0.087267 -0.29148 -0.053556 0.18182 -0.11983 0.20309 0.16317 -0.2746 0.059835 -0.12366 0.4187 0.093625 -0.091871 0.46739 -0.20346 -0.051065 0.019171 0.25479 -0.024782 0.05954 0.10331 -0.13681 -0.44302 0.0097103 -0.23327 -0.1475 0.35785 0.28133 0.69286 -0.48166 -0.19055 0.80364 0.30656 -0.039871 0.053325 0.46743 -0.050938 -0.12106 -0.26011 -0.27163 0.27737 -0.071462 0.23087 0.29939 -0.16232 -0.021594 0.18577 0.019553 0.41418 -0.41296 -0.092661 -0.30531 0.11269 0.26856 0.15516 -0.12681 -0.14423 0.14873 -0.10238 0.10529 -0.21727 -0.37486 0.16841 -0.29481 0.35415 -0.34787 -0.24904 0.39922 0.21179 -0.35735 -0.091495 0.12603 -0.2643 -0.078413 -0.16515 0.3866 0.4746 0.40802 -0.3168 0.31129 -0.2661 -0.2783 0.20688 -0.15508 -0.12621 0.2155 -0.37675 -0.24299 0.10661 -0.19684 0.32476 -0.51551 -0.40934 -0.25866 -0.44414 0.056277 -0.050156 0.38642 -0.046327 -0.11681 -0.3872 0.021696 -0.040026 0.39229 0.19011 -0.11519 0.055413 -0.39051 0.17913 -0.25056 -0.052618 0.14345 -0.21811 0.17174 -0.029255 0.12625 -0.1116 -0.10846 0.15673 -0.13096 -0.086822 -0.0091798 -0.018278 -0.045537 -0.28719 0.20896 0.48402 -0.31491 0.42236 0.28919 0.018968 -0.18751 0.20907 0.1161 -0.22245 -0.085037 0.48937 0.26306 -0.24191 0.10488 -0.31061 -0.23278 -0.40265 0.13978 0.35509 -0.021251 0.10698 -0.23899 -0.030711 -0.14845 -0.13388 -0.42873 -0.049942 -0.14451 0.15826 0.14272 0.1248 -0.34915 -0.024686 0.18432 -0.025538 -0.054518 -0.10777 -0.04628 -0.044913 -0.37704 0.025977 diff --git a/test/common/torchtext_test_case.py b/test/common/torchtext_test_case.py index 7bcfc881e7..21ccc4d785 100644 --- a/test/common/torchtext_test_case.py +++ b/test/common/torchtext_test_case.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import torch from torch.testing._internal.common_utils import TestCase import json import logging diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index aa0fff33a5..1c120da16c 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -156,6 +156,108 @@ def test_multi30k(self): "multi30k_task*.tar.gz") conditional_remove(datafile) + def test_udpos_sequence_tagging(self): + from torchtext.experimental.datasets import UDPOS + + # smoke test to ensure imdb works properly + train_dataset, valid_dataset, test_dataset = UDPOS() + self.assertEqual(len(train_dataset), 12543) + self.assertEqual(len(valid_dataset), 2002) + self.assertEqual(len(test_dataset), 2077) + self.assertEqual(train_dataset[0][0][:10], + torch.tensor([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585]).long()) + self.assertEqual(train_dataset[0][1][:10], + torch.tensor([8, 3, 8, 3, 9, 2, 4, 8, 8, 8]).long()) + self.assertEqual(train_dataset[0][2][:10], + torch.tensor([5, 34, 5, 27, 7, 11, 14, 5, 5, 5]).long()) + self.assertEqual(train_dataset[-1][0][:10], + torch.tensor([9, 32, 169, 436, 59, 192, 30, 6, 117, 17]).long()) + self.assertEqual(train_dataset[-1][1][:10], + torch.tensor([5, 10, 11, 4, 11, 11, 3, 12, 11, 4]).long()) + self.assertEqual(train_dataset[-1][2][:10], + torch.tensor([6, 20, 8, 10, 8, 8, 24, 13, 8, 15]).long()) + + self.assertEqual(valid_dataset[0][0][:10], + torch.tensor([746, 3, 10633, 656, 25, 1334, 45]).long()) + self.assertEqual(valid_dataset[0][1][:10], + torch.tensor([6, 7, 8, 4, 7, 2, 3]).long()) + self.assertEqual(valid_dataset[0][2][:10], + torch.tensor([3, 4, 5, 16, 4, 2, 27]).long()) + self.assertEqual(valid_dataset[-1][0][:10], + torch.tensor([354, 4, 31, 17, 141, 421, 148, 6, 7, 78]).long()) + self.assertEqual(valid_dataset[-1][1][:10], + torch.tensor([11, 3, 5, 4, 9, 2, 2, 12, 7, 11]).long()) + self.assertEqual(valid_dataset[-1][2][:10], + torch.tensor([8, 12, 6, 15, 7, 2, 2, 13, 4, 8]).long()) + + self.assertEqual(test_dataset[0][0][:10], + torch.tensor([210, 54, 3115, 0, 12229, 0, 33]).long()) + self.assertEqual(test_dataset[0][1][:10], + torch.tensor([5, 15, 8, 4, 6, 8, 3]).long()) + self.assertEqual(test_dataset[0][2][:10], + torch.tensor([30, 3, 5, 14, 3, 5, 9]).long()) + self.assertEqual(test_dataset[-1][0][:10], + torch.tensor([116, 0, 6, 11, 412, 10, 0, 4, 0, 6]).long()) + self.assertEqual(test_dataset[-1][1][:10], + torch.tensor([5, 4, 12, 10, 9, 15, 4, 3, 4, 12]).long()) + self.assertEqual(test_dataset[-1][2][:10], + torch.tensor([6, 16, 13, 16, 7, 3, 19, 12, 19, 13]).long()) + + # Assert vocabs + self.assertEqual(len(train_dataset.get_vocabs()), 3) + self.assertEqual(len(train_dataset.get_vocabs()[0]), 19674) + self.assertEqual(len(train_dataset.get_vocabs()[1]), 19) + self.assertEqual(len(train_dataset.get_vocabs()[2]), 52) + + # Assert token ids + word_vocab = train_dataset.get_vocabs()[0] + tokens_ids = [word_vocab[token] for token in 'Two of them were being run'.split()] + self.assertEqual(tokens_ids, [1206, 8, 69, 60, 157, 452]) + + def test_conll_sequence_tagging(self): + from torchtext.experimental.datasets import CoNLL2000Chunking + + # smoke test to ensure imdb works properly + train_dataset, test_dataset = CoNLL2000Chunking() + self.assertEqual(len(train_dataset), 8936) + self.assertEqual(len(test_dataset), 2012) + self.assertEqual(train_dataset[0][0][:10], + torch.tensor([11556, 9, 3, 1775, 17, 1164, 177, 6, 212, 317]).long()) + self.assertEqual(train_dataset[0][1][:10], + torch.tensor([2, 3, 5, 2, 17, 12, 16, 15, 13, 5]).long()) + self.assertEqual(train_dataset[0][2][:10], + torch.tensor([3, 6, 3, 2, 5, 7, 7, 7, 7, 3]).long()) + self.assertEqual(train_dataset[-1][0][:10], + torch.tensor([85, 17, 59, 6473, 288, 115, 72, 5, 2294, 2502]).long()) + self.assertEqual(train_dataset[-1][1][:10], + torch.tensor([18, 17, 12, 19, 10, 6, 3, 3, 4, 4]).long()) + self.assertEqual(train_dataset[-1][2][:10], + torch.tensor([3, 5, 7, 7, 3, 2, 6, 6, 3, 2]).long()) + + self.assertEqual(test_dataset[0][0][:10], + torch.tensor([0, 294, 73, 10, 13582, 194, 18, 24, 2414, 7]).long()) + self.assertEqual(test_dataset[0][1][:10], + torch.tensor([4, 4, 4, 23, 4, 2, 11, 18, 11, 5]).long()) + self.assertEqual(test_dataset[0][2][:10], + torch.tensor([3, 2, 2, 3, 2, 2, 5, 3, 5, 3]).long()) + self.assertEqual(test_dataset[-1][0][:10], + torch.tensor([51, 456, 560, 2, 11, 465, 2, 1413, 36, 60]).long()) + self.assertEqual(test_dataset[-1][1][:10], + torch.tensor([3, 4, 4, 8, 3, 2, 8, 4, 17, 16]).long()) + self.assertEqual(test_dataset[-1][2][:10], + torch.tensor([6, 3, 2, 4, 6, 3, 4, 3, 5, 7]).long()) + + # Assert vocabs + self.assertEqual(len(train_dataset.get_vocabs()), 3) + self.assertEqual(len(train_dataset.get_vocabs()[0]), 19124) + self.assertEqual(len(train_dataset.get_vocabs()[1]), 46) + self.assertEqual(len(train_dataset.get_vocabs()[2]), 24) + + # Assert token ids + word_vocab = train_dataset.get_vocabs()[0] + tokens_ids = [word_vocab[token] for token in 'Two of them were being run'.split()] + self.assertEqual(tokens_ids, [970, 5, 135, 43, 214, 690]) + def test_squad1(self): from torchtext.experimental.datasets import SQuAD1 from torchtext.vocab import Vocab diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 6ddbbde8b3..738ef98788 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -1,20 +1,29 @@ # -*- coding: utf-8 -*- -import torch import os +import shutil +import tempfile + +import torch from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vectors import ( + FastText, + GloVe, Vectors, vectors_from_file_object ) class TestVectors(TorchtextTestCase): + def tearDown(self): + super().tearDown() + torch._C._jit_clear_class_registry() + torch.jit._recursive.concrete_type_store = torch.jit._recursive.ConcreteTypeStore() def test_empty_vectors(self): tokens = [] - vectors = [] + vectors = torch.empty(0, dtype=torch.float) unk_tensor = torch.tensor([0], dtype=torch.float) vectors_obj = Vectors(tokens, vectors, unk_tensor) @@ -25,7 +34,7 @@ def test_empty_unk(self): expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a'] - vectors = [tensorA] + vectors = tensorA.unsqueeze(0) vectors_obj = Vectors(tokens, vectors) self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) @@ -36,7 +45,7 @@ def test_vectors_basic(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] - vectors = [tensorA, tensorB] + vectors = torch.stack((tensorA, tensorB), 0) vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) self.assertEqual(vectors_obj['a'], tensorA) @@ -49,7 +58,7 @@ def test_vectors_jit(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] - vectors = [tensorA, tensorB] + vectors = torch.stack((tensorA, tensorB), 0) vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) jit_vectors_obj = torch.jit.script(vectors_obj) @@ -62,10 +71,11 @@ def test_vectors_add_item(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a'] - vectors = [tensorA] + vectors = tensorA.unsqueeze(0) + print(vectors) vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) - tensorB = torch.tensor([0., 1]) + tensorB = torch.tensor([0, 1], dtype=torch.float) vectors_obj['b'] = tensorB self.assertEqual(vectors_obj['a'], tensorA) @@ -77,7 +87,7 @@ def test_vectors_load_and_save(self): expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a'] - vectors = [tensorA] + vectors = tensorA.unsqueeze(0) vectors_obj = Vectors(tokens, vectors) vector_path = os.path.join(self.test_dir, 'vectors.pt') @@ -89,7 +99,7 @@ def test_vectors_load_and_save(self): def test_errors(self): tokens = [] - vectors = [] + vectors = torch.empty(0, dtype=torch.float) with self.assertRaises(ValueError): # Test proper error raised when passing in empty tokens and vectors and @@ -99,7 +109,7 @@ def test_errors(self): tensorA = torch.tensor([1, 0, 0], dtype=torch.float) tensorB = torch.tensor([0, 1, 0], dtype=torch.float) tokens = ['a', 'b', 'c'] - vectors = [tensorA, tensorB] + vectors = torch.stack((tensorA, tensorB,), 0) with self.assertRaises(RuntimeError): # Test proper error raised when tokens and vectors have different sizes @@ -107,7 +117,7 @@ def test_errors(self): tensorC = torch.tensor([0, 0, 1], dtype=torch.float) tokens = ['a', 'a', 'c'] - vectors = [tensorA, tensorB, tensorC] + vectors = torch.stack((tensorA, tensorB, tensorC), 0) with self.assertRaises(RuntimeError): # Test proper error raised when tokens have duplicates @@ -116,12 +126,28 @@ def test_errors(self): Vectors(tokens, vectors) tensorC = torch.tensor([0, 0, 1], dtype=torch.int8) - vectors = [tensorA, tensorB, tensorC] + tokens = ['a'] + vectors = tensorC.unsqueeze(0) with self.assertRaises(TypeError): - # Test proper error raised when vectors are not of type torch.float + # Test proper error raised when vector is not of type torch.float Vectors(tokens, vectors) + with tempfile.TemporaryDirectory() as dir_name: + # Test proper error raised when incorrect filename or dim passed into GloVe + asset_name = 'glove.6B.zip' + asset_path = get_asset_path(asset_name) + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + + with self.assertRaises(ValueError): + # incorrect name + GloVe(name='UNK', dim=50, root=dir_name, validate_file=False) + + with self.assertRaises(ValueError): + # incorrect dim + GloVe(name='6B', dim=500, root=dir_name, validate_file=False) + def test_vectors_from_file(self): asset_name = 'vectors_test.csv' asset_path = get_asset_path(asset_name) @@ -135,3 +161,83 @@ def test_vectors_from_file(self): self.assertEqual(vectors_obj['a'], expected_tensorA) self.assertEqual(vectors_obj['b'], expected_tensorB) self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) + + def test_fast_text(self): + # copy the asset file into the expected download location + # note that this is just a file with the first 100 entries of the FastText english dataset + asset_name = 'wiki.en.vec' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + vectors_obj = FastText(root=dir_name, validate_file=False) + jit_vectors_obj = torch.jit.script(vectors_obj) + + # The first 3 entries in each vector. + expected_fasttext_simple_en = { + 'the': [-0.065334, -0.093031, -0.017571], + 'world': [-0.32423, -0.098845, -0.0073467], + } + + for word in expected_fasttext_simple_en.keys(): + self.assertEqual(vectors_obj[word][:3], expected_fasttext_simple_en[word]) + self.assertEqual(jit_vectors_obj[word][:3], expected_fasttext_simple_en[word]) + + def test_glove(self): + # copy the asset file into the expected download location + # note that this is just a zip file with the first 100 entries of the GloVe 840B dataset + asset_name = 'glove.840B.300d.zip' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + vectors_obj = GloVe(root=dir_name, validate_file=False) + jit_vectors_obj = torch.jit.script(vectors_obj) + + # The first 3 entries in each vector. + expected_glove = { + 'the': [0.27204, -0.06203, -0.1884], + 'people': [-0.19686, 0.11579, -0.41091], + } + + for word in expected_glove.keys(): + self.assertEqual(vectors_obj[word][:3], expected_glove[word]) + self.assertEqual(jit_vectors_obj[word][:3], expected_glove[word]) + + def test_glove_different_dims(self): + # copy the asset file into the expected download location + # note that this is just a zip file with 1 line txt files used to test that the + # correct files are being loaded + asset_name = 'glove.6B.zip' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + + glove_50d = GloVe(name='6B', dim=50, root=dir_name, validate_file=False) + glove_100d = GloVe(name='6B', dim=100, root=dir_name, validate_file=False) + glove_200d = GloVe(name='6B', dim=200, root=dir_name, validate_file=False) + glove_300d = GloVe(name='6B', dim=300, root=dir_name, validate_file=False) + vectors_objects = [glove_50d, glove_100d, glove_200d, glove_300d] + + # The first 3 entries in each vector. + expected_glove_50d = { + 'the': [0.418, 0.24968, -0.41242], + } + expected_glove_100d = { + 'the': [-0.038194, -0.24487, 0.72812], + } + expected_glove_200d = { + 'the': [-0.071549, 0.093459, 0.023738], + } + expected_glove_300d = { + 'the': [0.04656, 0.21318, -0.0074364], + } + expected_gloves = [expected_glove_50d, expected_glove_100d, expected_glove_200d, expected_glove_300d] + + for vectors_obj, expected_glove in zip(vectors_objects, expected_gloves): + for word in expected_glove.keys(): + self.assertEqual(vectors_obj[word][:3], expected_glove[word]) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py new file mode 100644 index 0000000000..f3e4a4aeb5 --- /dev/null +++ b/test/experimental/test_vocab.py @@ -0,0 +1,209 @@ +# -*- coding: utf-8 -*- +from collections import OrderedDict +import os +import torch + +from test.common.torchtext_test_case import TorchtextTestCase +from torchtext.experimental.vocab import ( + Vocab +) + + +class TestVocab(TorchtextTestCase): + def tearDown(self): + super().tearDown() + torch._C._jit_clear_class_registry() + torch.jit._recursive.concrete_type_store = torch.jit._recursive.ConcreteTypeStore() + + def test_has_unk(self): + c = OrderedDict({}) + v = Vocab(c) + + # check if unk is mapped to the first index + self.assertEqual(v['not_in_it'], 0) + self.assertEqual(v[''], 0) + + def test_new_unk(self): + c = OrderedDict({}) + v = Vocab(c, specials=('',), unk_token="") + + # check if new_unk is mapped to the first index + self.assertEqual(v[''], 0) + self.assertEqual(v['not_in_it'], 0) + + def test_vocab_get_item(self): + token_to_freq = {'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c) + + self.assertEqual(v[''], 0) + self.assertEqual(v[''], 1) + self.assertEqual(v['a'], 2) + self.assertEqual(v['b'], 3) + + def test_vocab_set_item(self): + c = OrderedDict({'a': 2}) + + # add item to end + v = Vocab(c) + v.insert_token('b', 3) + + self.assertEqual(v[''], 0) + self.assertEqual(v[''], 1) + self.assertEqual(v['a'], 2) + self.assertEqual(v['b'], 3) + + # add item to middle + v = Vocab(c, specials_first=False) + v.insert_token('b', 0) + + self.assertEqual(v['b'], 0) + self.assertEqual(v['a'], 1) + self.assertEqual(v[''], 2) + self.assertEqual(v[''], 3) + + def test_vocab_append_token(self): + c = OrderedDict({'a': 2}) + v = Vocab(c) + v.append_token('b') + + self.assertEqual(len(v), 4) + self.assertEqual(v['b'], 3) + + def test_vocab_len(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c) + + self.assertEqual(len(v), 5) + + def test_vocab_basic(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c, min_freq=3, specials=['', '', '']) + + expected_itos = ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + def test_vocab_jit(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c, min_freq=3, specials=['', '', '']) + jit_v = torch.jit.script(v) + + expected_itos = ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(jit_v.get_itos(), expected_itos) + self.assertEqual(dict(jit_v.get_stoi()), expected_stoi) + + def test_vocab_specials_order(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + + # add specials into vocabulary at first + v = Vocab(c, specials=['', '']) + expected_itos = ['', '', 'a', 'b', 'c'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + # add specials into vocabulary at last + v = Vocab(c, specials=['', ''], specials_first=False) + expected_itos = ['a', 'b', 'c', '', ''] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + def test_vocab_lookup_token(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c, specials_first=False) + + self.assertEqual(v.lookup_token(0), 'a') + + def test_vocab_lookup_tokens(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c, specials_first=False) + + indices = [1, 0, 2] + expected_tokens = ['b', 'a', 'c'] + + self.assertEqual(v.lookup_tokens(indices), expected_tokens) + + def test_vocab_lookup_indices(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c, specials_first=False) + + tokens = ['b', 'a', 'c'] + expected_indices = [1, 0, 2] + + self.assertEqual(v.lookup_indices(tokens), expected_indices) + + def test_errors(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + + with self.assertRaises(ValueError): + # Test proper error raised when setting unk token to None + Vocab(c, specials=['', ''], unk_token=None) + + with self.assertRaises(ValueError): + # Test proper error raised when specials token doesn't contain unk_token + Vocab(c, specials=['', '']) + + with self.assertRaises(ValueError): + # Test proper error raised when ordered_dict contains a special token + updated_token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2, '': 1} + updated_sorted_by_freq_tuples = sorted(updated_token_to_freq.items(), key=lambda x: x[1], reverse=True) + updated_c = OrderedDict(updated_sorted_by_freq_tuples) + Vocab(updated_c, specials=['', '', '']) + + with self.assertRaises(RuntimeError): + # Test proper error raised when setting a token out of bounds + v = Vocab(c, min_freq=3) + v.insert_token('new_token', 100) + + with self.assertRaises(RuntimeError): + # Test proper error raised when looking up a token out of bounds + v = Vocab(c) + v.lookup_token(100) + + def test_vocab_load_and_save(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = Vocab(c, min_freq=3) + + expected_itos = ['', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + vocab_path = os.path.join(self.test_dir, 'vocab.pt') + torch.save(v, vocab_path) + loaded_v = torch.load(vocab_path) + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) diff --git a/torchtext/csrc/vectors.cpp b/torchtext/csrc/vectors.cpp index bec20e2264..16c5055a7a 100644 --- a/torchtext/csrc/vectors.cpp +++ b/torchtext/csrc/vectors.cpp @@ -2,76 +2,84 @@ #include #include +using c10::Dict; + namespace torchtext { namespace { struct Vectors : torch::CustomClassHolder { -private: - std::unordered_map stovectors_; - public: - // tokens_, vectors_, and unk_tensor_ holds the serialized params passed in - // during initialization. We need this because we need to be able to serialize - // the model so that we can save the scripted object. Pickle will get the - // serialized model from these members, thus they needs to be public. + Dict stovec_; std::vector tokens_; - std::vector vectors_; + torch::Tensor vectors_; torch::Tensor unk_tensor_; explicit Vectors(const std::vector &tokens, - const std::vector &vectors, + const torch::Tensor &vectors, const torch::Tensor &unk_tensor) - : tokens_(tokens), vectors_(vectors), unk_tensor_(unk_tensor) { + : tokens_(std::move(tokens)), vectors_(std::move(vectors)), + unk_tensor_(std::move(unk_tensor)) { // guarding against size mismatch of vectors and tokens - if (tokens.size() != vectors.size()) { + if (static_cast(tokens.size()) != vectors.size(0)) { throw std::runtime_error( "Mismatching sizes for tokens and vectors. Size of tokens: " + std::to_string(tokens.size()) + - ", size of vectors: " + std::to_string(vectors.size()) + "."); + ", size of vectors: " + std::to_string(vectors.size(0)) + "."); } - stovectors_.reserve(tokens.size()); + stovec_.reserve(tokens.size()); for (std::size_t i = 0; i < tokens.size(); i++) { // tokens should not have any duplicates - if (stovectors_.find(tokens[i]) != stovectors_.end()) { + if (stovec_.find(tokens[i]) != stovec_.end()) { throw std::runtime_error("Duplicate token found in tokens list: " + tokens[i]); } - stovectors_[tokens[i]] = vectors_[i]; + stovec_.insert(std::move(tokens[i]), vectors_.select(0, i)); } } - torch::Tensor GetItem(const std::string &token) const { - if (stovectors_.find(token) != stovectors_.end()) { - return stovectors_.at(token); + torch::Tensor __getitem__(const std::string &token) const { + const auto &item = stovec_.find(token); + if (item != stovec_.end()) { + return item->value(); } return unk_tensor_; } - void AddItem(const std::string &token, const torch::Tensor &vector) { - stovectors_[token] = vector; + void __setitem__(const std::string &token, const torch::Tensor &vector) { + const auto &item = stovec_.find(token); + if (item != stovec_.end()) { + item->value() = vector; + } else { + tokens_.push_back(token); + vectors_ = torch::cat({vectors_, torch::unsqueeze(vector, /*dim=*/0)}, + /*dim=*/0); + stovec_.insert_or_assign(token, vectors_.select(0, stovec_.size())); + } } + + int64_t __len__() { return stovec_.size(); } }; // Registers our custom class with torch. static auto vectors = torch::class_("torchtext", "Vectors") - .def(torch::init, std::vector, + .def(torch::init, torch::Tensor, torch::Tensor>()) - .def("GetItem", &Vectors::GetItem) - .def("AddItem", &Vectors::AddItem) + .def("__getitem__", &Vectors::__getitem__) + .def("__setitem__", &Vectors::__setitem__) + .def("__len__", &Vectors::__len__) .def_pickle( - // __getstate__ + // __setstate__ [](const c10::intrusive_ptr &self) - -> std::tuple, - std::vector, torch::Tensor> { - std::tuple, std::vector, - torch::Tensor> + -> std::tuple, torch::Tensor, + torch::Tensor> { + std::tuple, torch::Tensor, torch::Tensor> states(self->tokens_, self->vectors_, self->unk_tensor_); return states; }, - // __setstate__ - [](std::tuple, std::vector, + // __getstate__ + [](std::tuple, torch::Tensor, torch::Tensor> states) -> c10::intrusive_ptr { return c10::make_intrusive( diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp new file mode 100644 index 0000000000..9fbe3231dd --- /dev/null +++ b/torchtext/csrc/vocab.cpp @@ -0,0 +1,142 @@ +#include +#include +#include + +namespace torchtext { +namespace { + +using c10::Dict; + +struct Vocab : torch::CustomClassHolder { +private: + int64_t unk_index_; + Dict stoi_; + +public: + // stoi_, and unordered_map holds the serialized params passed in + // during initialization. We need this because we need to be able to serialize + // the model so that we can save the scripted object. Pickle will get the + // serialized model from these members, thus they needs to be public. + std::vector itos_; + std::string unk_token_; + + explicit Vocab(const std::vector &tokens, + const std::string &unk_token) + : itos_(std::move(tokens)), unk_token_(std::move(unk_token)) { + stoi_.reserve(tokens.size()); + for (std::size_t i = 0; i < tokens.size(); i++) { + // tokens should not have any duplicates + if (stoi_.find(tokens[i]) != stoi_.end()) { + throw std::runtime_error("Duplicate token found in tokens list: " + + tokens[i]); + } + stoi_.insert(std::move(tokens[i]), i); + } + unk_index_ = stoi_.find(unk_token)->value(); + } + + int64_t __len__() const { return stoi_.size(); } + + int64_t __getitem__(const std::string &token) const { + const auto &item = stoi_.find(token); + if (item != stoi_.end()) { + return item->value(); + } + return unk_index_; + } + + void append_token(const std::string &token) { + if (stoi_.find(token) == stoi_.end()) { + stoi_.insert(std::move(token), stoi_.size()); + } + } + + void insert_token(const std::string &token, const int64_t &index) { + if (index < 0 || index > static_cast(stoi_.size())) { + throw std::runtime_error( + "Specified index " + std::to_string(index) + + " is out of bounds of the size of stoi dictionary: " + + std::to_string(stoi_.size()) + "."); + } + + const auto &item = stoi_.find(token); + // if item already in stoi we throw an error + if (item != stoi_.end()) { + throw std::runtime_error("Token " + token + + " already exists in the Vocab with index: " + + std::to_string(item->value()) + "."); + } + + // need to offset all tokens greater than or equal index by 1 + for (auto &entry : stoi_) { + if (entry.value() >= index) { + stoi_.insert_or_assign(entry.key(), std::move(entry.value() + 1)); + } + } + stoi_.insert(std::move(token), std::move(index)); + + // need to update unk_index in case token equals unk_token or token inserted + // before unk_token + unk_index_ = stoi_.find(unk_token_)->value(); + } + + std::string lookup_token(const int64_t &index) { + if (index < 0 || index > static_cast(itos_.size())) { + throw std::runtime_error( + "Specified index " + std::to_string(index) + + " is out of bounds of the size of itos dictionary: " + + std::to_string(itos_.size()) + "."); + } + + return itos_[index]; + } + + std::vector lookup_tokens(const std::vector &indices) { + std::vector tokens(indices.size()); + for (int64_t i = 0; i < static_cast(indices.size()); i++) { + tokens[i] = lookup_token(indices[i]); + } + return tokens; + } + + std::vector lookup_indices(const std::vector &tokens) { + std::vector indices(tokens.size()); + for (int64_t i = 0; i < static_cast(tokens.size()); i++) { + indices[i] = __getitem__(tokens[i]); + } + return indices; + } + + Dict get_stoi() const { return stoi_; } + std::vector get_itos() const { return itos_; } +}; + +// Registers our custom class with torch. +static auto vocab = + torch::class_("torchtext", "Vocab") + .def(torch::init, std::string>()) + .def("__getitem__", &Vocab::__getitem__) + .def("__len__", &Vocab::__len__) + .def("insert_token", &Vocab::insert_token) + .def("append_token", &Vocab::append_token) + .def("lookup_token", &Vocab::lookup_token) + .def("lookup_tokens", &Vocab::lookup_tokens) + .def("lookup_indices", &Vocab::lookup_indices) + .def("get_stoi", &Vocab::get_stoi) + .def("get_itos", &Vocab::get_itos) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) + -> std::tuple, std::string> { + std::tuple, std::string> states( + self->itos_, self->unk_token_); + return states; + }, + // __setstate__ + [](std::tuple, std::string> states) + -> c10::intrusive_ptr { + return c10::make_intrusive(std::move(std::get<0>(states)), + std::move(std::get<1>(states))); + }); +} // namespace +} // namespace torchtext diff --git a/torchtext/experimental/asset/get_checksum.sh b/torchtext/experimental/asset/get_checksum.sh new file mode 100755 index 0000000000..04c5701b6d --- /dev/null +++ b/torchtext/experimental/asset/get_checksum.sh @@ -0,0 +1,5 @@ +#!/bin/bash +FILENAME="$1" +URL="$2" + +wget -O - -o /dev/null "$URL" | sha256sum | head -c 64 > "$FILENAME" diff --git a/torchtext/experimental/asset/get_checksums_fast_text.py b/torchtext/experimental/asset/get_checksums_fast_text.py new file mode 100644 index 0000000000..e58a2a3e29 --- /dev/null +++ b/torchtext/experimental/asset/get_checksums_fast_text.py @@ -0,0 +1,58 @@ +import glob +import json +import os +import subprocess +from tqdm import tqdm + + +def output_checksums_to_files(dir=".checksums"): + if not os.path.exists(dir): + os.makedirs(dir) + + processes = [] + with open("languages_fast_text.txt", 'r') as f: + num_languages = 0 + for line in f: + num_languages += 1 + language = line.strip() + filepath = '{}/{}.txt'.format(dir, language) + url = 'https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.{}.vec'.format(language) + processes.append(subprocess.Popen(['./get_checksum.sh', filepath, url])) + + print('Computing checksums') + with tqdm(unit_scale=0, unit='files', total=num_languages) as t: + for p in processes: + p.wait() + t.update(1) + + +def process_checksums_to_json_file(dir=".checksums"): + if not os.path.exists(dir): + os.makedirs(dir) + os.chdir(dir) + + checksums = {} + for file_name in glob.glob("*.txt"): + file_base_name = os.path.splitext(file_name)[0] + url = 'https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.{}.vec'.format(file_base_name) + + with open(file_name, 'r') as f: + sha256hash = f.readline() + checksums[url] = sha256hash + checksums_json = json.dumps(checksums) + + with open("checksums_fast_text.json", 'w') as f: + f.write(checksums_json) + + +def main(): + dir = ".checksums" + json_file_path = os.path.join(os.getcwd(), dir, "checksums_fast_text.json") + output_checksums_to_files(dir=dir) + process_checksums_to_json_file(dir=dir) + + print("Path to FastTest checksum file: {}".format(json_file_path)) + + +if __name__ == "__main__": + main() diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index 7929f5f733..b86e9f4756 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -2,6 +2,7 @@ from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB +from .sequence_tagging import UDPOS, CoNLL2000Chunking from .translation import Multi30k, IWSLT, WMT14 from .question_answer import SQuAD1, SQuAD2 @@ -19,6 +20,8 @@ 'YahooAnswers', 'AmazonReviewPolarity', 'AmazonReviewFull', + 'UDPOS', + 'CoNLL2000Chunking', 'Multi30k', 'IWSLT', 'WMT14', diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py index ad100429b0..ec3371de26 100644 --- a/torchtext/experimental/datasets/raw/__init__.py +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -1,6 +1,7 @@ from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB +from .sequence_tagging import UDPOS, CoNLL2000Chunking from .translation import Multi30k, IWSLT, WMT14 from .language_modeling import WikiText2, WikiText103, PennTreebank, WMTNewsCrawl from .question_answer import SQuAD1, SQuAD2 @@ -14,6 +15,8 @@ 'YahooAnswers', 'AmazonReviewPolarity', 'AmazonReviewFull', + 'UDPOS', + 'CoNLL2000Chunking', 'Multi30k', 'IWSLT', 'WMT14', diff --git a/torchtext/experimental/datasets/raw/sequence_tagging.py b/torchtext/experimental/datasets/raw/sequence_tagging.py new file mode 100644 index 0000000000..b4576e7f81 --- /dev/null +++ b/torchtext/experimental/datasets/raw/sequence_tagging.py @@ -0,0 +1,136 @@ +import torch + +from torchtext.utils import download_from_url, extract_archive + +URLS = { + "UDPOS": + 'https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip', + "CoNLL2000Chunking": [ + 'https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz', + 'https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz' + ] +} + + +def _create_data_from_iob(data_path, separator="\t"): + with open(data_path, encoding="utf-8") as input_file: + columns = [] + for line in input_file: + line = line.strip() + if line == "": + if columns: + yield columns + columns = [] + else: + for i, column in enumerate(line.split(separator)): + if len(columns) < i + 1: + columns.append([]) + columns[i].append(column) + if len(columns) > 0: + yield columns + + +def _construct_filepath(paths, file_suffix): + if file_suffix: + path = None + for p in paths: + path = p if p.endswith(file_suffix) else path + return path + return None + + +def _setup_datasets(dataset_name, separator, root=".data"): + + extracted_files = [] + if isinstance(URLS[dataset_name], list): + for f in URLS[dataset_name]: + dataset_tar = download_from_url(f, root=root) + extracted_files.extend(extract_archive(dataset_tar)) + elif isinstance(URLS[dataset_name], str): + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files.extend(extract_archive(dataset_tar)) + else: + raise ValueError( + "URLS for {} has to be in a form or list or string".format( + dataset_name)) + + data_filenames = { + "train": _construct_filepath(extracted_files, "train.txt"), + "valid": _construct_filepath(extracted_files, "dev.txt"), + "test": _construct_filepath(extracted_files, "test.txt") + } + + datasets = [] + for key in data_filenames.keys(): + if data_filenames[key] is not None: + datasets.append( + RawSequenceTaggingIterableDataset( + _create_data_from_iob(data_filenames[key], separator))) + else: + datasets.append(None) + + return datasets + + +class RawSequenceTaggingIterableDataset(torch.utils.data.IterableDataset): + """Defines an abstraction for raw text sequence tagging iterable datasets. + """ + def __init__(self, iterator): + super(RawSequenceTaggingIterableDataset).__init__() + + self._iterator = iterator + self.has_setup = False + self.start = 0 + self.num_lines = None + + def setup_iter(self, start=0, num_lines=None): + self.start = start + self.num_lines = num_lines + self.has_setup = True + + def __iter__(self): + if not self.has_setup: + self.setup_iter() + + for i, item in enumerate(self._iterator): + if i >= self.start: + yield item + if (self.num_lines is not None) and (i == (self.start + + self.num_lines)): + break + + def get_iterator(self): + return self._iterator + + +def UDPOS(*args, **kwargs): + """ Universal Dependencies English Web Treebank + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets.raw import UDPOS + >>> train_dataset, valid_dataset, test_dataset = UDPOS() + """ + return _setup_datasets(*(("UDPOS", "\t") + args), **kwargs) + + +def CoNLL2000Chunking(*args, **kwargs): + """ CoNLL 2000 Chunking Dataset + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + + Examples: + >>> from torchtext.datasets.raw import CoNLL2000Chunking + >>> train_dataset, valid_dataset, test_dataset = CoNLL2000Chunking() + """ + return _setup_datasets(*(("CoNLL2000Chunking", " ") + args), **kwargs) + + +DATASETS = {"UDPOS": UDPOS, "CoNLL2000Chunking": CoNLL2000Chunking} diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py new file mode 100644 index 0000000000..8a6a97a55e --- /dev/null +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -0,0 +1,169 @@ +import torch + +from torchtext.experimental.datasets import raw +from torchtext.vocab import build_vocab_from_iterator +from torchtext.experimental.functional import ( + vocab_func, + totensor, + sequential_transforms, +) + + +def _build_vocab(data): + total_columns = len(data[0]) + data_list = [[] for _ in range(total_columns)] + vocabs = [] + + for line in data: + for idx, col in enumerate(line): + data_list[idx].append(col) + + for it in data_list: + vocabs.append(build_vocab_from_iterator(it)) + + return vocabs + + +def _setup_datasets(dataset_name, + root=".data", + vocabs=None, + data_select=("train", "valid", "test")): + if isinstance(data_select, str): + data_select = [data_select] + if not set(data_select).issubset(set(("train", "valid", "test"))): + raise TypeError("Given data selection {} is not supported!".format(data_select)) + + train, val, test = DATASETS[dataset_name](root=root) + raw_data = { + "train": [line for line in train] if train else None, + "valid": [line for line in val] if val else None, + "test": [line for line in test] if test else None + } + + if vocabs is None: + if "train" not in data_select: + raise TypeError("Must pass a vocab if train is not selected.") + vocabs = _build_vocab(raw_data["train"]) + else: + if not isinstance(vocabs, list): + raise TypeError("vocabs must be an instance of list") + + # Find data that's not None + notnone_data = None + for key in raw_data.keys(): + if raw_data[key] is not None: + notnone_data = raw_data[key] + break + if len(vocabs) != len(notnone_data[0]): + raise ValueError( + "Number of vocabs must match the number of columns " + "in the data") + + transformers = [ + sequential_transforms(vocab_func(vocabs[idx]), + totensor(dtype=torch.long)) + for idx in range(len(vocabs)) + ] + + datasets = [] + for item in data_select: + if raw_data[item] is not None: + datasets.append( + SequenceTaggingDataset(raw_data[item], vocabs, transformers)) + + return datasets + + +class SequenceTaggingDataset(torch.utils.data.Dataset): + """Defines an abstraction for raw text sequence tagging iterable datasets. + Currently, we only support the following datasets: + - UDPOS + - CoNLL2000Chunking + """ + def __init__(self, data, vocabs, transforms): + """Initiate sequence tagging dataset. + Arguments: + data: a list of word and its respective tags. Example: + [[word, POS, dep_parsing label, ...]] + vocabs: a list of vocabularies for its respective tags. + The number of vocabs must be the same as the number of columns + found in the data. + transforms: a list of string transforms for words and tags. + The number of transforms must be the same as the number of columns + found in the data. + """ + + super(SequenceTaggingDataset, self).__init__() + self.data = data + self.vocabs = vocabs + self.transforms = transforms + + if len(self.data[0]) != len(self.vocabs): + raise ValueError("vocabs must have the same number of columns " + "as the data") + + def __getitem__(self, i): + curr_data = self.data[i] + if len(curr_data) != len(self.transforms): + raise ValueError("data must have the same number of columns " + "with transforms function") + return [self.transforms[idx](curr_data[idx]) for idx in range(len(self.transforms))] + + def __len__(self): + return len(self.data) + + def get_vocabs(self): + return self.vocabs + + +def UDPOS(*args, **kwargs): + """ Universal Dependencies English Web Treebank + + Separately returns the training, validation, and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + vocabs: A list of voabularies for each columns in the dataset. Must be in an + instance of List + Default: None + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.datasets.raw import UDPOS + >>> train_dataset, valid_dataset, test_dataset = UDPOS() + """ + return _setup_datasets(*(("UDPOS", ) + args), **kwargs) + + +def CoNLL2000Chunking(*args, **kwargs): + """ CoNLL 2000 Chunking Dataset + + Separately returns the training and test dataset + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + vocabs: A list of voabularies for each columns in the dataset. Must be in an + instance of List + Default: None + data_select: a string or tuple for the returned datasets + (Default: ('train', 'valid', 'test')) + By default, all the three datasets (train, test, valid) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test + data. + + Examples: + >>> from torchtext.datasets.raw import CoNLL2000Chunking + >>> train_dataset, valid_dataset, test_dataset = CoNLL2000Chunking() + """ + return _setup_datasets(*(("CoNLL2000Chunking", ) + args), **kwargs) + + +DATASETS = {"UDPOS": raw.UDPOS, "CoNLL2000Chunking": raw.CoNLL2000Chunking} diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index 5fad51135d..e5d29c3d1b 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -2,7 +2,7 @@ import logging from torchtext.experimental.datasets import raw -from torchtext.vocab import build_vocab_from_iterator +from torchtext.vocab import Vocab, build_vocab_from_iterator from torchtext.data.utils import get_tokenizer from ..functional import vocab_func, totensor, sequential_transforms diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index a0f2dfeeec..fad8e0ad87 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -1,36 +1,240 @@ -import csv +import logging +import os + import torch from torch import Tensor import torch.nn as nn +from tqdm import tqdm + +from torchtext.utils import ( + download_from_url, + extract_archive +) + +logger = logging.getLogger(__name__) + + +def _infer_shape(f, delimiter=" "): + num_lines, vector_dim = 0, None + for line in f: + if vector_dim is None: + # token and entries are separated by delimiter + token, entries = line.rstrip().split(bytes(delimiter, "utf-8"), 1) + # we assume entries are always separated by " " + vector = entries.split(b" ") + + # Assuming word, [vector] format + if len(vector) > 2: + # The header present in some (w2v) formats contains two elements. + vector_dim = len(vector) + num_lines += 1 # First element read + else: + num_lines += 1 + f.seek(0) + return num_lines, vector_dim + + +def _load_token_and_vectors_from_file(file_path, delimiter=" "): + with open(file_path, "rb") as f: + num_lines, dim = _infer_shape(f, delimiter=delimiter) + stoi, tokens, vectors, dup_tokens = {}, [], [], [] + + vectors = torch.zeros((num_lines, dim)) + vectors_loaded = 0 + + for line in tqdm(f, unit_scale=0, unit="lines", total=num_lines): + # token and entries are separated by delimiter + token, entries = line.rstrip().split(bytes(delimiter, "utf-8"), 1) + # we assume entries are always separated by " " + entries = entries.split(b" ") + + if dim is None and len(entries) > 1: + dim = len(entries) + elif len(entries) == 1: + logger.warning("Skipping token {} with 1-dimensional " + "vector {}; likely a header".format(token, entries)) + continue + elif dim != len(entries): + raise RuntimeError( + "Vector for token {} has {} dimensions, but previously " + "read vectors have {} dimensions. All vectors must have " + "the same number of dimensions.".format(token, len(entries), + dim)) + try: + if isinstance(token, bytes): + token = token.decode("utf-8") + except UnicodeDecodeError: + logger.info("Skipping non-UTF8 token {}".format(repr(token))) + continue + + if token in stoi: + dup_tokens.append((token, len(vectors) + 1)) + continue + + stoi[token] = len(vectors) + tokens.append(token) + vectors[vectors_loaded] = torch.tensor([float(c) for c in entries], dtype=torch.float) + vectors_loaded += 1 + vectors = vectors[:vectors_loaded] + return tokens, vectors, dup_tokens + + +def FastText(language="en", unk_tensor=None, root=".data", validate_file=True): + r"""Create a FastText Vectors object. + + Args: + language (str): the language to use for FastText. The list of supported languages options + can be found at https://fasttext.cc/docs/en/language-identification.html + unk_tensor (Tensor): a 1d tensor representing the vector associated with an unknown token + root (str): folder used to store downloaded files in (.data) + validate_file (bool): flag to determine whether to validate the downloaded files checksum. + Should be `False` when running tests with a local asset. + + Returns: + Vectors: a Vectors object. + + Raises: + ValueError: if duplicate tokens are found in FastText file. + + """ + url = "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.{}.vec".format(language) + file_name = os.path.basename(url) + + cached_vectors_file_path = os.path.join(root, file_name + ".pt") + if os.path.isfile(cached_vectors_file_path): + logger.info("Loading from cached file {}".format(str(cached_vectors_file_path))) + return torch.load(cached_vectors_file_path) + + checksum = None + if validate_file: + checksum = CHECKSUMS_FAST_TEXT.get(url, None) + + downloaded_file_path = download_from_url(url, root=root, hash_value=checksum) + tokens, vectors, dup_tokens = _load_token_and_vectors_from_file(downloaded_file_path) + + if dup_tokens: + raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) + + vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + torch.save(vectors_obj, cached_vectors_file_path) + return vectors_obj -def vectors_from_file_object(file_like_object, unk_tensor=None): +def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=True): + r"""Create a GloVe Vectors object. + + Args: + name (str): the name of the GloVe dataset to use. Options are: + - 42B + - 840B + - twitter.27B + - 6B + dim (int): the dimension for the GloVe dataset to load. Options are: + 42B: + - 300 + 840B: + - 300 + twitter.27B: + - 25 + - 50 + - 100 + - 200 + 6B: + - 50 + - 100 + - 200 + - 300 + unk_tensor (Tensor): a 1d tensor representing the vector associated with an unknown token. + root (str): folder used to store downloaded files in (.data) + validate_file (bool): flag to determine whether to validate the downloaded files checksum. + Should be `False` when running tests with a local asset. + Returns: + Vectors: a Vectors object. + + Raises: + ValueError: if unexpected duplicate tokens are found in GloVe file. + + """ + dup_token_glove_840b = [("����������������������������������������������������������������������" + "����������������������������������������������������������������������" + "����������������������������������������������������������������������" + "����������������������������������������������������������������������" + "������������������������������������������������������", 140649)] + urls = { + "42B": "https://nlp.stanford.edu/data/glove.42B.300d.zip", + "840B": "https://nlp.stanford.edu/data/glove.840B.300d.zip", + "twitter.27B": "https://nlp.stanford.edu/data/glove.twitter.27B.zip", + "6B": "https://nlp.stanford.edu/data/glove.6B.zip", + } + valid_glove_file_names = { + "glove.42B.300d.txt", + "glove.840B.300d.txt", + "glove.twitter.27B.25d.txt", + "glove.twitter.27B.50d.txt", + "glove.twitter.27B.100d.txt", + "glove.twitter.27B.200d.txt", + "glove.6B.50d.txt", + "glove.6B.100d.txt", + "glove.6B.200d.txt", + "glove.6B.300d.txt" + } + + file_name = "glove.{}.{}d.txt".format(name, str(dim)) + if file_name not in valid_glove_file_names: + raise ValueError("Could not find GloVe file with name {}. Please check that `name` and `dim`" + "are valid.".format(str(file_name))) + + url = urls[name] + cached_vectors_file_path = os.path.join(root, file_name + '.pt') + if os.path.isfile(cached_vectors_file_path): + logger.info("Loading from cached file {}".format(str(cached_vectors_file_path))) + return torch.load(cached_vectors_file_path) + + checksum = None + if validate_file: + checksum = CHECKSUMS_GLOVE.get(url, None) + + downloaded_file_path = download_from_url(url, root=root, hash_value=checksum) + extracted_file_paths = extract_archive(downloaded_file_path) + # need to get the full path to the correct file in the case when multiple files are extracted with different dims + extracted_file_path_with_correct_dim = [path for path in extracted_file_paths if file_name in path][0] + tokens, vectors, dup_tokens = _load_token_and_vectors_from_file(extracted_file_path_with_correct_dim) + + # Ensure there is only 1 expected duplicate token present for 840B dataset + if dup_tokens and dup_tokens != dup_token_glove_840b: + raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) + + vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + torch.save(vectors_obj, cached_vectors_file_path) + return vectors_obj + + +def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None): r"""Create a Vectors object from a csv file like object. Note that the tensor corresponding to each vector is of type `torch.float`. Format for csv file: - token1,num1 num2 num3 - token2,num4 num5 num6 + token1num1 num2 num3 + token2num4 num5 num6 ... - token_n,num_m num_j num_k + token_nnum_m num_j num_k Args: file_like_object (FileObject): a file like object to read data from. - unk_tensor (int): a 1d tensors representing the vector associated with an unknown token + delimiter (char): a character to delimit between the token and the vector. Default value is "," + unk_tensor (Tensor): a 1d tensor representing the vector associated with an unknown token. Returns: Vectors: a Vectors object. - """ - readCSV = csv.reader(file_like_object, delimiter=',') - - tokens = [] - vectors = [] - for row in readCSV: - tokens.append(row[0]) - vectors.append(torch.tensor([float(c) for c in row[1].split()], dtype=torch.float)) + Raises: + ValueError: if duplicate tokens are found in FastText file. + """ + tokens, vectors, dup_tokens = _load_token_and_vectors_from_file(file_like_object.name, delimiter=delimiter) + if dup_tokens: + raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) return Vectors(tokens, vectors, unk_tensor=unk_tensor) @@ -39,7 +243,7 @@ class Vectors(nn.Module): Arguments: tokens (List[str]): a list of tokens. - vectors (List[torch.Tensor]): a list of 1d tensors representing the vector associated with each token. + vectors (torch.Tensor): a 2d tensor representing the vector associated with each token. unk_tensor (torch.Tensor): a 1d tensors representing the vector associated with an unknown token. Raises: @@ -51,14 +255,13 @@ class Vectors(nn.Module): def __init__(self, tokens, vectors, unk_tensor=None): super(Vectors, self).__init__() - if unk_tensor is None and not vectors: + if unk_tensor is None and (vectors is None or not len(vectors)): raise ValueError("The vectors list is empty and a default unk_tensor wasn't provided.") - if not all(vector.dtype == torch.float for vector in vectors): - raise TypeError("All tensors within `vectors` should be of data type `torch.float`.") + if not vectors.dtype == torch.float: + raise TypeError("`vectors` should be of data type `torch.float`.") unk_tensor = unk_tensor if unk_tensor is not None else torch.zeros(vectors[0].size(), dtype=torch.float) - self.vectors = torch.classes.torchtext.Vectors(tokens, vectors, unk_tensor) @torch.jit.export @@ -69,10 +272,10 @@ def __getitem__(self, token: str) -> Tensor: Returns: vector (Tensor): a tensor (the vector) corresponding to the associated token. """ - return self.vectors.GetItem(token) + return self.vectors[token] @torch.jit.export - def __setitem__(self, token: str, vector: Tensor): + def __setitem__(self, token: str, vector: Tensor) -> None: r""" Args: token (str): the token used to lookup the corresponding vector. @@ -84,4 +287,380 @@ def __setitem__(self, token: str, vector: Tensor): if vector.dtype != torch.float: raise TypeError("`vector` should be of data type `torch.float` but it's of type " + vector.dtype) - self.vectors.AddItem(token, vector.float()) + self.vectors[token] = vector.float() + + @torch.jit.export + def __len__(self) -> int: + r"""Get length of vectors object. + + Returns: + length (int): the length of the vectors. + """ + return len(self.vectors) + + +CHECKSUMS_GLOVE = { + "https://nlp.stanford.edu/data/glove.42B.300d.zip": + "03d5d7fa28e58762ace4b85fb71fe86a345ef0b5ff39f5390c14869da0fc1970", + "https://nlp.stanford.edu/data/glove.840B.300d.zip": + "c06db255e65095393609f19a4cfca20bf3a71e20cc53e892aafa490347e3849f", + "https://nlp.stanford.edu/data/glove.twitter.27B.zip": + "792af52f795d1a32c9842a3240f5f3fe5e941a8ff6df5eb0f9d668092ebc019c", + "https://nlp.stanford.edu/data/glove.6B.zip": + "617afb2fe6cbd085c235baf7a465b96f4112bd7f7ccb2b2cbd649fed9cbcf2fb" +} + +CHECKSUMS_FAST_TEXT = { + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.am.vec": + "b532c57a74628fb110b48b9d8ae2464eb971df2ecc43b89c2eb92803b8ac92bf", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.als.vec": + "056a359a2651a211817dbb7885ea3e6f69e0d6048d7985eab173858c59ee1adf", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.af.vec": + "87ecbfea969eb707eab72a7156b4318d341c0652e6e5c15c21bc08f5cf458644", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.an.vec": + "57db91d8c307c45613092ebfd405061ccfdec5905035d9a8ad364f6b8ce41b29", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ar.vec": + "5527041ce04fa66e45e27d7bd278f00425d97fde8c67755392d70f112fecc356", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.arz.vec": + "0b6c261fd179e5d030f2b363f9f7a4db0a52e6241a910b39fb3332d39bcfbec3", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.as.vec": + "4475daa38bc1e8501e54dfcd79a1a58bb0771b347ad9092ce9e57e9ddfdd3b07", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.av.vec": + "1292eed7f649687403fac18e0ee97202e163f9ab50f6efa885aa2db9760a967e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ast.vec": + "fbba958174ced32fde2593f628c3cf4f00d53cd1d502612a34e180a0d13ce037", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.be.vec": + "3b36ba86f5b76c40dabe1c7fc3214338d53ce7347c28bb2fba92b6acc098c6ad", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.az.vec": + "93ebe624677a1bfbb57de001d373e111ef9191cd3186f42cad5d52886b8c6467", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ba.vec": + "b739fd6f9fe57205314d67a7975a2fc387b55679399a6b2bda0d1835b1fdd5a8", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.azb.vec": + "05709ce8abc91115777f3cc2574d24d9439d3f6905500163295d695d41260a06", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bar.vec": + "3f58304eb0345d96c0abbffb61621c1f6ec2ca39e13272b434cc6cc2bde052a1", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bcl.vec": + "309bb74a85647ac3a5be53fd9d3be3196cff385d257561f4183a0d91a67f0c8b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bg.vec": + "16f1a02f3b708f2cbc04971258b0febdfc9ed4e64fcc3818cc6a397e3db5cf81", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bh.vec": + "ab0819c155fd1609393f8af74794de8d5b49db0787edf136e938ea2c87993ab5", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bn.vec": + "3dd27b9b271c203a452de1c533fdf975ebec121f17f945ef234370358db2bae6", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bpy.vec": + "2ba9f046d70bdaae2cbd9d33f9a1d2913637c00126588cc3223ba58ca80d49fe", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bo.vec": + "c5ed2a28edf39bc100f4200cdf1c9d3c1448efefcb3d78db8becea613a2fb2eb", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.br.vec": + "fe858e2be787351cce96c206a9034c361e45f8b9e0a385aacfce3c73f844e923", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.da.vec": + "397b0c3e18f710fb8aa1caf86441a25af2f247335e8560dbe949feb3613ef5cc", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bs.vec": + "ee065fe168c0a4f1a0b9fbd8854be4572c138a414fd7200381d0135ce6c03b49", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.bxr.vec": + "0bc0e47a669aa0d9ad1c665593f7257c4b27a4e3becce457a7348da716bdabb4", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ca.vec": + "1600696088c7f2fe555eb6a4548f427f969a450ed0313d68e859d6024242db5f", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.cbk.vec": + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ceb.vec": + "7fbe4474043e4f656eb2f81ee03d1e863cef8e62ad4e3bd9a3a4143785752568", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ce.vec": + "2a321e2de98d0abb5a12599d9567dd5ac93f9e2599251237026acff35f23cef8", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.cs.vec": + "0eba2ac0852b1057909d4e8e5e3fa75470f9cb9408b364433ac4747eb2b568a9", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.cv.vec": + "67f09d353f2561b16c385187789eb6ff43fa125d3cc81081b2bc7d062c9f0b8a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.cy.vec": + "1023affdcb7e84dd59b1b7de892f65888b6403e2ed4fd77cb836face1c70ee68", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.co.vec": + "7f16f06c19c8528dc48a0997f67bf5f0d79da2d817247776741b54617b6053d9", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ckb.vec": + "ef3a8472cc2ac86976a1a91cde3edc7fcd1d1affd3c6fb6441451e9fbc6c3ae8", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.de.vec": + "3020c26e32238ba95a933926763b5c693bf7793bf0c722055cecda1e0283578c", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.diq.vec": + "6f71204e521e03ae70b4bd8a41c50cc72cd4b8c3e242a4ab5c77670603df1b42", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.dty.vec": + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.dv.vec": + "2b4f19bfcf0d38e6ab54e53d752847ab60f4880bae955fff2c485135e923501e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.dsb.vec": + "ed6699709e0e2f2e3b4a4e32ef3f98f0ccb3f1fed2dad41b7a6deafdc2b32acf", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.el.vec": + "a397de14c637f0b843fcda8724b406f5a7fe9f3ead7f02cfcaeed43858212da6", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.en.vec": + "ba5420ac217fb34f15f58ded0d911a4370dfb1f3341fa7511a49ae74c87de282", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.eml.vec": + "a81f0a05c9d3ffd310f6e2d864ee48bff952dbfb2612293b58ab7bc49755cfe6", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.es.vec": + "cf2e9a1976055a18ad358fb0331bc5f9b2e8541d6d4903b562a63b60f3ae392e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.et.vec": + "de15792f8373f27f1053eef28cff4c782c4b440fd57a3472af38e5bf94eafda6", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.eo.vec": + "a137201c5cf54e218b6bb0bac540beaee2e81e285bf9c59c0d57e0a85e3353c0", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.fi.vec": + "63017414860020f7409d31c8b65c1f8ed0a64fe11224d4e82e17667ce0fbd0c5", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.fa.vec": + "da0250d60d159820bf0830499168c2f4f1eaffe74f1508c579ca9b41bae6c53f", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.eu.vec": + "93f6e44742ea43ff11b5da4c634ebf73f3b1aa3e9485d43eb27bd5ee3979b657", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ilo.vec": + "e20ac3c7ef6a076315f15d9c326e93b22c2d5eee6bec5caef7bab6faf691b13a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.frr.vec": + "a39b393261a8a5c19d97f6a085669daa9e0b9a0cab0b5cf5f7cb23f6084c35e0", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ga.vec": + "7b33e77e9feb32a6ce2f85ab449516294a616267173c6bbf8f1de5c2b2885699", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.fy.vec": + "07b695f598e2d51cdd17359814b32f15c56f5beaa7a6b49f69de835e13a212b8", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.fr.vec": + "bc68b0703375da9e81c3c11d0c28f3f8375dd944c209e697c4075e579455ac2a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.gd.vec": + "464e8b97a8b262352a0dc663aa22f98fc0c3f9e7134a749644ad07249dbd42e8", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.gn.vec": + "5d2ac06649f6199ffad8480efa03f97d2910d1501a4528bfb013524d6f2d6c2b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.gl.vec": + "b4b6233b0c650f9d665e5c8aa372f8745d1a40868f93ecf87f026c60b2bb0f9e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.gu.vec": + "910296b888e17416e9af43f636f83bbe0b81da68b5e62139ab9c06671dbbacf1", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.gom.vec": + "20f38a650e90a372a92a1680c6a92fc1d89c21cd41835c8d0e5e42f30d52b7ec", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.hi.vec": + "e5ec503a898207e17a7681d97876607b0481384b6c1cc4c9c6b6aaba7ad293d0", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.gv.vec": + "b9d6384219d999e43f66ace6decd80eb6359e0956c61cb7049021b194c269ffe", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.he.vec": + "5d861a705bf541671c0cee731c1b71f6a65d8defd3df2978a7f83e8b0580903b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.hif.vec": + "445e65668be650f419e0a14791b95c89c3f4142d32371501e53038749eb2c71c", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.hsb.vec": + "27be86ce2435dfeb07d76d406a8ec7b46ebf9b6b8fb5da24208eca1492ffe5bb", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.hr.vec": + "4d42787554747a86253a23e9a830a8571faea0b622e48ed136f8b9817dea9da3", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ht.vec": + "be5e089f22a43ca00a35467545bc6cca15b5c5951ac34c504a23686ab735e995", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.hy.vec": + "63dc48faeb4f3c5ea2e6f78a0bf4d8bf3d623af52b7f3a9b9e5984dbc79ba66f", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.hu.vec": + "766de324b4783fe2d31df8f78966ea088712a981b6b0b5336bc71938773fe21e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ia.vec": + "1ec19501030cafa0fdccf7f4c5794f4cd7e795b015330f6ea6bc9eff97eaeca5", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ie.vec": + "41c9e34f5445c4aafd7f5d52665b9aa89fb3c76b5262e9401d21b58dd2e53609", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.id.vec": + "436180ac3d405eefe8c2be20ae3e67cddc866afb94e486afcbaef549c24b7d60", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.io.vec": + "2bedf13a6d751ad5191474e65b6104fa3175ca4c3f9ade214f25cfeede1c9c8c", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.is.vec": + "7fe6d8eca113e245ea5467e8f4cab9697dff1d623ac0a8e6fdaca0a93d7fc6f3", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.it.vec": + "5a9d111edd3f199e7379373ba18f4e5317c6c6c5053a9d6d0a56f32298d3bde4", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ja.vec": + "b44b2eef8bdcf0739c971c4ff7fcae7a300b5e06cf0e50c5787082957ad9d998", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.jv.vec": + "4a46ac08781861d6e19fcc70a421340b627889a054279dacee0f32ee12b1f4f7", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.jbo.vec": + "766c0eb15b1e2cad9a14d0a0937e859e20f6f2ed203ff7ba4f3c70d3b1888d2b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ka.vec": + "10b08b9372ef6e44e0e826e6a8d01b3396a319d78ce2db990c51d688c2d0259e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.kk.vec": + "2dabc86ed917ba236c96c8c327aa3394f32ea511068a9dce205a46923c5716d1", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.kn.vec": + "7f9ab4985e0d5f91462fbdcbfbfaeef619d973e638fbc7c928cfcc5bd37d473b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.km.vec": + "bf35b294d86fceac916feee3e167fe6aee3fe73380f78e5377c94ff0d023b77c", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ko.vec": + "44bae904dd7923d1178e83067cc42d9437097f7e86cb83bdd8281febe4b9adaa", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.krc.vec": + "b0ff031a60938b612f9b0c9612bd206cbb1f5288a6ee3482d116174b81d9269f", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.kv.vec": + "a6202b11f869683ce75e60bf206c230109f91b651801dc6ea07b3b7f2c5c9b32", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.kw.vec": + "061e26d970aa7cb3fded9278372a53d0dd8359abc664caa385edaac9aac1359d", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ku.vec": + "7f117b704d5ac791463796b1ac2d833717c0cfc75dbfb50c2e80aa0c9348c448", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ky.vec": + "adb5c72c47c514cd5417f46f8a7baba4061063b0e75c2d0b2e42dc08144af6cf", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.lb.vec": + "566334801777746bc2c1076e1b24a8281e10fe31f0db30a2a4b0b490033e6d04", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.li.vec": + "50a1054a31a7e11f5bd3fe980e1646205284e540fb1be3ae88f4bf16b0d10301", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.lez.vec": + "109c3f3fee8970cfab1b7152315816284aa4b5788403d4007866ad417a63b5e6", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.la.vec": + "ca3b46e03bebf6b937cd7f01c29566b7d48d94d3de033a527ce45744a40ea00a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.lo.vec": + "acd1a8cbabbfc50196cb3dfeb9e82c71409c40ae90dc3485044396bbb7350431", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.lmo.vec": + "26952850a5569e8241d1e6ff2d6877fa51b6715e8fdeec9bf5f9d716e94c958e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.lt.vec": + "54bc7d3c1ef600f4710047c4dafd1346e8b53bd29a327bc132f6a9fd0c14b8c7", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.lrc.vec": + "24d6c530275176cb03e566e9e5737a1680e79854e6c0a2da19a7cb27a029a0ce", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.lv.vec": + "ed93e318306e19cc18154b095a2494d94ab061009c3a8fa1c3501495f81b7198", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mg.vec": + "12ab899108b74bbee8b685ed7f4941719485560c7346875a0be79c7ba6dbec2a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mai.vec": + "387a5d1194e8e441b09c7a215a71cad75e6e1a0777c08f90b2ed5bf4e90423d3", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mhr.vec": + "080cb31ff85f0bc21ae75b66311214d594f76a7fdf17699aa5ba8239c6ccd164", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mk.vec": + "ea3d8e77ba3cf17c516e7d0c93e45a73a5e54b1b245ddb65351826678fe102d1", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.min.vec": + "13fac5abbd2053365c5570edea2017e2a6d814e682a8e906d92b3deaa761b741", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ml.vec": + "69eafbab72db69278acec01ff8883d41d616f8aaa59e473faafc115996db5898", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mn.vec": + "a1ec46e780d2f42633ffbe363ce17b1f700fa6744ce40b5a19446a714b9066d8", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mr.vec": + "e30ee3d90d6687868cc6dee609e4d487b81362ea231e8456f8265bace55c7ffb", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ms.vec": + "71ebc8bc0959a592e071db35995119ee33fc17ff61611e6ea09ea6736b317f17", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mrj.vec": + "93351fb85f38523fbf3767fac32625f26be37582afbddfef258642f4530f4ab9", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.my.vec": + "5a8216d0df2d70e5517bcb4cbe523fc03d34f802a83d04a88faadfff7b700b9f", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mwl.vec": + "6997a71b0a745c124135d6c52196d14412d4068fca8aa13b2b3b9598b933cf38", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mt.vec": + "f07a6071fcb3bcda4c6c5e6a0ebe6f3f5d228e8c1fc7ef5160cc3dd098718e98", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.myv.vec": + "ffebdb940b95fe76f3885e8853f3d88ebf9a23c24f64ccdf52c9a269a3f4d459", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.nah.vec": + "2b1fc52e4a4901d824070d1e5fc2196f33c6d787edb8ce3732ace1d05407788e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.mzn.vec": + "692f68fa5537a690720f9c2ce0a2c5edaa0d06fe04b2749d169a178aecf751ad", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.nap.vec": + "954aa926c6d47882c2397997d57a8afde3e0ca851a42b07280d6e465577f6925", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ne.vec": + "8d4bf875ca4733d022d4f415777dc2f9e33a93ddc67361add30aed298bc41bc6", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.nds.vec": + "767dcf37a6018cce9f885b31b3c54671199c0f9554ffb09112130b62144556db", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.nl.vec": + "d0601975d00d672ad03a3b146c13c4b6240111d286834e385853e2a25f4fb66a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.new.vec": + "b7328d5408d91bbdc7ee7a9fd6761af322ea8ddb35a405a60826a5b7e327dd29", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.nn.vec": + "c2d2617c932bb49ba64bea9396435ce882fc4238e3983081967658891d18309e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.no.vec": + "762670d35c29910a0daa86444a1b32d4fd9c94deff82c53abe751c5463dcb025", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.or.vec": + "b1d97ba3d93b37903266b551e164fc9e51c7d5a429e77330cb281fb7de28bd71", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.os.vec": + "c249450a7cb5750c39a9121658b91055a0f5cccfe67c1879706a8bced390bebd", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.oc.vec": + "a4bb95b2fc28e82c5c976af32d632e5241daeeaea2bca2cb3300ad036619c0f6", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.pam.vec": + "b0dd33c3f7e85805b1937d95d73194f3834f40a43a92c12544911ab30818cd20", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.pa.vec": + "61462550fac53d8156c2e61f738b63ef0639949b87d8abeb566194dc86b1a488", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.pl.vec": + "9c2674431e796595c8c1d3b5e1a941c7e833d23cad223d6e4d1c36447af5f3cc", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.pfl.vec": + "889a62dbb945033bfc53516b976042df7791c0aa8290dcb92f12240685d2d2c1", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.pnb.vec": + "7c26c9297b15a75bb1f2bfeb8f11dd3c55821a06bd64fe7a105699ed4d9d794a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ps.vec": + "e718dfda7790cb309e37f0d42400afebf6036aa018dcd7eb330d576bb5c55030", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.qu.vec": + "b71076861dc0221acf540d4abbf6e760a2871c2dc380556fc7bad402d26ec738", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.pms.vec": + "33a90387e8b75c09980b4c80171cabaae38e9b87de7bf320ecd93c344afaeb39", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.rm.vec": + "9a7f0690c8b42c96a1ad50bb8e7da5d69a3a9f7f0676289243319553a10aac41", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ro.vec": + "e19b3e99a6eae03c15dc5f5d7385beb2540528ee102501499b7ca846c2687d83", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.pt.vec": + "bffbfcafb9f004f13f1be12fa0201c5011324b14a52c2996ae2b97f268819e0c", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.rue.vec": + "cb0aa15cb7816337509ed1b95c8844928a38d29e392e4e5295f35593e633b222", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sa.vec": + "6a303056d4841496599595be06fdcdf28ab5a2fc611c3428d95a3af9d4df0067", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ru.vec": + "9567b90e037c459eb4be4c2a47a04fffbfd5b0d01b84baf86b16535f0dc3728e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sah.vec": + "670a7c98a6c4bf6444b1a26213a5c8114d41c68006b4f32f6dee96558494076d", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sc.vec": + "52abeb74f579f53b3c8bb55ae5cd8bbf8878c7083e61c693c0f7c8d289e80248", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.scn.vec": + "ad8e57aba916c6ab571157c02098ad1519c8f6ce1e72f35538efe1cb488a1a25", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sd.vec": + "7906a45f27aa65ba3d5cb034f56d2852d54d9ec3301b9df345f1a12a6cef9d7a", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sco.vec": + "eafc948e3e9e20aac5e7986979b3b3275c1acb2944e07b9b58d964da61408ff7", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sh.vec": + "36dc95a0fc0de137421df0b86eb7c55faff04d30b26969ae1fa331631824276d", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sk.vec": + "dd9f51e48a55fe63c5cf901c9ce0bd6baab249ac51135a1b4cdb4e12f164687b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sl.vec": + "2ab76744a9d5321b6709b4ff379fb10495e004f72f6f221965028d6ee1cffd1e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.so.vec": + "28025afd6be6c8166898af85eb33536b111753fbf30e363beb7c064674c6d3c4", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.si.vec": + "112246c583380fcf367932b55e5d42d5ffc12b8c206f981deae24fd4c61b7416", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sq.vec": + "4b4850d700aa1674e44bf733d6e2f83763b1ce9f0e7dfd524eb2c1b29c782631", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sr.vec": + "713f24f861cf540e3e28882915a89023cde222b6edb28fac7fb45b9bd894042e", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sv.vec": + "d21b96312bcf64faf1cd972d6eff44cd4a5afc575ff5c8f9b31d2d8819f56fca", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.su.vec": + "b763d1c6471320b071ad2009a82dc6fb0ffeaf07319562438f84cfcb2718e2a4", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.sw.vec": + "b9e17565d44cfba3c120274fd359b371c3b8d969b973e77ada3357defa843c79", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.te.vec": + "2d684ba8af330a716f732f9581c7faee80322232e02713d441130f304af8a897", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.tg.vec": + "e2ed18d08da76bff25f2170452365aa341e967114a45271a8ba8d9cefc062aef", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.th.vec": + "079fadf992d34ae885ce5d7c23baa10aea4ee971147993b007d8bf0557906a18", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ta.vec": + "a3cedbf2ce4adb5a8b3688539ef37c6c59047d8d20ffd74e2e384ffcac588ac1", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.tk.vec": + "05f0ccf5f6a2bdf6073e16f11c7a2327ebe4d12610af44051872d4fea32591ec", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.tl.vec": + "a524621cefca337c5b83e6a2849afd12100fcd59bd7f3b228bddb4fb95cb17ea", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.tr.vec": + "4cf567dbb73053bb7b08370e89ec6a7c5626e397e71de99637e70c68ba4c71d9", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.tt.vec": + "6dc86b913c0375b204f1c8d7c8543d80888030693ed4ebef10c75e358c17d0fa", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.tyv.vec": + "b8a687337b3e7f344b9aecff19306c7a1cb432cdc03b46fd2f2e9e376be3073c", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.uk.vec": + "186523ce3be943f9ecae127155371c494192564d1dffe743ab5db8ba28e50874", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ug.vec": + "04184a3a6be245e55f09c04856acc14f687adc4b802aaf875bf5883a1669a856", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.ur.vec": + "df38c3cf123edf09366f47ea694c02dec59929df218ca81d5aa69d77552b6865", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.uz.vec": + "f6289fa8cf2ff936a1716a5cf8fd07da46907af26b1236403a292273f2d8fb55", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.vec.vec": + "c6d786f4231f30b4116a8dce181b2513b40b55a654c60793a5c0566152287aeb", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.vls.vec": + "2f430e1d83f0f00fef517f7d35505bcf1445dc7de0db4f051ae7315f1bb0647b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.vep.vec": + "81268d74e29bbae9f166d523151d12c246ff26be9cd680344faece7e1ca97ebe", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.vi.vec": + "206206d496697de7e96c69500e926014c9f71c7115c3844350766ced21d7003f", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.war.vec": + "51b58d0ace2779b17b88a5b51847a813042e2b018ada573e0bce5a093da5ff4d", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.wa.vec": + "37aee21a768a5883f6bee4a486040883224a93619b8b03dcefb1e939b655cd1c", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.vo.vec": + "4fa6a6ff897a1a49470861d343792feac0ca16e02e9ed1917f1506245ac28b2d", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.wuu.vec": + "09a619a8ef25392bf8905d741cdb63922a115e05b38f56de27c339985691c5d2", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.xal.vec": + "bf9ad172c55d8910e0156953158a9cb1f9cbcc6b9b1e78cf09c123d3409af5e3", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.yi.vec": + "75dc1cad2a4dad5ad7d7723ef0b8e87abe3f4b799e9c38c54f4afe51d916a82b", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.yo.vec": + "c8aa49859debb8b3d1568bb510e12814d55ce5994f0cc6dc43ca9b2c4f739946", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.xmf.vec": + "94ffed6fc1123523d72e3b92d0d3cc5513c116b9e9b2bba5d8b47f7b6fce6abd", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.yue.vec": + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.zh.vec": + "76f72bd13269ae492715415ef62afb109046ce557f5af24e822b71f9b9360bef" +} diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py new file mode 100644 index 0000000000..a52599d952 --- /dev/null +++ b/torchtext/experimental/vocab.py @@ -0,0 +1,155 @@ +import logging +from typing import Dict, List + +import torch +import torch.nn as nn + +logger = logging.getLogger(__name__) + + +class Vocab(nn.Module): + r"""Creates a vocab object which maps tokens to indices. + + Note that the ordering in which key value pairs were inserted in the `ordered_dict` will be respected when building the vocab. + Therefore if sorting by token frequency is important to the user, the `ordered_dict` should be created in a way to reflect this. + + Arguments: + ordered_dict (collections.OrderedDict): object holding the frequencies of each token found in the data. + min_freq: The minimum frequency needed to include a token in the vocabulary. + Values less than 1 will be set to 1. Default: 1. + specials: The tuple of special tokens (e.g., padding or eos) that will be prepended/postpended to the vocabulary. + based on the `specials_first` flag. The ordering of the tuple will be preserved. Default: ('', '') + specials_first: Whether to add special tokens into the vocabulary at first. If it is False, + they are added into the vocabulary at last. Default: True. + + Raises: + ValueError: if a default `unk_token` isn't provided. + + Examples: + >>> from torchtext.experimental.vocab import Vocab + >>> from collections import Counter, OrderedDict + >>> counter = Counter(["a", "a", "b", "b", "b"]) + >>> sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) + >>> ordered_dict = OrderedDict(sorted_by_freq_tuples) + >>> v1 = Vocab(ordered_dict) + >>> tokens = ['e', 'd', 'c', 'b', 'a'] + >>> v2 = Vocab(OrderedDict([(token, 1) for token in tokens])) + """ + + def __init__(self, ordered_dict, min_freq=1, unk_token='', specials=('', ''), specials_first=True): + super(Vocab, self).__init__() + + if not unk_token: + raise ValueError("A default unk token wasn't provided.") + + if unk_token not in specials: + raise ValueError("The unk token wasn't found in the `specials` tuple.") + + tokens = [] + for token, freq in ordered_dict.items(): + if freq >= min_freq: + if token in specials: + raise ValueError("A `specials` token {} was found inside of `ordered_dict`." + "Please ensure that the `ordered_dict` doesn't contain any special tokens.".format(token)) + tokens.append(token) + + # assume special tokens dont appear in ordered_dict + if specials_first: + tokens = list(specials) + tokens + else: + tokens += list(specials) + + self.vocab = torch.classes.torchtext.Vocab(tokens, unk_token) + + @torch.jit.export + def __len__(self) -> int: + r"""Returns: + length (int): the length of the vocab + """ + return len(self.vocab) + + @torch.jit.export + def __getitem__(self, token: str) -> int: + r""" + Args: + token (str): the token used to lookup the corresponding index. + + Returns: + index (int): the index corresponding to the associated token. + """ + return self.vocab[token] + + @torch.jit.export + def insert_token(self, token: str, index: int) -> None: + r""" + Args: + token (str): the token used to lookup the corresponding index. + index (int): the index corresponding to the associated token. + + Raises: + RuntimeError: if `index` not between [0, Vocab.size()] or if token already exists in the vocab. + """ + self.vocab.insert_token(token, index) + + @torch.jit.export + def append_token(self, token: str) -> None: + r""" + Args: + token (str): the token used to lookup the corresponding index. + """ + self.vocab.append_token(token) + + @torch.jit.export + def lookup_token(self, index: int) -> str: + r""" + Args: + index (int): the index corresponding to the associated token. + + Returns: + token (str): the token used to lookup the corresponding index. + + Raises: + RuntimeError: if `index` not between [0, itos.size()]. + """ + return self.vocab.lookup_token(index) + + @torch.jit.export + def lookup_tokens(self, indices: List[int]) -> List[str]: + r""" + Args: + indices (List[int]): the `indices` used to lookup their corresponding`tokens`. + + Returns: + tokens (List[str]): the `tokens` associated with `indices`. + + Raises: + RuntimeError: if an index within `indices` is not between [0, itos.size()]. + """ + return self.vocab.lookup_tokens(indices) + + @torch.jit.export + def lookup_indices(self, tokens: List[str]) -> List[int]: + r""" + Args: + tokens (List[str]): the tokens used to lookup their corresponding `indices`. + + Returns: + indices (List[int]): the 'indices` associated with `tokens`. + """ + return self.vocab.lookup_indices(tokens) + + @torch.jit.export + def get_stoi(self) -> Dict[str, int]: + r""" + Returns: + stoi (dict): dictionary mapping tokens to indices. + """ + return self.vocab.get_stoi() + + @torch.jit.export + def get_itos(self) -> List[str]: + r""" + Returns: + stoi (dict): dictionary mapping indices to tokens. + """ + return self.vocab.get_itos() diff --git a/torchtext/utils.py b/torchtext/utils.py index b892396a15..d8348e840b 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -1,5 +1,6 @@ import requests import csv +import hashlib from tqdm import tqdm import os import tarfile @@ -11,7 +12,9 @@ def reporthook(t): - """https://github.com/tqdm/tqdm""" + """ + https://github.com/tqdm/tqdm. + """ last_b = [0] def inner(b=1, bsize=1, tsize=None): @@ -30,22 +33,31 @@ def inner(b=1, bsize=1, tsize=None): return inner -def download_from_url(url, path=None, root='.data', overwrite=False): - """Download file, with logic (from tensor2tensor) for Google Drive. - Returns the path to the downloaded file. +def download_from_url(url, path=None, root='.data', overwrite=False, hash_value=None, + hash_type="sha256"): + """Download file, with logic (from tensor2tensor) for Google Drive. Returns + the path to the downloaded file. Arguments: - url: the url of the file - path: explicitly set the filename, otherwise attempts to - detect the file name from URL header. (None) + url: the url of the file from URL header. (None) root: download folder used to store the file in (.data) overwrite: overwrite existing files (False) + hash_value (str, optional): hash for url (Default: ``None``). + hash_type (str, optional): hash type, among "sha256" and "md5" (Default: ``"sha256"``). Examples: + >>> url = 'http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/validation.tar.gz' + >>> torchtext.utils.download_from_url(url) >>> url = 'http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/validation.tar.gz' >>> torchtext.utils.download_from_url(url) >>> '.data/validation.tar.gz' + """ + def _check_hash(path): + if hash_value: + with open(path, "rb") as file_obj: + if not validate_file(file_obj, hash_value, hash_type): + raise RuntimeError("The hash of {} does not match. Delete the file manually and retry.".format(path)) def _process_response(r, root, filename): chunk_size = 16 * 1024 @@ -60,6 +72,7 @@ def _process_response(r, root, filename): if os.path.exists(path): logging.info('File %s already exists.' % path) if not overwrite: + _check_hash(path) return path logging.info('Overwriting file %s.' % path) logging.info('Downloading file {} to {}.'.format(filename, path)) @@ -71,6 +84,8 @@ def _process_response(r, root, filename): file.write(chunk) t.update(len(chunk)) logging.info('File {} downloaded.'.format(path)) + + _check_hash(path) return path if path is None: @@ -162,6 +177,10 @@ def extract_archive(from_path, to_path=None, overwrite=False): >>> torchtext.utils.download_from_url(url, from_path) >>> torchtext.utils.extract_archive(from_path, to_path) >>> ['.data/val.de', '.data/val.en'] + >>> torchtext.utils.download_from_url(url, from_path) + >>> torchtext.utils.extract_archive(from_path, to_path) + >>> ['.data/val.de', '.data/val.en'] + """ if to_path is None: @@ -216,3 +235,31 @@ def extract_archive(from_path, to_path=None, overwrite=False): else: raise NotImplementedError( "We currently only support tar.gz, .tgz, .gz and zip achives.") + + +def validate_file(file_obj, hash_value, hash_type="sha256"): + """Validate a given file object with its hash. + + Args: + file_obj: File object to read from. + hash_value (str): Hash for url. + hash_type (str, optional): Hash type, among "sha256" and "md5" (Default: ``"sha256"``). + Returns: + bool: return True if its a valid file, else False. + + """ + + if hash_type == "sha256": + hash_func = hashlib.sha256() + elif hash_type == "md5": + hash_func = hashlib.md5() + else: + raise ValueError + + while True: + # Read by chunk to avoid filling memory + chunk = file_obj.read(1024 ** 2) + if not chunk: + break + hash_func.update(chunk) + return hash_func.hexdigest() == hash_value diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 283f8176f7..0000000000 --- a/tox.ini +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -ignore = E401,E402,E722,W503,W504,F821,B006,B007,B008 -max-line-length = 120 -exclude = docs/source From 8003a0270aa622b5f2101019fd1c59c2ab24a741 Mon Sep 17 00:00:00 2001 From: Stanislau Hlebik Date: Fri, 17 Jul 2020 17:07:23 -0700 Subject: [PATCH 16/68] remediation of S205607 fbshipit-source-id: 5113fe0c527595e4227ff827253b7414abbdf7ac --- .python3 | 1 + build_tools/__init__.py | 1 + test/.gitignore | 1 + test/__init__.py | 1 + test/common/__init__.py | 1 + test/data/__init__.py | 1 + 6 files changed, 6 insertions(+) diff --git a/.python3 b/.python3 index e69de29bb2..56de9c5ee1 100644 --- a/.python3 +++ b/.python3 @@ -0,0 +1 @@ +S205607 diff --git a/build_tools/__init__.py b/build_tools/__init__.py index e69de29bb2..56de9c5ee1 100644 --- a/build_tools/__init__.py +++ b/build_tools/__init__.py @@ -0,0 +1 @@ +S205607 diff --git a/test/.gitignore b/test/.gitignore index e69de29bb2..56de9c5ee1 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -0,0 +1 @@ +S205607 diff --git a/test/__init__.py b/test/__init__.py index e69de29bb2..56de9c5ee1 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -0,0 +1 @@ +S205607 diff --git a/test/common/__init__.py b/test/common/__init__.py index e69de29bb2..56de9c5ee1 100644 --- a/test/common/__init__.py +++ b/test/common/__init__.py @@ -0,0 +1 @@ +S205607 diff --git a/test/data/__init__.py b/test/data/__init__.py index e69de29bb2..56de9c5ee1 100644 --- a/test/data/__init__.py +++ b/test/data/__init__.py @@ -0,0 +1 @@ +S205607 From 4e653d1052a8cd7b356f9af99983eef87661a98c Mon Sep 17 00:00:00 2001 From: Stanislau Hlebik Date: Fri, 17 Jul 2020 17:07:23 -0700 Subject: [PATCH 17/68] remediation of S205607 fbshipit-source-id: 798decc90db4f13770e97cdce3c0df7d5421b2a3 --- .python3 | 1 - build_tools/__init__.py | 1 - test/.gitignore | 1 - test/__init__.py | 1 - test/common/__init__.py | 1 - test/data/__init__.py | 1 - 6 files changed, 6 deletions(-) diff --git a/.python3 b/.python3 index 56de9c5ee1..e69de29bb2 100644 --- a/.python3 +++ b/.python3 @@ -1 +0,0 @@ -S205607 diff --git a/build_tools/__init__.py b/build_tools/__init__.py index 56de9c5ee1..e69de29bb2 100644 --- a/build_tools/__init__.py +++ b/build_tools/__init__.py @@ -1 +0,0 @@ -S205607 diff --git a/test/.gitignore b/test/.gitignore index 56de9c5ee1..e69de29bb2 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1 +0,0 @@ -S205607 diff --git a/test/__init__.py b/test/__init__.py index 56de9c5ee1..e69de29bb2 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -1 +0,0 @@ -S205607 diff --git a/test/common/__init__.py b/test/common/__init__.py index 56de9c5ee1..e69de29bb2 100644 --- a/test/common/__init__.py +++ b/test/common/__init__.py @@ -1 +0,0 @@ -S205607 diff --git a/test/data/__init__.py b/test/data/__init__.py index 56de9c5ee1..e69de29bb2 100644 --- a/test/data/__init__.py +++ b/test/data/__init__.py @@ -1 +0,0 @@ -S205607 From 55214778686a1e54dca1ca3d9779c951c5047b0b Mon Sep 17 00:00:00 2001 From: Nayef Ahmed Date: Tue, 21 Jul 2020 09:34:07 -0700 Subject: [PATCH 18/68] Import torchtext 2020/07/21 Summary: Import from github torchtext/master Reviewed By: zhangguanheng66 Differential Revision: D22641140 fbshipit-source-id: 8190692d059a937e25c5f93506581086f389c291 --- benchmark/experimental_vectors.py | 2 +- benchmark/experimental_vocab.py | 2 +- examples/BERT/README.rst | 152 ++++++++++ examples/BERT/data.py | 54 ++++ examples/BERT/metrics.py | 72 +++++ examples/BERT/mlm_task.py | 263 ++++++++++++++++++ examples/BERT/model.py | 175 ++++++++++++ examples/BERT/ns_task.py | 262 +++++++++++++++++ examples/BERT/qa_task.py | 213 ++++++++++++++ examples/BERT/utils.py | 58 ++++ test/common/torchtext_test_case.py | 1 + test/data/test_jit.py | 2 +- test/data/test_modules.py | 75 +++-- test/experimental/test_vectors.py | 130 +++++---- test/experimental/test_vocab.py | 114 ++++---- torchtext/__init__.py | 4 +- torchtext/csrc/vectors.cpp | 72 ++++- torchtext/csrc/vocab.cpp | 75 +++-- torchtext/data/batch.py | 2 + torchtext/data/example.py | 6 + torchtext/data/field.py | 7 +- torchtext/data/iterator.py | 3 +- torchtext/experimental/asset/get_checksum.sh | 6 +- torchtext/experimental/vectors.py | 28 +- torchtext/experimental/vocab.py | 75 +++-- torchtext/nn/__init__.py | 1 + torchtext/{ => nn}/modules/__init__.py | 0 .../{ => nn}/modules/multiheadattention.py | 65 +++-- tox.ini | 4 + 29 files changed, 1700 insertions(+), 223 deletions(-) create mode 100644 examples/BERT/README.rst create mode 100644 examples/BERT/data.py create mode 100644 examples/BERT/metrics.py create mode 100644 examples/BERT/mlm_task.py create mode 100644 examples/BERT/model.py create mode 100644 examples/BERT/ns_task.py create mode 100644 examples/BERT/qa_task.py create mode 100644 examples/BERT/utils.py create mode 100644 torchtext/nn/__init__.py rename torchtext/{ => nn}/modules/__init__.py (100%) rename torchtext/{ => nn}/modules/multiheadattention.py (77%) create mode 100644 tox.ini diff --git a/benchmark/experimental_vectors.py b/benchmark/experimental_vectors.py index 172b451db8..f7094d7d2b 100644 --- a/benchmark/experimental_vectors.py +++ b/benchmark/experimental_vectors.py @@ -16,7 +16,7 @@ def _run_benchmark_lookup(tokens, vector): train, = AG_NEWS(data_select='train') vocab = train.get_vocab() tokens = [] - for (_label, text) in train: + for (label, text) in train: for id in text.tolist(): tokens.append(vocab.itos[id]) diff --git a/benchmark/experimental_vocab.py b/benchmark/experimental_vocab.py index 622be541ad..d1106da7bb 100644 --- a/benchmark/experimental_vocab.py +++ b/benchmark/experimental_vocab.py @@ -17,7 +17,7 @@ def _run_benchmark_lookup(tokens, vocab): train, = AG_NEWS(data_select='train') vocab = train.get_vocab() tokens = [] - for (_label, text) in train: + for (label, text) in train: for id in text.tolist(): tokens.append(vocab.itos[id]) diff --git a/examples/BERT/README.rst b/examples/BERT/README.rst new file mode 100644 index 0000000000..8cf0a55281 --- /dev/null +++ b/examples/BERT/README.rst @@ -0,0 +1,152 @@ +BERT with torchtext ++++++++++ + +This example shows how to train a BERT model with PyTorch and torchtext only. Then, we fine-tune the pre-trained BERT for the question-answer task. + + +Generate pre-trained BERT +------------------------- + +Train the BERT model with masked language modeling task and next-sentence task. Run the tasks on a local GPU or CPU: + + python mlm_task.py + python ns_task.py + +or run the tasks on a SLURM powered cluster with Distributed Data Parallel (DDP): + + srun --label --ntasks-per-node=1 --time=4000 --mem-per-cpu=5120 --gres=gpu:8 --cpus-per-task 80 --nodes=1 --pty python mlm_task.py --parallel DDP --log-interval 600 --dataset BookCorpus + + srun --label --ntasks-per-node=1 --time=4000 --mem-per-cpu=5120 --gres=gpu:8 --cpus-per-task 80 --nodes=1 --pty python ns_task.py --parallel DDP --bert-model mlm_bert.pt --dataset BookCorpus + +The result ppl of mlm_task is 18.97899 for the test set. +The result loss of ns_task is 0.05446 for the test set. + +Fine-tune pre-trained BERT for question-answer task +--------------------------------------------------- + +With SQuAD dataset, the pre-trained BERT is used for question-answer task: + + python qa_task.py --bert-model ns_bert.pt --epochs 30 + +The pre-trained BERT models and vocab are available: + +* `bert_vocab.pt `_ +* `mlm_bert.pt `_ +* `ns_bert.pt `_ + +An example train/valid/test printout with the pretrained BERT model in question-answer task: + + | epoch 1 | 200/ 1055 batches | lr 5.00000 | ms/batch 746.33 | loss 3.70 | ppl 40.45 + | epoch 1 | 400/ 1055 batches | lr 5.00000 | ms/batch 746.78 | loss 3.06 | ppl 21.25 + | epoch 1 | 600/ 1055 batches | lr 5.00000 | ms/batch 746.83 | loss 2.84 | ppl 17.15 + | epoch 1 | 800/ 1055 batches | lr 5.00000 | ms/batch 746.55 | loss 2.69 | ppl 14.73 + | epoch 1 | 1000/ 1055 batches | lr 5.00000 | ms/batch 745.48 | loss 2.55 | ppl 12.85 + ----------------------------------------------------------------------------------------- + | end of epoch 1 | time: 821.25s | valid loss 2.33 | exact 40.052% | f1 52.595% + ----------------------------------------------------------------------------------------- + | epoch 2 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.17 | loss 2.33 | ppl 10.25 + | epoch 2 | 400/ 1055 batches | lr 5.00000 | ms/batch 745.52 | loss 2.28 | ppl 9.75 + | epoch 2 | 600/ 1055 batches | lr 5.00000 | ms/batch 745.50 | loss 2.24 | ppl 9.37 + | epoch 2 | 800/ 1055 batches | lr 5.00000 | ms/batch 745.10 | loss 2.22 | ppl 9.18 + | epoch 2 | 1000/ 1055 batches | lr 5.00000 | ms/batch 744.61 | loss 2.16 | ppl 8.66 + ----------------------------------------------------------------------------------------- + | end of epoch 2 | time: 820.75s | valid loss 2.12 | exact 44.632% | f1 57.965% + ----------------------------------------------------------------------------------------- + | epoch 3 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.88 | loss 2.00 | ppl 7.41 + | epoch 3 | 400/ 1055 batches | lr 5.00000 | ms/batch 746.46 | loss 1.99 | ppl 7.29 + | epoch 3 | 600/ 1055 batches | lr 5.00000 | ms/batch 745.35 | loss 1.99 | ppl 7.30 + | epoch 3 | 800/ 1055 batches | lr 5.00000 | ms/batch 746.03 | loss 1.98 | ppl 7.27 + | epoch 3 | 1000/ 1055 batches | lr 5.00000 | ms/batch 746.01 | loss 1.98 | ppl 7.26 + ----------------------------------------------------------------------------------------- + | end of epoch 3 | time: 821.98s | valid loss 1.96 | exact 48.001% | f1 61.036% + ----------------------------------------------------------------------------------------- + | epoch 4 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.72 | loss 1.82 | ppl 6.19 + | epoch 4 | 400/ 1055 batches | lr 5.00000 | ms/batch 745.86 | loss 1.84 | ppl 6.28 + | epoch 4 | 600/ 1055 batches | lr 5.00000 | ms/batch 745.63 | loss 1.85 | ppl 6.34 + | epoch 4 | 800/ 1055 batches | lr 5.00000 | ms/batch 745.59 | loss 1.82 | ppl 6.20 + | epoch 4 | 1000/ 1055 batches | lr 5.00000 | ms/batch 745.55 | loss 1.83 | ppl 6.21 + ----------------------------------------------------------------------------------------- + | end of epoch 4 | time: 821.10s | valid loss 1.95 | exact 49.149% | f1 62.040% + ----------------------------------------------------------------------------------------- + | epoch 5 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.40 | loss 1.66 | ppl 5.24 + | epoch 5 | 400/ 1055 batches | lr 5.00000 | ms/batch 756.09 | loss 1.69 | ppl 5.44 + | epoch 5 | 600/ 1055 batches | lr 5.00000 | ms/batch 769.19 | loss 1.70 | ppl 5.46 + | epoch 5 | 800/ 1055 batches | lr 5.00000 | ms/batch 764.96 | loss 1.72 | ppl 5.58 + | epoch 5 | 1000/ 1055 batches | lr 5.00000 | ms/batch 773.25 | loss 1.70 | ppl 5.49 + ----------------------------------------------------------------------------------------- + | end of epoch 5 | time: 844.20s | valid loss 1.99 | exact 49.509% | f1 61.994% + ----------------------------------------------------------------------------------------- + | epoch 6 | 200/ 1055 batches | lr 0.50000 | ms/batch 765.25 | loss 1.50 | ppl 4.49 + | epoch 6 | 400/ 1055 batches | lr 0.50000 | ms/batch 749.64 | loss 1.45 | ppl 4.25 + | epoch 6 | 600/ 1055 batches | lr 0.50000 | ms/batch 768.16 | loss 1.40 | ppl 4.06 + | epoch 6 | 800/ 1055 batches | lr 0.50000 | ms/batch 745.69 | loss 1.43 | ppl 4.18 + | epoch 6 | 1000/ 1055 batches | lr 0.50000 | ms/batch 744.90 | loss 1.40 | ppl 4.07 + ----------------------------------------------------------------------------------------- + | end of epoch 6 | time: 829.55s | valid loss 1.97 | exact 51.182% | f1 63.437% + ----------------------------------------------------------------------------------------- + | epoch 7 | 200/ 1055 batches | lr 0.50000 | ms/batch 747.73 | loss 1.36 | ppl 3.89 + | epoch 7 | 400/ 1055 batches | lr 0.50000 | ms/batch 744.50 | loss 1.37 | ppl 3.92 + | epoch 7 | 600/ 1055 batches | lr 0.50000 | ms/batch 744.20 | loss 1.35 | ppl 3.86 + | epoch 7 | 800/ 1055 batches | lr 0.50000 | ms/batch 743.85 | loss 1.36 | ppl 3.89 + | epoch 7 | 1000/ 1055 batches | lr 0.50000 | ms/batch 744.01 | loss 1.34 | ppl 3.83 + ----------------------------------------------------------------------------------------- + | end of epoch 7 | time: 820.02s | valid loss 2.01 | exact 51.507% | f1 63.885% + ----------------------------------------------------------------------------------------- + | epoch 8 | 200/ 1055 batches | lr 0.50000 | ms/batch 747.40 | loss 1.31 | ppl 3.72 + | epoch 8 | 400/ 1055 batches | lr 0.50000 | ms/batch 744.33 | loss 1.30 | ppl 3.68 + | epoch 8 | 600/ 1055 batches | lr 0.50000 | ms/batch 745.76 | loss 1.31 | ppl 3.69 + | epoch 8 | 800/ 1055 batches | lr 0.50000 | ms/batch 745.04 | loss 1.31 | ppl 3.69 + | epoch 8 | 1000/ 1055 batches | lr 0.50000 | ms/batch 745.13 | loss 1.31 | ppl 3.72 + ----------------------------------------------------------------------------------------- + | end of epoch 8 | time: 820.40s | valid loss 2.02 | exact 51.260% | f1 63.762% + ----------------------------------------------------------------------------------------- + | epoch 9 | 200/ 1055 batches | lr 0.05000 | ms/batch 748.36 | loss 1.26 | ppl 3.54 + | epoch 9 | 400/ 1055 batches | lr 0.05000 | ms/batch 744.55 | loss 1.26 | ppl 3.52 + | epoch 9 | 600/ 1055 batches | lr 0.05000 | ms/batch 745.46 | loss 1.23 | ppl 3.44 + | epoch 9 | 800/ 1055 batches | lr 0.05000 | ms/batch 745.23 | loss 1.26 | ppl 3.52 + | epoch 9 | 1000/ 1055 batches | lr 0.05000 | ms/batch 744.69 | loss 1.24 | ppl 3.47 + ----------------------------------------------------------------------------------------- + | end of epoch 9 | time: 820.41s | valid loss 2.02 | exact 51.578% | f1 63.704% + ----------------------------------------------------------------------------------------- + | epoch 10 | 200/ 1055 batches | lr 0.00500 | ms/batch 749.25 | loss 1.25 | ppl 3.50 + | epoch 10 | 400/ 1055 batches | lr 0.00500 | ms/batch 745.81 | loss 1.24 | ppl 3.47 + | epoch 10 | 600/ 1055 batches | lr 0.00500 | ms/batch 744.89 | loss 1.26 | ppl 3.51 + | epoch 10 | 800/ 1055 batches | lr 0.00500 | ms/batch 746.02 | loss 1.23 | ppl 3.42 + | epoch 10 | 1000/ 1055 batches | lr 0.00500 | ms/batch 746.61 | loss 1.25 | ppl 3.50 + ----------------------------------------------------------------------------------------- + | end of epoch 10 | time: 821.85s | valid loss 2.05 | exact 51.648% | f1 63.811% + ----------------------------------------------------------------------------------------- + ========================================================================================= + | End of training | test loss 2.05 | exact 51.337% | f1 63.645% + ========================================================================================= + +Structure of the example +======================== + +model.py +-------- + +This file defines the Transformer and MultiheadAttention models used for BERT. The embedding layer include PositionalEncoding and TokenTypeEncoding layers. MLMTask, NextSentenceTask, and QuestionAnswerTask are the models for the three tasks mentioned above. + +data.py +------- + +This file provides a few datasets required to train the BERT model and question-answer task. Please note that BookCorpus dataset is not available publicly. + + +mlm_task.py, ns_task.py, qa_task.py +----------------------------------- + +Those three files define the train/valid/test process for the tasks. + + +metrics.py +---------- + +This file provides two metrics (F1 and exact score) for question-answer task + + +utils.py +-------- + +This file provides a few utils used by the three tasks. diff --git a/examples/BERT/data.py b/examples/BERT/data.py new file mode 100644 index 0000000000..2f62459c1a --- /dev/null +++ b/examples/BERT/data.py @@ -0,0 +1,54 @@ +import glob +import torch +import logging +from torchtext.data.utils import get_tokenizer +import random +from torchtext.experimental.datasets import LanguageModelingDataset + + +################################################################### +# Set up dataset for book corpus +################################################################### +def BookCorpus(vocab, tokenizer=get_tokenizer("basic_english"), + data_select=('train', 'test', 'valid'), removed_tokens=[], + min_sentence_len=None): + + if isinstance(data_select, str): + data_select = [data_select] + if not set(data_select).issubset(set(('train', 'test', 'valid'))): + raise TypeError('data_select is not supported!') + + extracted_files = glob.glob('/datasets01/bookcorpus/021819/*/*.txt') + random.seed(1000) + random.shuffle(extracted_files) + + num_files = len(extracted_files) + _path = {'train': extracted_files[:(num_files // 20 * 17)], + 'test': extracted_files[(num_files // 20 * 17):(num_files // 20 * 18)], + 'valid': extracted_files[(num_files // 20 * 18):]} + + data = {} + for item in _path.keys(): + data[item] = [] + logging.info('Creating {} data'.format(item)) + tokens = [] + for txt_file in _path[item]: + with open(txt_file, 'r', encoding="utf8", errors='ignore') as f: + for line in f.readlines(): + _tokens = tokenizer(line.strip()) + if min_sentence_len: + if len(_tokens) >= min_sentence_len: + tokens.append([vocab.stoi[token] for token in _tokens]) + else: + tokens += [vocab.stoi[token] for token in _tokens] + data[item] = tokens + + for key in data_select: + if data[key] == []: + raise TypeError('Dataset {} is empty!'.format(key)) + if min_sentence_len: + return tuple(LanguageModelingDataset(data[d], vocab, lambda x: x, False) + for d in data_select) + else: + return tuple(LanguageModelingDataset(torch.tensor(data[d]).long(), vocab, lambda x: x, False) + for d in data_select) diff --git a/examples/BERT/metrics.py b/examples/BERT/metrics.py new file mode 100644 index 0000000000..dba20bb753 --- /dev/null +++ b/examples/BERT/metrics.py @@ -0,0 +1,72 @@ +import collections +import re +import string + + +def compute_qa_exact(ans_pred_tokens_samples): + + ''' + Input: ans_pred_tokens_samples: [([ans1_tokens_candidate1, ans1_tokens_candidate2], pred1_tokens), + ([ans2_tokens_candidate1, ans2_tokens_candidate2], pred2_tokens), + ... + ([ansn_tokens_candidate1, ansn_tokens_candidate2], predn_tokens)] + ans1_tokens_candidate1 = ['this', 'is', 'an', 'sample', 'example'] + Output: exact score of the samples + ''' + + def normalize_txt(text): + # lower case + text = text.lower() + + # remove punc + exclude = set(string.punctuation) + text = "".join(ch for ch in text if ch not in exclude) + + # remove articles + regex = re.compile(r"\b(a|an|the)\b", re.UNICODE) + text = re.sub(regex, " ", text) + + # white space fix + return " ".join(text.split()) + + exact_scores = [] + for (ans_tokens, pred_tokens) in ans_pred_tokens_samples: + pred_str = " ".join(pred_tokens) + candidate_score = [] + for item in ans_tokens: + ans_str = " ".join(item) + candidate_score.append(int(normalize_txt(ans_str) == normalize_txt(pred_str))) + exact_scores.append(max(candidate_score)) + return 100.0 * sum(exact_scores) / len(exact_scores) + + +def compute_qa_f1(ans_pred_tokens_samples): + + ''' + Input: ans_pred_tokens_samples: [([ans1_tokens_candidate1, ans1_tokens_candidate2], pred1_tokens), + ([ans2_tokens_candidate1, ans2_tokens_candidate2], pred2_tokens), + ... + ([ansn_tokens_candidate1, ansn_tokens_candidate2], predn_tokens)] + ans1_tokens_candidate1 = ['this', 'is', 'an', 'sample', 'example'] + Output: f1 score of the samples + ''' + def sample_f1(ans_tokens, pred_tokens): + common = collections.Counter(ans_tokens) & collections.Counter(pred_tokens) + num_same = sum(common.values()) + if len(ans_tokens) == 0 or len(pred_tokens) == 0: + # If either is no-answer, then F1 is 1 if they agree, 0 otherwise + return int(ans_tokens == pred_tokens) + if num_same == 0: + return 0 + precision = 1.0 * num_same / len(pred_tokens) + recall = 1.0 * num_same / len(ans_tokens) + f1 = (2 * precision * recall) / (precision + recall) + return f1 + + f1_scores = [] + for (ans_tokens, pred_tokens) in ans_pred_tokens_samples: + candidate_score = [] + for item in ans_tokens: + candidate_score.append(sample_f1(item, pred_tokens)) + f1_scores.append(max(candidate_score)) + return 100.0 * sum(f1_scores) / len(f1_scores) diff --git a/examples/BERT/mlm_task.py b/examples/BERT/mlm_task.py new file mode 100644 index 0000000000..d0623a9607 --- /dev/null +++ b/examples/BERT/mlm_task.py @@ -0,0 +1,263 @@ +import argparse +import time +import math +import torch +import torch.nn as nn +from model import MLMTask +from utils import run_demo, run_ddp, wrap_up +import torch.distributed as dist +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.utils.data import DataLoader + + +def collate_batch(batch_data, args, mask_id, cls_id): + batch_data = torch.tensor(batch_data).long().view(args.batch_size, -1).t().contiguous() + # Generate masks with args.mask_frac + data_len = batch_data.size(0) + ones_num = int(data_len * args.mask_frac) + zeros_num = data_len - ones_num + lm_mask = torch.cat([torch.zeros(zeros_num), torch.ones(ones_num)]) + lm_mask = lm_mask[torch.randperm(data_len)] + batch_data = torch.cat((torch.tensor([[cls_id] * batch_data.size(1)]).long(), batch_data)) + lm_mask = torch.cat((torch.tensor([0.0]), lm_mask)) + + targets = torch.stack([batch_data[i] for i in range(lm_mask.size(0)) if lm_mask[i]]).view(-1) + batch_data = batch_data.masked_fill(lm_mask.bool().unsqueeze(1), mask_id) + return batch_data, lm_mask, targets + + +def process_raw_data(raw_data, args): + _num = raw_data.size(0) // (args.batch_size * args.bptt) + raw_data = raw_data[:(_num * args.batch_size * args.bptt)] + return raw_data + + +def evaluate(data_source, model, vocab, ntokens, criterion, args, device): + # Turn on evaluation mode which disables dropout. + model.eval() + total_loss = 0. + mask_id = vocab.stoi[''] + cls_id = vocab.stoi[''] + dataloader = DataLoader(data_source, batch_size=args.batch_size * args.bptt, + shuffle=False, collate_fn=lambda b: collate_batch(b, args, mask_id, cls_id)) + with torch.no_grad(): + for batch, (data, lm_mask, targets) in enumerate(dataloader): + if args.parallel == 'DDP': + data = data.to(device[0]) + targets = targets.to(device[0]) + else: + data = data.to(device) + targets = targets.to(device) + data = data.transpose(0, 1) # Wrap up by DDP or DataParallel + output = model(data) + output = torch.stack([output[i] for i in range(lm_mask.size(0)) if lm_mask[i]]) + output_flat = output.view(-1, ntokens) + total_loss += criterion(output_flat, targets).item() + return total_loss / ((len(data_source) - 1) / args.bptt / args.batch_size) + + +def train(model, vocab, train_loss_log, train_data, + optimizer, criterion, ntokens, epoch, scheduler, args, device, rank=None): + model.train() + total_loss = 0. + start_time = time.time() + mask_id = vocab.stoi[''] + cls_id = vocab.stoi[''] + train_loss_log.append(0.0) + dataloader = DataLoader(train_data, batch_size=args.batch_size * args.bptt, + shuffle=False, collate_fn=lambda b: collate_batch(b, args, mask_id, cls_id)) + + for batch, (data, lm_mask, targets) in enumerate(dataloader): + optimizer.zero_grad() + if args.parallel == 'DDP': + data = data.to(device[0]) + targets = targets.to(device[0]) + else: + data = data.to(device) + targets = targets.to(device) + data = data.transpose(0, 1) # Wrap up by DDP or DataParallel + output = model(data) + output = torch.stack([output[i] for i in range(lm_mask.size(0)) if lm_mask[i]]) + loss = criterion(output.view(-1, ntokens), targets) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip) + optimizer.step() + total_loss += loss.item() + if batch % args.log_interval == 0 and batch > 0: + cur_loss = total_loss / args.log_interval + elapsed = time.time() - start_time + if (rank is None) or rank == 0: + train_loss_log[-1] = cur_loss + print('| epoch {:3d} | {:5d}/{:5d} batches | lr {:05.5f} | ms/batch {:5.2f} | ' + 'loss {:5.2f} | ppl {:8.2f}'.format(epoch, batch, + len(train_data) // (args.bptt * args.batch_size), + scheduler.get_last_lr()[0], + elapsed * 1000 / args.log_interval, + cur_loss, math.exp(cur_loss))) + total_loss = 0 + start_time = time.time() + + +def run_main(args, rank=None): + torch.manual_seed(args.seed) + if args.parallel == 'DDP': + n = torch.cuda.device_count() // args.world_size + device = list(range(rank * n, (rank + 1) * n)) + else: + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + + import torchtext + if args.dataset == 'WikiText103': + from torchtext.experimental.datasets import WikiText103 as WLMDataset + elif args.dataset == 'WikiText2': + from torchtext.experimental.datasets import WikiText2 as WLMDataset + elif args.dataset == 'WMTNewsCrawl': + from data import WMTNewsCrawl as WLMDataset + elif args.dataset == 'EnWik9': + from torchtext.datasets import EnWik9 + elif args.dataset == 'BookCorpus': + from data import BookCorpus + else: + print("dataset for MLM task is not supported") + + try: + vocab = torch.load(args.save_vocab) + except: + train_dataset, test_dataset, valid_dataset = WLMDataset() + old_vocab = train_dataset.vocab + vocab = torchtext.vocab.Vocab(counter=old_vocab.freqs, + specials=['', '', '']) + with open(args.save_vocab, 'wb') as f: + torch.save(vocab, f) + + if args.dataset == 'WikiText103' or args.dataset == 'WikiText2': + train_dataset, test_dataset, valid_dataset = WLMDataset(vocab=vocab) + elif args.dataset == 'WMTNewsCrawl': + from torchtext.experimental.datasets import WikiText2 + test_dataset, valid_dataset = WikiText2(vocab=vocab, data_select=('test', 'valid')) + train_dataset, = WLMDataset(vocab=vocab, data_select='train') + elif args.dataset == 'EnWik9': + enwik9 = EnWik9() + idx1, idx2 = int(len(enwik9) * 0.8), int(len(enwik9) * 0.9) + train_data = torch.tensor([vocab.stoi[_id] + for _id in enwik9[0:idx1]]).long() + val_data = torch.tensor([vocab.stoi[_id] + for _id in enwik9[idx1:idx2]]).long() + test_data = torch.tensor([vocab.stoi[_id] + for _id in enwik9[idx2:]]).long() + from torchtext.experimental.datasets import LanguageModelingDataset + train_dataset = LanguageModelingDataset(train_data, vocab) + valid_dataset = LanguageModelingDataset(val_data, vocab) + test_dataset = LanguageModelingDataset(test_data, vocab) + elif args.dataset == 'BookCorpus': + train_dataset, test_dataset, valid_dataset = BookCorpus(vocab) + + train_data = process_raw_data(train_dataset.data, args) + if rank is not None: + # Chunk training data by rank for different gpus + chunk_len = len(train_data) // args.world_size + train_data = train_data[(rank * chunk_len):((rank + 1) * chunk_len)] + val_data = process_raw_data(valid_dataset.data, args) + test_data = process_raw_data(test_dataset.data, args) + + ntokens = len(train_dataset.get_vocab()) + if args.checkpoint != 'None': + model = torch.load(args.checkpoint) + else: + model = MLMTask(ntokens, args.emsize, args.nhead, args.nhid, args.nlayers, args.dropout) + if args.parallel == 'DDP': + model = model.to(device[0]) + model = DDP(model, device_ids=device) + else: + model = model.to(device) + criterion = nn.CrossEntropyLoss() + optimizer = torch.optim.SGD(model.parameters(), lr=args.lr) + scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.1) + best_val_loss = None + train_loss_log, val_loss_log = [], [] + + for epoch in range(1, args.epochs + 1): + epoch_start_time = time.time() + train(model, train_dataset.vocab, train_loss_log, train_data, + optimizer, criterion, ntokens, epoch, scheduler, args, device, rank) + val_loss = evaluate(val_data, model, train_dataset.vocab, ntokens, criterion, args, device) + if (rank is None) or (rank == 0): + val_loss_log.append(val_loss) + print('-' * 89) + print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | ' + 'valid ppl {:8.2f}'.format(epoch, (time.time() - epoch_start_time), + val_loss, math.exp(val_loss))) + print('-' * 89) + if not best_val_loss or val_loss < best_val_loss: + if rank is None: + with open(args.save, 'wb') as f: + torch.save(model, f) + elif rank == 0: + with open(args.save, 'wb') as f: + torch.save(model.state_dict(), f) + best_val_loss = val_loss + else: + scheduler.step() + if args.parallel == 'DDP': + dist.barrier() + rank0_devices = [x - rank * len(device) for x in device] + device_pairs = zip(rank0_devices, device) + map_location = {'cuda:%d' % x: 'cuda:%d' % y for x, y in device_pairs} + model.load_state_dict( + torch.load(args.save, map_location=map_location)) + test_loss = evaluate(test_data, model, train_dataset.vocab, ntokens, criterion, args, device) + if rank == 0: + wrap_up(train_loss_log, val_loss_log, test_loss, args, model.module, 'mlm_loss.txt', 'full_mlm_model.pt') + else: + with open(args.save, 'rb') as f: + model = torch.load(f) + test_loss = evaluate(test_data, model, train_dataset.vocab, ntokens, criterion, args, device) + wrap_up(train_loss_log, val_loss_log, test_loss, args, model, 'mlm_loss.txt', 'full_mlm_model.pt') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='PyTorch Wikitext-2 Transformer Language Model') + parser.add_argument('--emsize', type=int, default=768, + help='size of word embeddings') + parser.add_argument('--nhid', type=int, default=3072, + help='number of hidden units per layer') + parser.add_argument('--nlayers', type=int, default=12, + help='number of layers') + parser.add_argument('--nhead', type=int, default=12, + help='the number of heads in the encoder/decoder of the transformer model') + parser.add_argument('--lr', type=float, default=6, + help='initial learning rate') + parser.add_argument('--clip', type=float, default=0.1, + help='gradient clipping') + parser.add_argument('--epochs', type=int, default=8, + help='upper epoch limit') + parser.add_argument('--batch_size', type=int, default=32, metavar='N', + help='batch size') + parser.add_argument('--bptt', type=int, default=128, + help='sequence length') + parser.add_argument('--dropout', type=float, default=0.2, + help='dropout applied to layers (0 = no dropout)') + parser.add_argument('--seed', type=int, default=5431916812, + help='random seed') + parser.add_argument('--log-interval', type=int, default=10, metavar='N', + help='report interval') + parser.add_argument('--checkpoint', type=str, default='None', + help='path to load the checkpoint') + parser.add_argument('--save', type=str, default='mlm_bert.pt', + help='path to save the final model') + parser.add_argument('--save-vocab', type=str, default='torchtext_bert_vocab.pt', + help='path to save the vocab') + parser.add_argument('--mask_frac', type=float, default=0.15, + help='the fraction of masked tokens') + parser.add_argument('--dataset', type=str, default='WikiText2', + help='dataset used for MLM task') + parser.add_argument('--parallel', type=str, default='None', + help='Use DataParallel to train model') + parser.add_argument('--world_size', type=int, default=8, + help='the world size to initiate DPP') + args = parser.parse_args() + + if args.parallel == 'DDP': + run_demo(run_ddp, run_main, args) + else: + run_main(args) diff --git a/examples/BERT/model.py b/examples/BERT/model.py new file mode 100644 index 0000000000..316841c751 --- /dev/null +++ b/examples/BERT/model.py @@ -0,0 +1,175 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch.nn import Linear, Dropout, LayerNorm, TransformerEncoder +from torchtext.nn import MultiheadAttentionContainer, InProjContainer, ScaledDotProduct + + +class PositionalEncoding(nn.Module): + def __init__(self, d_model, max_len=5000): + super(PositionalEncoding, self).__init__() + self.pos_embedding = nn.Embedding(max_len, d_model) + + def forward(self, x): + S, N = x.size() + pos = torch.arange(S, + dtype=torch.long, + device=x.device).unsqueeze(0).expand((N, S)).t() + return self.pos_embedding(pos) + + +class TokenTypeEncoding(nn.Module): + def __init__(self, type_token_num, d_model): + super(TokenTypeEncoding, self).__init__() + self.token_type_embeddings = nn.Embedding(type_token_num, d_model) + + def forward(self, seq_input, token_type_input): + S, N = seq_input.size() + if token_type_input is None: + token_type_input = torch.zeros((S, N), + dtype=torch.long, + device=seq_input.device) + return self.token_type_embeddings(token_type_input) + + +class BertEmbedding(nn.Module): + def __init__(self, ntoken, ninp, dropout=0.5): + super(BertEmbedding, self).__init__() + self.ninp = ninp + self.ntoken = ntoken + self.pos_embed = PositionalEncoding(ninp) + self.embed = nn.Embedding(ntoken, ninp) + self.tok_type_embed = TokenTypeEncoding(2, ninp) # Two sentence type + self.norm = LayerNorm(ninp) + self.dropout = Dropout(dropout) + + def forward(self, src, token_type_input): + src = self.embed(src) + self.pos_embed(src) \ + + self.tok_type_embed(src, token_type_input) + return self.dropout(self.norm(src)) + + +class TransformerEncoderLayer(nn.Module): + def __init__(self, d_model, nhead, dim_feedforward=2048, + dropout=0.1, activation="gelu"): + super(TransformerEncoderLayer, self).__init__() + in_proj_container = InProjContainer(Linear(d_model, d_model), + Linear(d_model, d_model), + Linear(d_model, d_model)) + self.mha = MultiheadAttentionContainer(nhead, in_proj_container, + ScaledDotProduct(), Linear(d_model, d_model)) + self.linear1 = Linear(d_model, dim_feedforward) + self.dropout = Dropout(dropout) + self.linear2 = Linear(dim_feedforward, d_model) + + self.norm1 = LayerNorm(d_model) + self.norm2 = LayerNorm(d_model) + self.dropout1 = Dropout(dropout) + self.dropout2 = Dropout(dropout) + + if activation == "relu": + self.activation = F.relu + elif activation == "gelu": + self.activation = F.gelu + else: + raise RuntimeError("only relu/gelu are supported, not {}".format(activation)) + + def init_weights(self): + self.mha.in_proj_container.query_proj.init_weights() + self.mha.in_proj_container.key_proj.init_weights() + self.mha.in_proj_container.value_proj.init_weights() + self.mha.out_proj.init_weights() + self.linear1.weight.data.normal_(mean=0.0, std=0.02) + self.linear2.weight.data.normal_(mean=0.0, std=0.02) + self.norm1.bias.data.zero_() + self.norm1.weight.data.fill_(1.0) + self.norm2.bias.data.zero_() + self.norm2.weight.data.fill_(1.0) + + def forward(self, src, src_mask=None, src_key_padding_mask=None): + attn_output, attn_output_weights = self.mha(src, src, src, attn_mask=src_mask) + src = src + self.dropout1(attn_output) + src = self.norm1(src) + src2 = self.linear2(self.dropout(self.activation(self.linear1(src)))) + src = src + self.dropout2(src2) + src = self.norm2(src) + return src + + +class BertModel(nn.Module): + """Contain a transformer encoder.""" + + def __init__(self, ntoken, ninp, nhead, nhid, nlayers, dropout=0.5): + super(BertModel, self).__init__() + self.model_type = 'Transformer' + self.bert_embed = BertEmbedding(ntoken, ninp) + encoder_layers = TransformerEncoderLayer(ninp, nhead, nhid, dropout) + self.transformer_encoder = TransformerEncoder(encoder_layers, nlayers) + self.ninp = ninp + + def forward(self, src, token_type_input): + src = self.bert_embed(src, token_type_input) + output = self.transformer_encoder(src) + return output + + +class MLMTask(nn.Module): + """Contain a transformer encoder plus MLM head.""" + + def __init__(self, ntoken, ninp, nhead, nhid, nlayers, dropout=0.5): + super(MLMTask, self).__init__() + self.bert_model = BertModel(ntoken, ninp, nhead, nhid, nlayers, dropout=0.5) + self.mlm_span = Linear(ninp, ninp) + self.activation = F.gelu + self.norm_layer = LayerNorm(ninp, eps=1e-12) + self.mlm_head = Linear(ninp, ntoken) + + def forward(self, src, token_type_input=None): + src = src.transpose(0, 1) # Wrap up by nn.DataParallel + output = self.bert_model(src, token_type_input) + output = self.mlm_span(output) + output = self.activation(output) + output = self.norm_layer(output) + output = self.mlm_head(output) + return output + + +class NextSentenceTask(nn.Module): + """Contain a pretrain BERT model and a linear layer.""" + + def __init__(self, bert_model): + super(NextSentenceTask, self).__init__() + self.bert_model = bert_model + self.linear_layer = Linear(bert_model.ninp, + bert_model.ninp) + self.ns_span = Linear(bert_model.ninp, 2) + self.activation = nn.Tanh() + + def forward(self, src, token_type_input): + src = src.transpose(0, 1) # Wrap up by nn.DataParallel + output = self.bert_model(src, token_type_input) + # Send the first <'cls'> seq to a classifier + output = self.activation(self.linear_layer(output[0])) + output = self.ns_span(output) + return output + + +class QuestionAnswerTask(nn.Module): + """Contain a pretrain BERT model and a linear layer.""" + + def __init__(self, bert_model): + super(QuestionAnswerTask, self).__init__() + self.bert_model = bert_model + self.activation = F.gelu + self.qa_span = Linear(bert_model.ninp, 2) + + def forward(self, src, token_type_input): + output = self.bert_model(src, token_type_input) + # transpose output (S, N, E) to (N, S, E) + output = output.transpose(0, 1) + output = self.activation(output) + pos_output = self.qa_span(output) + start_pos, end_pos = pos_output.split(1, dim=-1) + start_pos = start_pos.squeeze(-1) + end_pos = end_pos.squeeze(-1) + return start_pos, end_pos diff --git a/examples/BERT/ns_task.py b/examples/BERT/ns_task.py new file mode 100644 index 0000000000..062ebc343f --- /dev/null +++ b/examples/BERT/ns_task.py @@ -0,0 +1,262 @@ +import argparse +import time +import math +import torch +import torch.nn as nn +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.utils.data import DataLoader +from model import NextSentenceTask, BertModel +from utils import run_demo, run_ddp, wrap_up + + +def process_raw_data(whole_data, args): + processed_data = [] + for _idx in range(len(whole_data)): + item = whole_data[_idx] + if isinstance(item, list): + item = torch.tensor(item) + if len(item) > 1: + # idx to split the text into two sentencd + split_idx = torch.randint(1, len(item), size=(1, 1)).item() + # Index 2 means same sentence label. Initial true int(1) + processed_data.append([item[:split_idx], item[split_idx:], 1]) + # Random shuffle data to have args.frac_ns next sentence set up + shuffle_idx1 = torch.randperm(len(processed_data)) + shuffle_idx2 = torch.randperm(len(processed_data)) + num_shuffle = int(len(processed_data) * args.frac_ns) + shuffle_zip = list(zip(shuffle_idx1, shuffle_idx2))[:num_shuffle] + for (i, j) in shuffle_zip: + processed_data[i][1] = processed_data[j][0] + processed_data[i][2] = int(0) # Switch same sentence label to false 0 + return processed_data + + +def collate_batch(batch, args, cls_id, sep_id, pad_id): + # Fix sequence length to args.bptt with padding or trim + seq_list = [] + tok_type = [] + same_sentence_labels = [] + for item in batch: + qa_item = torch.cat([item[0], torch.tensor([sep_id]).long(), item[1], torch.tensor([sep_id]).long()]) + if qa_item.size(0) > args.bptt: + qa_item = qa_item[:args.bptt] + elif qa_item.size(0) < args.bptt: + qa_item = torch.cat((qa_item, + torch.tensor([pad_id] * (args.bptt - + qa_item.size(0))))) + seq_list.append(qa_item) + _tok_tp = torch.ones((qa_item.size(0))) + _idx = min(len(item[0]) + 1, args.bptt) + _tok_tp[:_idx] = 0.0 + tok_type.append(_tok_tp) + same_sentence_labels.append(item[2]) + seq_input = torch.stack(seq_list).long().t().contiguous() + seq_input = torch.cat((torch.tensor([[cls_id] * seq_input.size(1)]).long(), seq_input)) + tok_type = torch.stack(tok_type).long().t().contiguous() + tok_type = torch.cat((torch.tensor([[0] * tok_type.size(1)]).long(), tok_type)) + return seq_input, tok_type, torch.tensor(same_sentence_labels).long().contiguous() + + +def evaluate(data_source, model, device, criterion, cls_id, sep_id, pad_id, args): + model.eval() + total_loss = 0. + batch_size = args.batch_size + dataloader = DataLoader(data_source, batch_size=batch_size, shuffle=True, + collate_fn=lambda b: collate_batch(b, args, cls_id, sep_id, pad_id)) + with torch.no_grad(): + for idx, (seq_input, tok_type, target_ns_labels) in enumerate(dataloader): + if args.parallel == 'DDP': + seq_input = seq_input.to(device[0]) + tok_type = tok_type.to(device[0]) + target_ns_labels = target_ns_labels.to(device[0]) + else: + seq_input = seq_input.to(device) + tok_type = tok_type.to(device) + target_ns_labels = target_ns_labels.to(device) + seq_input = seq_input.transpose(0, 1) # Wrap up by DDP or DataParallel + ns_labels = model(seq_input, token_type_input=tok_type) + loss = criterion(ns_labels, target_ns_labels) + total_loss += loss.item() + return total_loss / (len(data_source) // batch_size) + + +def train(train_dataset, model, train_loss_log, device, optimizer, criterion, + epoch, scheduler, cls_id, sep_id, pad_id, args, rank=None): + model.train() + total_loss = 0. + start_time = time.time() + batch_size = args.batch_size + dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, + collate_fn=lambda b: collate_batch(b, args, cls_id, sep_id, pad_id)) + train_loss_log.append(0.0) + for idx, (seq_input, tok_type, target_ns_labels) in enumerate(dataloader): + if args.parallel == 'DDP': + seq_input = seq_input.to(device[0]) + tok_type = tok_type.to(device[0]) + target_ns_labels = target_ns_labels.to(device[0]) + else: + seq_input = seq_input.to(device) + tok_type = tok_type.to(device) + target_ns_labels = target_ns_labels.to(device) + optimizer.zero_grad() + seq_input = seq_input.transpose(0, 1) # Wrap up by DDP or DataParallel + ns_labels = model(seq_input, token_type_input=tok_type) + loss = criterion(ns_labels, target_ns_labels) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip) + optimizer.step() + total_loss += loss.item() + if idx % args.log_interval == 0 and idx > 0: + cur_loss = total_loss / args.log_interval + elapsed = time.time() - start_time + if (rank is None) or rank == 0: + train_loss_log[-1] = cur_loss + print('| epoch {:3d} | {:5d}/{:5d} batches | lr {:05.5f} | ' + 'ms/batch {:5.2f} | ' + 'loss {:8.5f} | ppl {:5.2f}'.format(epoch, idx, + len(train_dataset) // batch_size, + scheduler.get_last_lr()[0], + elapsed * 1000 / args.log_interval, + cur_loss, math.exp(cur_loss))) + total_loss = 0 + start_time = time.time() + + +def run_main(args, rank=None): + # Set the random seed manually for reproducibility. + torch.manual_seed(args.seed) + if args.parallel == 'DDP': + n = torch.cuda.device_count() // args.world_size + device = list(range(rank * n, (rank + 1) * n)) + else: + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + vocab = torch.load(args.save_vocab) + cls_id = vocab.stoi[''] + pad_id = vocab.stoi[''] + sep_id = vocab.stoi[''] + + if args.dataset == 'WikiText103': + from torchtext.experimental.datasets import WikiText103 + train_dataset, valid_dataset, test_dataset = WikiText103(vocab=vocab, + single_line=False) + elif args.dataset == 'BookCorpus': + from data import BookCorpus + train_dataset, test_dataset, valid_dataset = BookCorpus(vocab, min_sentence_len=60) + + if rank is not None: + chunk_len = len(train_dataset.data) // args.world_size + train_dataset.data = train_dataset.data[(rank * chunk_len):((rank + 1) * chunk_len)] + + if args.checkpoint != 'None': + model = torch.load(args.checkpoint) + else: + pretrained_bert = BertModel(len(vocab), args.emsize, args.nhead, args.nhid, args.nlayers, args.dropout) + pretrained_bert.load_state_dict(torch.load(args.bert_model)) + model = NextSentenceTask(pretrained_bert) + + if args.parallel == 'DDP': + model = model.to(device[0]) + model = DDP(model, device_ids=device) + else: + model = model.to(device) + criterion = nn.CrossEntropyLoss() + optimizer = torch.optim.SGD(model.parameters(), lr=args.lr) + scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.1) + best_val_loss = None + train_loss_log, val_loss_log = [], [] + + for epoch in range(1, args.epochs + 1): + epoch_start_time = time.time() + train(process_raw_data(train_dataset, args), model, train_loss_log, device, optimizer, + criterion, epoch, scheduler, cls_id, sep_id, pad_id, args, rank) + val_loss = evaluate(process_raw_data(valid_dataset, args), model, device, criterion, + cls_id, sep_id, pad_id, args) + val_loss_log.append(val_loss) + + if (rank is None) or (rank == 0): + print('-' * 89) + print('| end of epoch {:3d} | time: {:5.2f}s ' + '| valid loss {:8.5f} | '.format(epoch, + (time.time() - epoch_start_time), + val_loss)) + print('-' * 89) + if not best_val_loss or val_loss < best_val_loss: + if rank is None: + with open(args.save, 'wb') as f: + torch.save(model, f) + elif rank == 0: + with open(args.save, 'wb') as f: + torch.save(model.state_dict(), f) + best_val_loss = val_loss + else: + scheduler.step() + if args.parallel == 'DDP': + rank0_devices = [x - rank * len(device) for x in device] + device_pairs = zip(rank0_devices, device) + map_location = {'cuda:%d' % x: 'cuda:%d' % y for x, y in device_pairs} + model.load_state_dict(torch.load(args.save, map_location=map_location)) + test_loss = evaluate(process_raw_data(test_dataset, args), model, device, criterion, + cls_id, sep_id, pad_id, args) + if rank == 0: + wrap_up(train_loss_log, val_loss_log, test_loss, args, model.module, 'ns_loss.txt', 'ns_model.pt') + else: + with open(args.save, 'rb') as f: + model = torch.load(f) + + test_loss = evaluate(process_raw_data(test_dataset, args), model, device, criterion, + cls_id, sep_id, pad_id, args) + wrap_up(train_loss_log, val_loss_log, test_loss, args, model, 'ns_loss.txt', 'ns_model.pt') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Question-Answer fine-tuning task') + parser.add_argument('--dataset', type=str, default='WikiText103', + help='dataset used for next sentence task') + parser.add_argument('--lr', type=float, default=0.25, + help='initial learning rate') + parser.add_argument('--clip', type=float, default=0.1, + help='gradient clipping') + parser.add_argument('--epochs', type=int, default=5, + help='upper epoch limit') + parser.add_argument('--batch_size', type=int, default=24, metavar='N', + help='batch size') + parser.add_argument('--bptt', type=int, default=128, + help='max. sequence length for the next-sentence pair') + parser.add_argument('--min_sentence_len', type=int, default=60, + help='min. sequence length for the raw text tokens') + parser.add_argument('--seed', type=int, default=312216194, + help='random seed') + parser.add_argument('--cuda', action='store_true', + help='use CUDA') + parser.add_argument('--log-interval', type=int, default=600, metavar='N', + help='report interval') + parser.add_argument('--checkpoint', type=str, default='None', + help='path to load the checkpoint') + parser.add_argument('--save', type=str, default='ns_bert.pt', + help='path to save the bert model') + parser.add_argument('--save-vocab', type=str, default='torchtext_bert_vocab.pt', + help='path to save the vocab') + parser.add_argument('--bert-model', type=str, default='mlm_bert.pt', + help='path to save the pretrained bert') + parser.add_argument('--frac_ns', type=float, default=0.5, + help='fraction of not next sentence') + parser.add_argument('--parallel', type=str, default='None', + help='Use DataParallel/DDP to train model') + parser.add_argument('--world_size', type=int, default=8, + help='the world size to initiate DPP') + parser.add_argument('--emsize', type=int, default=768, + help='size of word embeddings') + parser.add_argument('--nhid', type=int, default=3072, + help='number of hidden units per layer') + parser.add_argument('--nlayers', type=int, default=12, + help='number of layers') + parser.add_argument('--nhead', type=int, default=12, + help='the number of heads in the encoder/decoder of the transformer model') + parser.add_argument('--dropout', type=float, default=0.2, + help='dropout applied to layers (0 = no dropout)') + args = parser.parse_args() + + if args.parallel == 'DDP': + run_demo(run_ddp, run_main, args) + else: + run_main(args) diff --git a/examples/BERT/qa_task.py b/examples/BERT/qa_task.py new file mode 100644 index 0000000000..a92f67be05 --- /dev/null +++ b/examples/BERT/qa_task.py @@ -0,0 +1,213 @@ +import argparse +import time +import math +import torch +import torch.nn as nn +from torch.utils.data import DataLoader +import torchtext +from torchtext.experimental.datasets import SQuAD1 +from model import QuestionAnswerTask +from metrics import compute_qa_exact, compute_qa_f1 +from utils import print_loss_log +from model import BertModel + + +def process_raw_data(data): + _data = [] + for item in data: + right_length = True + for _idx in range(len(item['ans_pos'])): + if item['ans_pos'][_idx][1] + item['question'].size(0) + 2 >= args.bptt: + right_length = False + if right_length: + _data.append(item) + return _data + + +def collate_batch(batch): + seq_list = [] + ans_pos_list = [] + tok_type = [] + for item in batch: + qa_item = torch.cat((torch.tensor([cls_id]), item['question'], torch.tensor([sep_id]), + item['context'], torch.tensor([sep_id]))) + if qa_item.size(0) > args.bptt: + qa_item = qa_item[:args.bptt] + elif qa_item.size(0) < args.bptt: + qa_item = torch.cat((qa_item, + torch.tensor([pad_id] * (args.bptt - + qa_item.size(0))))) + seq_list.append(qa_item) + pos_list = [pos + item['question'].size(0) + 2 for pos in item['ans_pos']] # 1 for sep and 1 for cls + ans_pos_list.append(pos_list) + tok_type.append(torch.cat((torch.zeros((item['question'].size(0) + 2)), + torch.ones((args.bptt - + item['question'].size(0) - 2))))) + _ans_pos_list = [] + for pos in zip(*ans_pos_list): + _ans_pos_list.append(torch.stack(list(pos))) + return torch.stack(seq_list).long().t().contiguous().to(device), \ + _ans_pos_list, \ + torch.stack(tok_type).long().t().contiguous().to(device) + + +def evaluate(data_source, vocab): + model.eval() + total_loss = 0. + batch_size = args.batch_size + dataloader = DataLoader(data_source, batch_size=batch_size, shuffle=True, + collate_fn=collate_batch) + ans_pred_tokens_samples = [] + with torch.no_grad(): + for idx, (seq_input, ans_pos_list, tok_type) in enumerate(dataloader): + start_pos, end_pos = model(seq_input, token_type_input=tok_type) + target_start_pos, target_end_pos = [], [] + for item in ans_pos_list: + _target_start_pos, _target_end_pos = item.to(device).split(1, dim=-1) + target_start_pos.append(_target_start_pos.squeeze(-1)) + target_end_pos.append(_target_end_pos.squeeze(-1)) + loss = (criterion(start_pos, target_start_pos[0]) + + criterion(end_pos, target_end_pos[0])) / 2 + total_loss += loss.item() + start_pos = nn.functional.softmax(start_pos, dim=1).argmax(1) + end_pos = nn.functional.softmax(end_pos, dim=1).argmax(1) + seq_input = seq_input.transpose(0, 1) # convert from (S, N) to (N, S) + for num in range(0, seq_input.size(0)): + if int(start_pos[num]) > int(end_pos[num]): + continue # start pos is in front of end pos + ans_tokens = [] + for _idx in range(len(target_end_pos)): + ans_tokens.append([vocab.itos[int(seq_input[num][i])] + for i in range(target_start_pos[_idx][num], + target_end_pos[_idx][num] + 1)]) + pred_tokens = [vocab.itos[int(seq_input[num][i])] + for i in range(start_pos[num], + end_pos[num] + 1)] + ans_pred_tokens_samples.append((ans_tokens, pred_tokens)) + return total_loss / (len(data_source) // batch_size), \ + compute_qa_exact(ans_pred_tokens_samples), \ + compute_qa_f1(ans_pred_tokens_samples) + + +def train(): + model.train() + total_loss = 0. + start_time = time.time() + batch_size = args.batch_size + dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, + collate_fn=collate_batch) + train_loss_log.append(0.0) + for idx, (seq_input, ans_pos, tok_type) in enumerate(dataloader): + optimizer.zero_grad() + start_pos, end_pos = model(seq_input, token_type_input=tok_type) + target_start_pos, target_end_pos = ans_pos[0].to(device).split(1, dim=-1) + target_start_pos = target_start_pos.squeeze(-1) + target_end_pos = target_end_pos.squeeze(-1) + loss = (criterion(start_pos, target_start_pos) + criterion(end_pos, target_end_pos)) / 2 + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip) + optimizer.step() + total_loss += loss.item() + if idx % args.log_interval == 0 and idx > 0: + cur_loss = total_loss / args.log_interval + train_loss_log[-1] = cur_loss + elapsed = time.time() - start_time + print('| epoch {:3d} | {:5d}/{:5d} batches | lr {:05.5f} | ' + 'ms/batch {:5.2f} | ' + 'loss {:5.2f} | ppl {:8.2f}'.format(epoch, idx, + len(train_dataset) // batch_size, + scheduler.get_last_lr()[0], + elapsed * 1000 / args.log_interval, + cur_loss, math.exp(cur_loss))) + total_loss = 0 + start_time = time.time() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Question-Answer fine-tuning task') + parser.add_argument('--lr', type=float, default=5.0, + help='initial learning rate') + parser.add_argument('--clip', type=float, default=0.1, + help='gradient clipping') + parser.add_argument('--epochs', type=int, default=2, + help='upper epoch limit') + parser.add_argument('--batch_size', type=int, default=72, metavar='N', + help='batch size') + parser.add_argument('--bptt', type=int, default=128, + help='max. sequence length for context + question') + parser.add_argument('--seed', type=int, default=21192391, + help='random seed') + parser.add_argument('--log-interval', type=int, default=200, metavar='N', + help='report interval') + parser.add_argument('--save', type=str, default='qa_model.pt', + help='path to save the final bert model') + parser.add_argument('--save-vocab', type=str, default='torchtext_bert_vocab.pt', + help='path to save the vocab') + parser.add_argument('--bert-model', type=str, default='ns_bert.pt', + help='path to save the pretrained bert') + parser.add_argument('--emsize', type=int, default=768, + help='size of word embeddings') + parser.add_argument('--nhid', type=int, default=3072, + help='number of hidden units per layer') + parser.add_argument('--nlayers', type=int, default=12, + help='number of layers') + parser.add_argument('--nhead', type=int, default=12, + help='the number of heads in the encoder/decoder of the transformer model') + parser.add_argument('--dropout', type=float, default=0.2, + help='dropout applied to layers (0 = no dropout)') + args = parser.parse_args() + torch.manual_seed(args.seed) + + try: + vocab = torch.load(args.save_vocab) + except: + train_dataset, dev_dataset = SQuAD1() + old_vocab = train_dataset.vocab + vocab = torchtext.vocab.Vocab(counter=old_vocab.freqs, + specials=['', '', '']) + with open(args.save_vocab, 'wb') as f: + torch.save(vocab, f) + pad_id = vocab.stoi[''] + sep_id = vocab.stoi[''] + cls_id = vocab.stoi[''] + train_dataset, dev_dataset = SQuAD1(vocab=vocab) + train_dataset = process_raw_data(train_dataset) + dev_dataset = process_raw_data(dev_dataset) + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + pretrained_bert = BertModel(len(vocab), args.emsize, args.nhead, args.nhid, args.nlayers, args.dropout) + pretrained_bert.load_state_dict(torch.load(args.bert_model)) + model = QuestionAnswerTask(pretrained_bert).to(device) + criterion = nn.CrossEntropyLoss() + optimizer = torch.optim.SGD(model.parameters(), lr=args.lr) + scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.1) + best_f1 = None + train_loss_log, val_loss_log = [], [] + + for epoch in range(1, args.epochs + 1): + epoch_start_time = time.time() + train() + val_loss, val_exact, val_f1 = evaluate(dev_dataset, vocab) + val_loss_log.append(val_loss) + print('-' * 89) + print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | ' + 'exact {:8.3f}% | ' + 'f1 {:8.3f}%'.format(epoch, (time.time() - epoch_start_time), + val_loss, val_exact, val_f1)) + print('-' * 89) + if best_f1 is None or val_f1 > best_f1: + with open(args.save, 'wb') as f: + torch.save(model, f) + best_f1 = val_f1 + else: + scheduler.step() + + with open(args.save, 'rb') as f: + model = torch.load(f) + test_loss, test_exact, test_f1 = evaluate(dev_dataset, vocab) + print('=' * 89) + print('| End of training | test loss {:5.2f} | exact {:8.3f}% | f1 {:8.3f}%'.format( + test_loss, test_exact, test_f1)) + print('=' * 89) + print_loss_log('qa_loss.txt', train_loss_log, val_loss_log, test_loss) + with open(args.save, 'wb') as f: + torch.save(model, f) diff --git a/examples/BERT/utils.py b/examples/BERT/utils.py new file mode 100644 index 0000000000..94cf371663 --- /dev/null +++ b/examples/BERT/utils.py @@ -0,0 +1,58 @@ +import torch +import torch.distributed as dist +import os +import torch.multiprocessing as mp +import math + + +def setup(rank, world_size, seed): + os.environ['MASTER_ADDR'] = 'localhost' + os.environ['MASTER_PORT'] = '12355' + # initialize the process group + dist.init_process_group("nccl", rank=rank, world_size=world_size) + + # Explicitly setting seed to make sure that models created in two processes + # start from same random weights and biases. + torch.manual_seed(seed) + + +def cleanup(): + dist.destroy_process_group() + + +def run_demo(demo_fn, main_fn, args): + mp.spawn(demo_fn, + args=(main_fn, args,), + nprocs=args.world_size, + join=True) + + +def run_ddp(rank, main_fn, args): + setup(rank, args.world_size, args.seed) + main_fn(args, rank) + cleanup() + + +def print_loss_log(file_name, train_loss, val_loss, test_loss, args=None): + with open(file_name, 'w') as f: + if args: + for item in args.__dict__: + f.write(item + ': ' + str(args.__dict__[item]) + '\n') + for idx in range(len(train_loss)): + f.write('epoch {:3d} | train loss {:8.5f}'.format(idx + 1, + train_loss[idx]) + '\n') + for idx in range(len(val_loss)): + f.write('epoch {:3d} | val loss {:8.5f}'.format(idx + 1, + val_loss[idx]) + '\n') + f.write('test loss {:8.5f}'.format(test_loss) + '\n') + + +def wrap_up(train_loss_log, val_loss_log, test_loss, args, model, ns_loss_log, model_filename): + print('=' * 89) + print('| End of training | test loss {:8.5f} | test ppl {:8.5f}'.format(test_loss, math.exp(test_loss))) + print('=' * 89) + print_loss_log(ns_loss_log, train_loss_log, val_loss_log, test_loss) + with open(args.save, 'wb') as f: + torch.save(model.bert_model.state_dict(), f) + with open(model_filename, 'wb') as f: + torch.save(model.state_dict(), f) diff --git a/test/common/torchtext_test_case.py b/test/common/torchtext_test_case.py index 21ccc4d785..322eb32292 100644 --- a/test/common/torchtext_test_case.py +++ b/test/common/torchtext_test_case.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import torch # noqa: F401 from torch.testing._internal.common_utils import TestCase import json import logging diff --git a/test/data/test_jit.py b/test/data/test_jit.py index dff0d26b9a..8ac0284466 100644 --- a/test/data/test_jit.py +++ b/test/data/test_jit.py @@ -1,5 +1,5 @@ import torch -from torchtext.modules import InProjContainer, MultiheadAttentionContainer, ScaledDotProduct +from torchtext.nn import InProjContainer, MultiheadAttentionContainer, ScaledDotProduct from torch.testing import assert_allclose from ..common.torchtext_test_case import TorchtextTestCase diff --git a/test/data/test_modules.py b/test/data/test_modules.py index 0de4e93239..7f88d131eb 100644 --- a/test/data/test_modules.py +++ b/test/data/test_modules.py @@ -1,7 +1,7 @@ import torch -from torchtext.modules import InProjContainer, MultiheadAttentionContainer, ScaledDotProduct +from torch.nn import Linear +from torchtext.nn import InProjContainer, MultiheadAttentionContainer, ScaledDotProduct from torch.nn.functional import multi_head_attention_forward as mha_forward -from torch.testing import assert_allclose from ..common.torchtext_test_case import TorchtextTestCase @@ -10,13 +10,13 @@ class TestModels(TorchtextTestCase): def test_multiheadattention(self): embed_dim, nhead, tgt_len, src_len, bsz = 10, 5, 6, 10, 64 # Build torchtext MultiheadAttention module - in_proj = InProjContainer(torch.nn.Linear(embed_dim, embed_dim, bias=False), - torch.nn.Linear(embed_dim, embed_dim, bias=False), - torch.nn.Linear(embed_dim, embed_dim, bias=False)) + in_proj = InProjContainer(Linear(embed_dim, embed_dim, bias=False), + Linear(embed_dim, embed_dim, bias=False), + Linear(embed_dim, embed_dim, bias=False)) MHA = MultiheadAttentionContainer(nhead, in_proj, ScaledDotProduct(), - torch.nn.Linear(embed_dim, embed_dim, bias=False)) + Linear(embed_dim, embed_dim, bias=False)) query = torch.rand((tgt_len, bsz, embed_dim)) key = value = torch.rand((src_len, bsz, embed_dim)) @@ -40,10 +40,49 @@ def test_multiheadattention(self): MHA.out_proj.weight, None, attn_mask=torch_attn_mask) - assert_allclose(mha_output, torch_mha_output) + self.assertEqual(mha_output, torch_mha_output) # With bias_k and bias_v, src_len needs to plus 1 attn_weights = attn_weights.view(bsz, nhead, tgt_len, src_len + 1).sum(dim=1) / nhead - assert_allclose(attn_weights, torch_mha_weights) + self.assertEqual(attn_weights, torch_mha_weights) + + def test_mha_batch_first(self): + embed_dim, nhead, tgt_len, src_len, bsz = 10, 5, 6, 10, 64 + # Build torchtext MultiheadAttention module + in_proj = InProjContainer(Linear(embed_dim, embed_dim, bias=False), + Linear(embed_dim, embed_dim, bias=False), + Linear(embed_dim, embed_dim, bias=False)) + + MHA_batch_1st = MultiheadAttentionContainer(nhead, in_proj, + ScaledDotProduct(), + Linear(embed_dim, embed_dim, bias=False), + batch_first=True) + + query = torch.rand((tgt_len, bsz, embed_dim)) + key = value = torch.rand((src_len, bsz, embed_dim)) + attn_mask_2D = torch.randint(0, 2, (tgt_len, src_len)).to(torch.bool) + bias_k = bias_v = torch.rand((1, 1, embed_dim)) + mha_output_1st, attn_weights_1st = MHA_batch_1st(query.transpose(0, 1), key.transpose(0, 1), value.transpose(0, 1), + attn_mask=torch.stack([attn_mask_2D] * (bsz * nhead)), + bias_k=bias_k.repeat(1, bsz, 1).reshape(1, bsz * nhead, -1), + bias_v=bias_v.repeat(1, bsz, 1).reshape(1, bsz * nhead, -1)) + + # Use torch.nn.functional.multi_head_attention_forward + torch_attn_mask = torch.zeros((tgt_len, src_len)).masked_fill_(attn_mask_2D, float('-inf')) + in_proj_weight = torch.cat([MHA_batch_1st.in_proj_container.query_proj.weight, + MHA_batch_1st.in_proj_container.key_proj.weight, + MHA_batch_1st.in_proj_container.value_proj.weight]) + torch_mha_output, torch_mha_weights = mha_forward(query, key, value, + embed_dim, nhead, + in_proj_weight, None, + bias_k, bias_v, + False, 0.0, + MHA_batch_1st.out_proj.weight, None, + attn_mask=torch_attn_mask) + + self.assertEqual(mha_output_1st.transpose(0, 1), torch_mha_output) + # With bias_k and bias_v, src_len needs to plus 1 + attn_weights_1st = attn_weights_1st.view(bsz, nhead, tgt_len, src_len + 1).sum(dim=1) / nhead + self.assertEqual(attn_weights_1st, torch_mha_weights) def test_broadcast_scaled_dot_product(self): embed_dim, nhead, tgt_len, src_len, bsz = 10, 5, 6, 10, 64 @@ -61,15 +100,15 @@ def test_broadcast_scaled_dot_product(self): sdp_attn_output, sdp_attn_weights = SDP(query, key.expand(src_len, bsz * nhead, embed_dim), value.expand(src_len, bsz * nhead, embed_dim), attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) - assert_allclose(sdp_attn_output, sdp_attn_output_full) - assert_allclose(sdp_attn_weights, sdp_attn_weights_full) + self.assertEqual(sdp_attn_output, sdp_attn_output_full) + self.assertEqual(sdp_attn_weights, sdp_attn_weights_full) # key/value have a batch size of 1 while query has a batch size of bsz * nhead sdp_attn_output, sdp_attn_weights = SDP(query.expand(tgt_len, bsz * nhead, embed_dim), key, value, attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) - assert_allclose(sdp_attn_output, sdp_attn_output_full) - assert_allclose(sdp_attn_weights, sdp_attn_weights_full) + self.assertEqual(sdp_attn_output, sdp_attn_output_full) + self.assertEqual(sdp_attn_weights, sdp_attn_weights_full) # key/value have a size of (3, 3, src_len, bsz * nhead, embed_dim) # while query has a size of (tgt_len, 1, embed_dim) @@ -79,8 +118,8 @@ def test_broadcast_scaled_dot_product(self): attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) assert list(sdp_attn_output.size()) == [3, 3, tgt_len, bsz * nhead, embed_dim] assert list(sdp_attn_weights.size()) == [3, 3, bsz * nhead, tgt_len, embed_dim] - assert_allclose(sdp_attn_output[2][2], sdp_attn_output_full) - assert_allclose(sdp_attn_weights[2][2], sdp_attn_weights_full) + self.assertEqual(sdp_attn_output[2][2], sdp_attn_output_full) + self.assertEqual(sdp_attn_weights[2][2], sdp_attn_weights_full) # dim -2 is not equal to neither key/value's dim -2 or 1 with self.assertRaises(RuntimeError): SDP(query.expand(tgt_len, 2, embed_dim), key.expand(3, 3, src_len, bsz * nhead, embed_dim), @@ -95,8 +134,8 @@ def test_broadcast_scaled_dot_product(self): attn_mask=attn_mask_2D.expand(bsz * nhead, tgt_len, src_len)) assert list(sdp_attn_output.size()) == [1, 2, 3, tgt_len, bsz * nhead, embed_dim] assert list(sdp_attn_weights.size()) == [1, 2, 3, bsz * nhead, tgt_len, embed_dim] - assert_allclose(sdp_attn_output[0][1][2], sdp_attn_output_full) - assert_allclose(sdp_attn_weights[0][1][2], sdp_attn_weights_full) + self.assertEqual(sdp_attn_output[0][1][2], sdp_attn_output_full) + self.assertEqual(sdp_attn_weights[0][1][2], sdp_attn_weights_full) # key dim -2 is not equal to value dim -2 with self.assertRaisesRegex(AssertionError, "Shape of key, value must match"): SDP(query.expand(1, 2, 3, tgt_len, bsz * nhead, embed_dim), key.expand(src_len, 2, embed_dim), @@ -114,8 +153,8 @@ def test_broadcast_scaled_dot_product(self): key.expand(src_len, bsz * nhead, embed_dim), value.expand(src_len, bsz * nhead, embed_dim), attn_mask=attn_mask_2D.expand(1, tgt_len, src_len)) - assert_allclose(sdp_attn_output, sdp_attn_output_full) - assert_allclose(sdp_attn_weights, sdp_attn_weights_full) + self.assertEqual(sdp_attn_output, sdp_attn_output_full) + self.assertEqual(sdp_attn_weights, sdp_attn_weights_full) # attn_mask's dim -3 is not equal to neither batch size or 1 with self.assertRaisesRegex(RuntimeError, "The size of the attn_mask is not correct."): SDP(query.expand(tgt_len, bsz * nhead, embed_dim), key.expand(src_len, bsz * nhead, embed_dim), diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 738ef98788..7769156f7f 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -66,6 +66,21 @@ def test_vectors_jit(self): self.assertEqual(vectors_obj['b'], jit_vectors_obj['b']) self.assertEqual(vectors_obj['not_in_it'], jit_vectors_obj['not_in_it']) + def test_vectors_lookup_vectors(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1], dtype=torch.float) + + unk_tensor = torch.tensor([0, 0], dtype=torch.float) + tokens = ['a', 'b'] + vectors = torch.stack((tensorA, tensorB), 0) + vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + + tokens_to_lookup = ['a', 'b', 'c'] + expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) + vectors_by_tokens = vectors_obj.lookup_vectors(tokens_to_lookup) + + self.assertEqual(expected_vectors, vectors_by_tokens) + def test_vectors_add_item(self): tensorA = torch.tensor([1, 0], dtype=torch.float) unk_tensor = torch.tensor([0, 0], dtype=torch.float) @@ -184,60 +199,61 @@ def test_fast_text(self): self.assertEqual(vectors_obj[word][:3], expected_fasttext_simple_en[word]) self.assertEqual(jit_vectors_obj[word][:3], expected_fasttext_simple_en[word]) - def test_glove(self): - # copy the asset file into the expected download location - # note that this is just a zip file with the first 100 entries of the GloVe 840B dataset - asset_name = 'glove.840B.300d.zip' - asset_path = get_asset_path(asset_name) - - with tempfile.TemporaryDirectory() as dir_name: - data_path = os.path.join(dir_name, asset_name) - shutil.copy(asset_path, data_path) - vectors_obj = GloVe(root=dir_name, validate_file=False) - jit_vectors_obj = torch.jit.script(vectors_obj) - - # The first 3 entries in each vector. - expected_glove = { - 'the': [0.27204, -0.06203, -0.1884], - 'people': [-0.19686, 0.11579, -0.41091], - } - - for word in expected_glove.keys(): - self.assertEqual(vectors_obj[word][:3], expected_glove[word]) - self.assertEqual(jit_vectors_obj[word][:3], expected_glove[word]) - - def test_glove_different_dims(self): - # copy the asset file into the expected download location - # note that this is just a zip file with 1 line txt files used to test that the - # correct files are being loaded - asset_name = 'glove.6B.zip' - asset_path = get_asset_path(asset_name) - - with tempfile.TemporaryDirectory() as dir_name: - data_path = os.path.join(dir_name, asset_name) - shutil.copy(asset_path, data_path) - - glove_50d = GloVe(name='6B', dim=50, root=dir_name, validate_file=False) - glove_100d = GloVe(name='6B', dim=100, root=dir_name, validate_file=False) - glove_200d = GloVe(name='6B', dim=200, root=dir_name, validate_file=False) - glove_300d = GloVe(name='6B', dim=300, root=dir_name, validate_file=False) - vectors_objects = [glove_50d, glove_100d, glove_200d, glove_300d] - - # The first 3 entries in each vector. - expected_glove_50d = { - 'the': [0.418, 0.24968, -0.41242], - } - expected_glove_100d = { - 'the': [-0.038194, -0.24487, 0.72812], - } - expected_glove_200d = { - 'the': [-0.071549, 0.093459, 0.023738], - } - expected_glove_300d = { - 'the': [0.04656, 0.21318, -0.0074364], - } - expected_gloves = [expected_glove_50d, expected_glove_100d, expected_glove_200d, expected_glove_300d] - - for vectors_obj, expected_glove in zip(vectors_objects, expected_gloves): - for word in expected_glove.keys(): - self.assertEqual(vectors_obj[word][:3], expected_glove[word]) + # TODO: reenable test once the GloVe dataset url starts working + # def test_glove(self): + # # copy the asset file into the expected download location + # # note that this is just a zip file with the first 100 entries of the GloVe 840B dataset + # asset_name = 'glove.840B.300d.zip' + # asset_path = get_asset_path(asset_name) + + # with tempfile.TemporaryDirectory() as dir_name: + # data_path = os.path.join(dir_name, asset_name) + # shutil.copy(asset_path, data_path) + # vectors_obj = GloVe(root=dir_name, validate_file=False) + # jit_vectors_obj = torch.jit.script(vectors_obj) + + # # The first 3 entries in each vector. + # expected_glove = { + # 'the': [0.27204, -0.06203, -0.1884], + # 'people': [-0.19686, 0.11579, -0.41091], + # } + + # for word in expected_glove.keys(): + # self.assertEqual(vectors_obj[word][:3], expected_glove[word]) + # self.assertEqual(jit_vectors_obj[word][:3], expected_glove[word]) + + # def test_glove_different_dims(self): + # # copy the asset file into the expected download location + # # note that this is just a zip file with 1 line txt files used to test that the + # # correct files are being loaded + # asset_name = 'glove.6B.zip' + # asset_path = get_asset_path(asset_name) + + # with tempfile.TemporaryDirectory() as dir_name: + # data_path = os.path.join(dir_name, asset_name) + # shutil.copy(asset_path, data_path) + + # glove_50d = GloVe(name='6B', dim=50, root=dir_name, validate_file=False) + # glove_100d = GloVe(name='6B', dim=100, root=dir_name, validate_file=False) + # glove_200d = GloVe(name='6B', dim=200, root=dir_name, validate_file=False) + # glove_300d = GloVe(name='6B', dim=300, root=dir_name, validate_file=False) + # vectors_objects = [glove_50d, glove_100d, glove_200d, glove_300d] + + # # The first 3 entries in each vector. + # expected_glove_50d = { + # 'the': [0.418, 0.24968, -0.41242], + # } + # expected_glove_100d = { + # 'the': [-0.038194, -0.24487, 0.72812], + # } + # expected_glove_200d = { + # 'the': [-0.071549, 0.093459, 0.023738], + # } + # expected_glove_300d = { + # 'the': [0.04656, 0.21318, -0.0074364], + # } + # expected_gloves = [expected_glove_50d, expected_glove_100d, expected_glove_200d, expected_glove_300d] + + # for vectors_obj, expected_glove in zip(vectors_objects, expected_gloves): + # for word in expected_glove.keys(): + # self.assertEqual(vectors_obj[word][:3], expected_glove[word]) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index f3e4a4aeb5..abcb151ff0 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -3,9 +3,11 @@ import os import torch +from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vocab import ( - Vocab + Vocab, + vocab_from_file_object ) @@ -16,7 +18,7 @@ def tearDown(self): torch.jit._recursive.concrete_type_store = torch.jit._recursive.ConcreteTypeStore() def test_has_unk(self): - c = OrderedDict({}) + c = OrderedDict() v = Vocab(c) # check if unk is mapped to the first index @@ -24,52 +26,53 @@ def test_has_unk(self): self.assertEqual(v[''], 0) def test_new_unk(self): - c = OrderedDict({}) - v = Vocab(c, specials=('',), unk_token="") + c = OrderedDict() + v = Vocab(c, unk_token="") # check if new_unk is mapped to the first index self.assertEqual(v[''], 0) self.assertEqual(v['not_in_it'], 0) def test_vocab_get_item(self): - token_to_freq = {'a': 2, 'b': 2} + token_to_freq = {'': 2, 'a': 2, 'b': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c) + v = Vocab(c, min_freq=2) self.assertEqual(v[''], 0) - self.assertEqual(v[''], 1) - self.assertEqual(v['a'], 2) - self.assertEqual(v['b'], 3) + self.assertEqual(v['a'], 1) + self.assertEqual(v['b'], 2) - def test_vocab_set_item(self): - c = OrderedDict({'a': 2}) + def test_vocab_insert_token(self): + c = OrderedDict({'': 2, 'a': 2}) # add item to end v = Vocab(c) - v.insert_token('b', 3) + v.insert_token('b', 2) - self.assertEqual(v[''], 0) - self.assertEqual(v[''], 1) - self.assertEqual(v['a'], 2) - self.assertEqual(v['b'], 3) + expected_itos = ['', 'a', 'b'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) # add item to middle - v = Vocab(c, specials_first=False) + v = Vocab(c) v.insert_token('b', 0) - self.assertEqual(v['b'], 0) - self.assertEqual(v['a'], 1) - self.assertEqual(v[''], 2) - self.assertEqual(v[''], 3) + expected_itos = ['b', '', 'a'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) def test_vocab_append_token(self): c = OrderedDict({'a': 2}) v = Vocab(c) v.append_token('b') - self.assertEqual(len(v), 4) - self.assertEqual(v['b'], 3) + self.assertEqual(len(v), 3) + self.assertEqual(v['b'], 2) def test_vocab_len(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} @@ -77,17 +80,16 @@ def test_vocab_len(self): c = OrderedDict(sorted_by_freq_tuples) v = Vocab(c) - self.assertEqual(len(v), 5) + self.assertEqual(len(v), 4) def test_vocab_basic(self): token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, min_freq=3, specials=['', '', '']) + v = Vocab(c, min_freq=3) - expected_itos = ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) @@ -98,40 +100,20 @@ def test_vocab_jit(self): sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, min_freq=3, specials=['', '', '']) + v = Vocab(c, min_freq=3) jit_v = torch.jit.script(v) - expected_itos = ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(jit_v.get_itos(), expected_itos) self.assertEqual(dict(jit_v.get_stoi()), expected_stoi) - def test_vocab_specials_order(self): - token_to_freq = {'a': 2, 'b': 2, 'c': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - - # add specials into vocabulary at first - v = Vocab(c, specials=['', '']) - expected_itos = ['', '', 'a', 'b', 'c'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - self.assertEqual(dict(v.get_stoi()), expected_stoi) - - # add specials into vocabulary at last - v = Vocab(c, specials=['', ''], specials_first=False) - expected_itos = ['a', 'b', 'c', '', ''] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - self.assertEqual(dict(v.get_stoi()), expected_stoi) - def test_vocab_lookup_token(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, specials_first=False) + v = Vocab(c) self.assertEqual(v.lookup_token(0), 'a') @@ -139,7 +121,7 @@ def test_vocab_lookup_tokens(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, specials_first=False) + v = Vocab(c) indices = [1, 0, 2] expected_tokens = ['b', 'a', 'c'] @@ -150,7 +132,7 @@ def test_vocab_lookup_indices(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, specials_first=False) + v = Vocab(c) tokens = ['b', 'a', 'c'] expected_indices = [1, 0, 2] @@ -164,18 +146,7 @@ def test_errors(self): with self.assertRaises(ValueError): # Test proper error raised when setting unk token to None - Vocab(c, specials=['', ''], unk_token=None) - - with self.assertRaises(ValueError): - # Test proper error raised when specials token doesn't contain unk_token - Vocab(c, specials=['', '']) - - with self.assertRaises(ValueError): - # Test proper error raised when ordered_dict contains a special token - updated_token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2, '': 1} - updated_sorted_by_freq_tuples = sorted(updated_token_to_freq.items(), key=lambda x: x[1], reverse=True) - updated_c = OrderedDict(updated_sorted_by_freq_tuples) - Vocab(updated_c, specials=['', '', '']) + Vocab(c, unk_token=None) with self.assertRaises(RuntimeError): # Test proper error raised when setting a token out of bounds @@ -194,8 +165,7 @@ def test_vocab_load_and_save(self): c = OrderedDict(sorted_by_freq_tuples) v = Vocab(c, min_freq=3) - expected_itos = ['', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) @@ -207,3 +177,15 @@ def test_vocab_load_and_save(self): self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + + def test_vocab_from_file(self): + asset_name = 'vocab_test.txt' + asset_path = get_asset_path(asset_name) + f = open(asset_path, 'r') + v = vocab_from_file_object(f, unk_token='') + + expected_itos = ['', 'a', 'b', 'c'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/__init__.py b/torchtext/__init__.py index 9ce2ce9c08..e7c08bb239 100644 --- a/torchtext/__init__.py +++ b/torchtext/__init__.py @@ -1,5 +1,5 @@ from . import data -from . import modules +from . import nn from . import datasets from . import utils from . import vocab @@ -12,7 +12,7 @@ pass __all__ = ['data', - 'modules', + 'nn', 'datasets', 'utils', 'vocab', diff --git a/torchtext/csrc/vectors.cpp b/torchtext/csrc/vectors.cpp index 16c5055a7a..cf84b694f0 100644 --- a/torchtext/csrc/vectors.cpp +++ b/torchtext/csrc/vectors.cpp @@ -7,8 +7,14 @@ using c10::Dict; namespace torchtext { namespace { +typedef std::tuple, std::vector, + std::vector> + VectorsStates; + struct Vectors : torch::CustomClassHolder { public: + const std::string version_str_ = "0.0.1"; + Dict stovec_; std::vector tokens_; torch::Tensor vectors_; @@ -46,6 +52,15 @@ struct Vectors : torch::CustomClassHolder { return unk_tensor_; } + torch::Tensor lookup_vectors(const std::vector &tokens) { + std::vector vectors; + for (const std::string &token : tokens) { + vectors.push_back(__getitem__(token)); + } + + return torch::stack(vectors, 0); + } + void __setitem__(const std::string &token, const torch::Tensor &vector) { const auto &item = stovec_.find(token); if (item != stovec_.end()) { @@ -61,31 +76,62 @@ struct Vectors : torch::CustomClassHolder { int64_t __len__() { return stovec_.size(); } }; +VectorsStates _set_vectors_states(const c10::intrusive_ptr &self) { + std::vector integers; + std::vector strings = self->tokens_; + std::vector tensors{self->vectors_, self->unk_tensor_}; + + VectorsStates states = + std::make_tuple(self->version_str_, std::move(integers), + std::move(strings), std::move(tensors)); + + return states; +} + +c10::intrusive_ptr _get_vectors_from_states(VectorsStates states) { + auto state_size = std::tuple_size::value; + if (state_size != 4) { + throw std::runtime_error( + "Expected deserialized Vectors to have 4 states but found only " + + std::to_string(state_size) + " states."); + } + + auto &version_str = std::get<0>(states); + auto &integers = std::get<1>(states); + auto &strings = std::get<2>(states); + auto &tensors = std::get<3>(states); + + // check integers are empty + if (integers.size() != 0) { + throw std::runtime_error("Expected `integers` states to be empty."); + } + + if (version_str.compare("0.0.1") >= 0) { + return c10::make_intrusive( + std::move(strings), std::move(tensors[0]), std::move(tensors[1])); + } + + throw std::runtime_error( + "Found unexpected version for serialized Vector: " + version_str + "."); +} + // Registers our custom class with torch. static auto vectors = torch::class_("torchtext", "Vectors") .def(torch::init, torch::Tensor, torch::Tensor>()) .def("__getitem__", &Vectors::__getitem__) + .def("lookup_vectors", &Vectors::lookup_vectors) .def("__setitem__", &Vectors::__setitem__) .def("__len__", &Vectors::__len__) .def_pickle( // __setstate__ - [](const c10::intrusive_ptr &self) - -> std::tuple, torch::Tensor, - torch::Tensor> { - std::tuple, torch::Tensor, torch::Tensor> - states(self->tokens_, self->vectors_, self->unk_tensor_); - return states; + [](const c10::intrusive_ptr &self) -> VectorsStates { + return _set_vectors_states(self); }, // __getstate__ - [](std::tuple, torch::Tensor, - torch::Tensor> - states) -> c10::intrusive_ptr { - return c10::make_intrusive( - std::move(std::get<0>(states)), - std::move(std::get<1>(states)), - std::move(std::get<2>(states))); + [](VectorsStates states) -> c10::intrusive_ptr { + return _get_vectors_from_states(states); }); } // namespace diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 9fbe3231dd..656d1c3bff 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -7,16 +7,17 @@ namespace { using c10::Dict; +typedef std::tuple, std::vector, + std::vector> + VocabStates; + struct Vocab : torch::CustomClassHolder { private: int64_t unk_index_; Dict stoi_; public: - // stoi_, and unordered_map holds the serialized params passed in - // during initialization. We need this because we need to be able to serialize - // the model so that we can save the scripted object. Pickle will get the - // serialized model from these members, thus they needs to be public. + const std::string version_str_ = "0.0.1"; std::vector itos_; std::string unk_token_; @@ -68,12 +69,11 @@ struct Vocab : torch::CustomClassHolder { } // need to offset all tokens greater than or equal index by 1 - for (auto &entry : stoi_) { - if (entry.value() >= index) { - stoi_.insert_or_assign(entry.key(), std::move(entry.value() + 1)); - } + for (size_t i = index; i < itos_.size(); i++) { + stoi_.insert_or_assign(itos_[i], std::move(i + 1)); } stoi_.insert(std::move(token), std::move(index)); + itos_.insert(itos_.begin() + index, std::move(token)); // need to update unk_index in case token equals unk_token or token inserted // before unk_token @@ -111,6 +111,47 @@ struct Vocab : torch::CustomClassHolder { std::vector get_itos() const { return itos_; } }; +VocabStates _set_vocab_states(const c10::intrusive_ptr &self) { + std::vector integers; + std::vector strings = self->itos_; + strings.push_back(self->unk_token_); + std::vector tensors; + + VocabStates states = std::make_tuple(self->version_str_, std::move(integers), + std::move(strings), std::move(tensors)); + return states; +} + +c10::intrusive_ptr _get_vocab_from_states(VocabStates states) { + auto state_size = std::tuple_size::value; + if (state_size != 4) { + throw std::runtime_error( + "Expected deserialized Vocab to have 4 states but found only " + + std::to_string(state_size) + " states."); + } + + auto &version_str = std::get<0>(states); + auto &integers = std::get<1>(states); + auto &strings = std::get<2>(states); + auto &tensors = std::get<3>(states); + + // check integers and tensors are empty + if (integers.size() != 0 || tensors.size() != 0) { + throw std::runtime_error( + "Expected `integers` and `tensors` states to be empty."); + } + + if (version_str.compare("0.0.1") >= 0) { + std::string unk_token = strings.back(); + strings.pop_back(); // remove last element which is unk_token + + return c10::make_intrusive(std::move(strings), std::move(unk_token)); + } + + throw std::runtime_error( + "Found unexpected version for serialized Vocab: " + version_str + "."); +} + // Registers our custom class with torch. static auto vocab = torch::class_("torchtext", "Vocab") @@ -125,18 +166,14 @@ static auto vocab = .def("get_stoi", &Vocab::get_stoi) .def("get_itos", &Vocab::get_itos) .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) - -> std::tuple, std::string> { - std::tuple, std::string> states( - self->itos_, self->unk_token_); - return states; - }, // __setstate__ - [](std::tuple, std::string> states) - -> c10::intrusive_ptr { - return c10::make_intrusive(std::move(std::get<0>(states)), - std::move(std::get<1>(states))); + [](const c10::intrusive_ptr &self) -> VocabStates { + return _set_vocab_states(self); + }, + // __getstate__ + [](VocabStates states) -> c10::intrusive_ptr { + return _get_vocab_from_states(states); }); + } // namespace } // namespace torchtext diff --git a/torchtext/data/batch.py b/torchtext/data/batch.py index af29f175d4..f345a82e19 100644 --- a/torchtext/data/batch.py +++ b/torchtext/data/batch.py @@ -1,4 +1,5 @@ import torch +import warnings class Batch(object): @@ -19,6 +20,7 @@ class Batch(object): def __init__(self, data=None, dataset=None, device=None): """Create a Batch from a list of examples.""" + warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) if data is not None: self.batch_size = len(data) self.dataset = dataset diff --git a/torchtext/data/example.py b/torchtext/data/example.py index d9f96aeda3..a5d29ef42a 100644 --- a/torchtext/data/example.py +++ b/torchtext/data/example.py @@ -1,5 +1,6 @@ import json from functools import reduce +import warnings class Example(object): @@ -9,6 +10,7 @@ class Example(object): """ @classmethod def fromJSON(cls, data, fields): + warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) ex = cls() obj = json.loads(data) @@ -47,6 +49,7 @@ def reducer(obj, key): @classmethod def fromdict(cls, data, fields): + warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) ex = cls() for key, vals in fields.items(): if key not in data: @@ -62,6 +65,7 @@ def fromdict(cls, data, fields): @classmethod def fromCSV(cls, data, fields, field_to_index=None): + warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) if field_to_index is None: return cls.fromlist(data, fields) else: @@ -71,6 +75,7 @@ def fromCSV(cls, data, fields, field_to_index=None): @classmethod def fromlist(cls, data, fields): + warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) ex = cls() for (name, field), val in zip(fields, data): if field is not None: @@ -86,6 +91,7 @@ def fromlist(cls, data, fields): @classmethod def fromtree(cls, data, fields, subtrees=False): + warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) try: from nltk.tree import Tree except ImportError: diff --git a/torchtext/data/field.py b/torchtext/data/field.py index 189331c1be..6054f1a510 100644 --- a/torchtext/data/field.py +++ b/torchtext/data/field.py @@ -3,7 +3,7 @@ from itertools import chain import torch from tqdm import tqdm - +import warnings from .dataset import Dataset from .pipeline import Pipeline from .utils import get_tokenizer, dtype_to_attr, is_tokenizer_serializable @@ -33,6 +33,7 @@ class RawField(object): """ def __init__(self, preprocessing=None, postprocessing=None, is_target=False): + warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) self.preprocessing = preprocessing self.postprocessing = postprocessing self.is_target = is_target @@ -146,6 +147,7 @@ def __init__(self, sequential=True, use_vocab=True, init_token=None, batch_first=False, pad_token="", unk_token="", pad_first=False, truncate_first=False, stop_words=None, is_target=False): + warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) self.sequential = sequential self.use_vocab = use_vocab self.init_token = init_token @@ -365,6 +367,7 @@ def numericalize(self, arr, device=None): class ReversibleField(Field): def __init__(self, **kwargs): + warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) if kwargs.get('tokenize') is list: self.use_revtok = False else: @@ -411,6 +414,7 @@ class SubwordField(ReversibleField): vocab_cls = SubwordVocab def __init__(self, **kwargs): + warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) kwargs['tokenize'] = 'subword' if 'unk_token' not in kwargs: kwargs['unk_token'] = '�' @@ -491,6 +495,7 @@ def __init__(self, nesting_field, use_vocab=True, init_token=None, eos_token=Non postprocessing=None, tokenize=None, tokenizer_language='en', include_lengths=False, pad_token='', pad_first=False, truncate_first=False): + warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) if isinstance(nesting_field, NestedField): raise ValueError('nesting field must not be another NestedField') if nesting_field.include_lengths: diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py index c76a7335ff..bc4d410464 100644 --- a/torchtext/data/iterator.py +++ b/torchtext/data/iterator.py @@ -2,7 +2,7 @@ import random import logging - +import warnings import torch from .utils import RandomShuffler from .batch import Batch @@ -45,6 +45,7 @@ def __init__(self, dataset, batch_size, sort_key=None, device=None, batch_size_fn=None, train=True, repeat=False, shuffle=None, sort=None, sort_within_batch=None): + warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) self.batch_size, self.train, self.dataset = batch_size, train, dataset self.batch_size_fn = batch_size_fn self.iterations = 0 diff --git a/torchtext/experimental/asset/get_checksum.sh b/torchtext/experimental/asset/get_checksum.sh index 04c5701b6d..b8980f0eed 100755 --- a/torchtext/experimental/asset/get_checksum.sh +++ b/torchtext/experimental/asset/get_checksum.sh @@ -1,5 +1,5 @@ #!/bin/bash -FILENAME="$1" -URL="$2" +FILENAME=$1 +URL=$2 -wget -O - -o /dev/null "$URL" | sha256sum | head -c 64 > "$FILENAME" +wget -O - -o /dev/null $URL | sha256sum | head -c 64 > $FILENAME diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index fad8e0ad87..bd05801c16 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -5,6 +5,7 @@ from torch import Tensor import torch.nn as nn from tqdm import tqdm +from typing import List from torchtext.utils import ( download_from_url, @@ -18,9 +19,9 @@ def _infer_shape(f, delimiter=" "): num_lines, vector_dim = 0, None for line in f: if vector_dim is None: - # token and entries are separated by delimiter + # token and entries are seperated by delimeter token, entries = line.rstrip().split(bytes(delimiter, "utf-8"), 1) - # we assume entries are always separated by " " + # we assume entries are always seperated by " " vector = entries.split(b" ") # Assuming word, [vector] format @@ -43,9 +44,9 @@ def _load_token_and_vectors_from_file(file_path, delimiter=" "): vectors_loaded = 0 for line in tqdm(f, unit_scale=0, unit="lines", total=num_lines): - # token and entries are separated by delimiter + # token and entries are seperated by delimeter token, entries = line.rstrip().split(bytes(delimiter, "utf-8"), 1) - # we assume entries are always separated by " " + # we assume entries are always seperated by " " entries = entries.split(b" ") if dim is None and len(entries) > 1: @@ -298,6 +299,25 @@ def __len__(self) -> int: """ return len(self.vectors) + @torch.jit.export + def lookup_vectors(self, tokens: List[str]) -> Tensor: + """Look up embedding vectors for a list of tokens. + Arguments: + tokens: a list of tokens + + Returns: + vectors (Tensor): returns a 2-D tensor of shape=(len(tokens), vector_dim) or an empty tensor if `tokens` is empty + + Examples: + >>> examples = ['chip', 'baby', 'Beautiful'] + >>> vec = text.vocab.GloVe(name='6B', dim=50) + >>> ret = vec.get_vectors_by_tokens(tokens) + """ + if not len(tokens): + return torch.empty(0, 0) + + return self.vectors.lookup_vectors(tokens) + CHECKSUMS_GLOVE = { "https://nlp.stanford.edu/data/glove.42B.300d.zip": diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index a52599d952..5e9dc32e50 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -1,26 +1,73 @@ +from collections import OrderedDict import logging from typing import Dict, List +import warnings import torch import torch.nn as nn +from tqdm import tqdm + logger = logging.getLogger(__name__) +def _infer_shape(f): + num_lines = 0 + for line in f: + num_lines += 1 + f.seek(0) + return num_lines + + +def vocab_from_file_object(file_like_object, **kwargs): + r"""Create a `Vocab` object from a file like object. + + The `file_like_object` should contain tokens seperated by new lines. Note that the vocab + will be created in the order that the tokens first appear in the file (and not by the frequency of tokens). + + Format for txt file: + token1 + token2 + ... + token_n + + Args: + file_like_object (FileObject): a file like object to read data from. + Remaining keyword arguments: Passed to the constructor of Vocab class. + + Returns: + Vocab: a `Vocab` object. + + Examples: + >>> from torchtext.experimental.vocab import vocab_from_file_object + >>> f = open('vocab.txt', 'r') + >>> v = vocab_from_file_object(f, specials=('', '', ''), specials_first=False) + """ + ordered_dict = OrderedDict() + num_lines = _infer_shape(file_like_object) + for line in tqdm(file_like_object, unit_scale=0, unit="lines", total=num_lines): + token = line.rstrip() + if token in ordered_dict: + ordered_dict[token] += 1 + else: + ordered_dict[token] = 1 + + return Vocab(ordered_dict, **kwargs) + + class Vocab(nn.Module): r"""Creates a vocab object which maps tokens to indices. Note that the ordering in which key value pairs were inserted in the `ordered_dict` will be respected when building the vocab. Therefore if sorting by token frequency is important to the user, the `ordered_dict` should be created in a way to reflect this. + Additionally, the if the `unk_token` isn't found inside of the `ordered_dict`, it will be added to the end of the vocab. Arguments: ordered_dict (collections.OrderedDict): object holding the frequencies of each token found in the data. min_freq: The minimum frequency needed to include a token in the vocabulary. Values less than 1 will be set to 1. Default: 1. - specials: The tuple of special tokens (e.g., padding or eos) that will be prepended/postpended to the vocabulary. - based on the `specials_first` flag. The ordering of the tuple will be preserved. Default: ('', '') - specials_first: Whether to add special tokens into the vocabulary at first. If it is False, - they are added into the vocabulary at last. Default: True. + unk_token: The default unknown token to use. Default: ''. + Raises: ValueError: if a default `unk_token` isn't provided. @@ -36,29 +83,21 @@ class Vocab(nn.Module): >>> v2 = Vocab(OrderedDict([(token, 1) for token in tokens])) """ - def __init__(self, ordered_dict, min_freq=1, unk_token='', specials=('', ''), specials_first=True): + def __init__(self, ordered_dict, min_freq=1, unk_token=''): super(Vocab, self).__init__() if not unk_token: raise ValueError("A default unk token wasn't provided.") - if unk_token not in specials: - raise ValueError("The unk token wasn't found in the `specials` tuple.") - tokens = [] for token, freq in ordered_dict.items(): if freq >= min_freq: - if token in specials: - raise ValueError("A `specials` token {} was found inside of `ordered_dict`." - "Please ensure that the `ordered_dict` doesn't contain any special tokens.".format(token)) tokens.append(token) - # assume special tokens dont appear in ordered_dict - if specials_first: - tokens = list(specials) + tokens - else: - tokens += list(specials) - + if unk_token not in tokens: + tokens.append(unk_token) + warnings.warn("The `unk_token` '{}' wasn't found in the `ordered_dict`. Adding the `unk_token` " + "to the end of the Vocab.".format(unk_token), RuntimeWarning) self.vocab = torch.classes.torchtext.Vocab(tokens, unk_token) @torch.jit.export @@ -150,6 +189,6 @@ def get_stoi(self) -> Dict[str, int]: def get_itos(self) -> List[str]: r""" Returns: - stoi (dict): dictionary mapping indices to tokens. + itos (dict): dictionary mapping indices to tokens. """ return self.vocab.get_itos() diff --git a/torchtext/nn/__init__.py b/torchtext/nn/__init__.py new file mode 100644 index 0000000000..c48d6de70e --- /dev/null +++ b/torchtext/nn/__init__.py @@ -0,0 +1 @@ +from .modules import * # noqa: F401,F403 diff --git a/torchtext/modules/__init__.py b/torchtext/nn/modules/__init__.py similarity index 100% rename from torchtext/modules/__init__.py rename to torchtext/nn/modules/__init__.py diff --git a/torchtext/modules/multiheadattention.py b/torchtext/nn/modules/multiheadattention.py similarity index 77% rename from torchtext/modules/multiheadattention.py rename to torchtext/nn/modules/multiheadattention.py index f6d8e7675d..4ce2a23bc0 100644 --- a/torchtext/modules/multiheadattention.py +++ b/torchtext/nn/modules/multiheadattention.py @@ -3,14 +3,20 @@ class MultiheadAttentionContainer(torch.nn.Module): - def __init__(self, nhead, in_proj_container, attention_layer, out_proj): + def __init__(self, nhead, in_proj_container, attention_layer, out_proj, batch_first=False): r""" A multi-head attention container Args: nhead: the number of heads in the multiheadattention model in_proj_container: A container of multi-head in-projection linear layers (a.k.a nn.Linear). - attention_layer: The attention layer. + attention_layer: The custom attention layer. The input sent from MHA container to the attention layer + is in the shape of `(..., L, N * H, E / H)` for query and `(..., S, N * H, E / H)` for key/value + while the output shape of the attention layer is expected to be `(..., L, N * H, E / H)`. + The attention_layer needs to support broadcast if users want the overall MultiheadAttentionContainer + with broadcast. out_proj: The multi-head out-projection layer (a.k.a nn.Linear). + batch_first: If ``True``, then the input and output tensors are provided + as `(..., N, L, E)`. Default: ``False`` Examples:: >>> import torch @@ -33,6 +39,7 @@ def __init__(self, nhead, in_proj_container, attention_layer, out_proj): self.in_proj_container = in_proj_container self.attention_layer = attention_layer self.out_proj = out_proj + self.batch_first = batch_first def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, attn_mask: Optional[torch.Tensor] = None, @@ -48,18 +55,24 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, Shape: - Inputs: - - query: :math:`(L, N, E)` - - key: :math:`(S, N, E)` - - value: :math:`(S, N, E)` + - query: :math:`(..., L, N, E)` + - key: :math:`(..., S, N, E)` + - value: :math:`(..., S, N, E)` - attn_mask, bias_k and bias_v: same with the shape of the corresponding args in attention layer. - Outputs: - - attn_output: :math:`(L, N, E)` + - attn_output: :math:`(..., L, N, E)` - attn_output_weights: :math:`(N * H, L, S)` + Note: It's optional to have the query/key/value inputs with more than three dimensions (for broadcast purpose). + The MultiheadAttentionContainer module will operate on the last three dimensions. + where where L is the target length, S is the sequence length, H is the number of attention heads, N is the batch size, and E is the embedding dimension. """ + if self.batch_first: + query, key, value = query.transpose(-3, -2), key.transpose(-3, -2), value.transpose(-3, -2) + tgt_len, src_len, bsz, embed_dim = query.size(-3), key.size(-3), query.size(-2), query.size(-1) q, k, v = self.in_proj_container(query, key, value) assert q.size(-1) % self.nhead == 0, "query's embed_dim must be divisible by the number of heads" @@ -78,28 +91,35 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, bias_k=bias_k, bias_v=bias_v) attn_output = attn_output.reshape(tgt_len, bsz, embed_dim) attn_output = self.out_proj(attn_output) + + if self.batch_first: + attn_output = attn_output.transpose(-3, -2) + return attn_output, attn_output_weights class ScaledDotProduct(torch.nn.Module): - def __init__(self, dropout=0.0): + def __init__(self, dropout=0.0, batch_first=False): r"""Processes a projected query and key-value pair to apply scaled dot product attention. Args: dropout (float): probability of dropping an attention weight. + batch_first: If ``True``, then the input and output tensors are provided + as `(batch, seq, feature)`. Default: ``False`` Examples:: - >>> SDP = torchtext.models.ScaledDotProduct(0.1) - >>> q = torch.randn(256, 21, 3) - >>> k = v = torch.randn(256, 21, 3) + >>> SDP = torchtext.nn.ScaledDotProduct(dropout=0.1) + >>> q = torch.randn(21, 256, 3) + >>> k = v = torch.randn(21, 256, 3) >>> attn_output, attn_weights = SDP(q, k, v) >>> print(attn_output.shape, attn_weights.shape) - torch.Size([256, 21, 3]) torch.Size([256, 21, 21]) + torch.Size([21, 256, 3]) torch.Size([256, 21, 21]) """ super(ScaledDotProduct, self).__init__() self.dropout = dropout + self.batch_first = batch_first def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, attn_mask: Optional[torch.Tensor] = None, @@ -118,18 +138,24 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, non-None to both arguments in order to activate them. Shape: - - query: :math:`(L, N * H, E / H)` - - key: :math:`(S, N * H, E / H)` - - value: :math:`(S, N * H, E / H)` + - query: :math:`(..., L, N * H, E / H)` + - key: :math:`(..., S, N * H, E / H)` + - value: :math:`(..., S, N * H, E / H)` - attn_mask: :math:`(N * H, L, S)`, positions with ``True`` are not allowed to attend while ``False`` values will be unchanged. - bias_k and bias_v:bias: :math:`(1, N * H, E / H)` - - Output: :math:`(L, N * H, E / H)`, :math:`(N * H, L, S)` + - Output: :math:`(..., L, N * H, E / H)`, :math:`(N * H, L, S)` + + Note: It's optional to have the query/key/value inputs with more than three dimensions (for broadcast purpose). + The ScaledDotProduct module will operate on the last three dimensions. where L is the target length, S is the source length, H is the number of attention heads, N is the batch size, and E is the embedding dimension. """ + if self.batch_first: + query, key, value = query.transpose(-3, -2), key.transpose(-3, -2), value.transpose(-3, -2) + if bias_k is not None and bias_v is not None: assert key.size(-1) == bias_k.size(-1) and key.size(-2) == bias_k.size(-2) and bias_k.size(-3) == 1, \ "Shape of bias_k is not supported" @@ -138,8 +164,7 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, key = torch.cat([key, bias_k]) value = torch.cat([value, bias_v]) if attn_mask is not None: - _attn_mask = attn_mask - attn_mask = torch.nn.functional.pad(_attn_mask, (0, 1)) + attn_mask = torch.nn.functional.pad(attn_mask, (0, 1)) tgt_len, head_dim = query.size(-3), query.size(-1) assert query.size(-1) == key.size(-1) == value.size(-1), "The feature dim of query, key, value must be equal." @@ -166,7 +191,11 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, attn_output_weights = torch.nn.functional.softmax(attn_output_weights, dim=-1) attn_output_weights = torch.nn.functional.dropout(attn_output_weights, p=self.dropout, training=self.training) attn_output = torch.matmul(attn_output_weights, value) - return attn_output.transpose(-2, -3), attn_output_weights + + if self.batch_first: + return attn_output, attn_output_weights + else: + return attn_output.transpose(-3, -2), attn_output_weights class InProjContainer(torch.nn.Module): diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000000..283f8176f7 --- /dev/null +++ b/tox.ini @@ -0,0 +1,4 @@ +[flake8] +ignore = E401,E402,E722,W503,W504,F821,B006,B007,B008 +max-line-length = 120 +exclude = docs/source From 9d0c4e15c42cf9f0e460dfc0d0961f3411f1457f Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Wed, 5 Aug 2020 18:26:48 -0700 Subject: [PATCH 19/68] Remove .python3 markers Reviewed By: ashwinp-fb Differential Revision: D22955630 fbshipit-source-id: f00ef17a905e4c7cd9196c8924db39f9cdfe8cfa --- .python3 | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .python3 diff --git a/.python3 b/.python3 deleted file mode 100644 index e69de29bb2..0000000000 From 1a786ca7c3e282a369dccdd75bd22af581e9d31f Mon Sep 17 00:00:00 2001 From: Nayef Ahmed Date: Mon, 10 Aug 2020 07:42:15 -0700 Subject: [PATCH 20/68] Import torchtext 2020/08/06 Summary: Import from github torchtext/master Reviewed By: zhangguanheng66 Differential Revision: D22989210 fbshipit-source-id: 083464e188b758a8746123f4dd2197cc7edc4bc4 --- ...s.py => benchmark_experimental_vectors.py} | 16 +- ...cab.py => benchmark_experimental_vocab.py} | 0 benchmark/benchmark_pytext_vocab.py | 199 ++++++++++++ build_tools/setup_helpers/extension.py | 3 +- docs/source/experimental_vocab.rst | 20 ++ docs/source/index.rst | 1 + examples/BERT/{README.rst => README.md} | 33 +- examples/data_pipeline/README.md | 100 ++++++ examples/data_pipeline/dataset.py | 20 ++ examples/data_pipeline/pipelines.py | 166 ++++++++++ examples/data_pipeline/transforms.py | 102 ++++++ examples/vocab/pytext_vocab.py | 182 +++++++++++ test/data/test_functional.py | 93 ++---- test/experimental/test_vectors.py | 169 +++++----- torchtext/csrc/sentencepiece.cpp | 13 + torchtext/csrc/vectors.cpp | 292 ++++++++++++++++-- torchtext/experimental/transforms.py | 16 + torchtext/experimental/vectors.py | 126 ++------ 18 files changed, 1261 insertions(+), 290 deletions(-) rename benchmark/{experimental_vectors.py => benchmark_experimental_vectors.py} (81%) rename benchmark/{experimental_vocab.py => benchmark_experimental_vocab.py} (100%) create mode 100644 benchmark/benchmark_pytext_vocab.py create mode 100644 docs/source/experimental_vocab.rst rename examples/BERT/{README.rst => README.md} (93%) create mode 100644 examples/data_pipeline/README.md create mode 100644 examples/data_pipeline/dataset.py create mode 100644 examples/data_pipeline/pipelines.py create mode 100644 examples/data_pipeline/transforms.py create mode 100644 examples/vocab/pytext_vocab.py diff --git a/benchmark/experimental_vectors.py b/benchmark/benchmark_experimental_vectors.py similarity index 81% rename from benchmark/experimental_vectors.py rename to benchmark/benchmark_experimental_vectors.py index f7094d7d2b..f2e77b02bb 100644 --- a/benchmark/experimental_vectors.py +++ b/benchmark/benchmark_experimental_vectors.py @@ -3,6 +3,7 @@ import torch from torchtext.experimental.datasets import AG_NEWS from torchtext.experimental.vectors import FastText as FastTextExperimental + from torchtext.vocab import FastText @@ -21,23 +22,26 @@ def _run_benchmark_lookup(tokens, vector): tokens.append(vocab.itos[id]) # existing FastText construction - print("Existing FastText - Not Jit Mode") + print("FastText Existing Construction") t0 = time.monotonic() fast_text = FastText() print("Construction time:", time.monotonic() - t0) - _run_benchmark_lookup(tokens, fast_text) # experimental FastText construction - print("FastText Experimental") + print("FastText Experimental Construction") t0 = time.monotonic() fast_text_experimental = FastTextExperimental(validate_file=False) print("Construction time:", time.monotonic() - t0) - # not jit lookup - print("FastText Experimental - Not Jit Mode") + # existing FastText eager lookup + print("FastText Existing - Eager Mode") + _run_benchmark_lookup(tokens, fast_text) + + # experimental FastText eager lookup + print("FastText Experimental - Eager Mode") _run_benchmark_lookup(tokens, fast_text_experimental) - # jit lookup + # experimental FastText jit lookup print("FastText Experimental - Jit Mode") jit_fast_text_experimental = torch.jit.script(fast_text_experimental) _run_benchmark_lookup(tokens, jit_fast_text_experimental) diff --git a/benchmark/experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py similarity index 100% rename from benchmark/experimental_vocab.py rename to benchmark/benchmark_experimental_vocab.py diff --git a/benchmark/benchmark_pytext_vocab.py b/benchmark/benchmark_pytext_vocab.py new file mode 100644 index 0000000000..6dbe200fd4 --- /dev/null +++ b/benchmark/benchmark_pytext_vocab.py @@ -0,0 +1,199 @@ +import os +import sys +from collections import (Counter, OrderedDict) +import time +from typing import List, Union + +# this is needed because we want to add 'torchtext/examples/data_pipeline' directory to the +# `sys.path` variable in order to import the pytext_vocab (since its not a module) +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "examples", "vocab")) + +from pytext_vocab import ScriptVocab as ExperimentalScriptVocabulary +from pytext.torchscript.vocab import ScriptVocabulary as PytextScriptVocabulary +from pytext.data.utils import Vocabulary as PytextVocabulary +import torch +from torchtext.experimental.datasets import AG_NEWS + + +def _run_benchmark_lookup(tokens, vocab, num_iters=1): + def _run_benchmark_pytext_vocab(toks, v: PytextVocabulary): + for token_or_tokens_list in toks: + v.lookup_all(token_or_tokens_list) + + def _run_benchmark_pytext_script_vocab(toks, v: PytextScriptVocabulary): + # list lookup + if isinstance(toks, list) and isinstance(toks[0], list): + for tokens_list in toks: + v.lookup_indices_1d(tokens_list) + # single token lookup + elif isinstance(toks, list): + for token in toks: + v.lookup_indices_1d([token]) + else: + raise RuntimeError("Received tokens of incorrect type {}.".format(type(toks))) + + def _run_benchmark_experimental_script_vocab(toks, v: ExperimentalScriptVocabulary): + # list lookup + if isinstance(toks, list) and isinstance(toks[0], list): + for tokens_list in toks: + v.lookup_indices_1d(tokens_list) + # single token lookup + elif isinstance(toks, list): + for token in toks: + v[token] + else: + raise RuntimeError("Received tokens of incorrect type {}.".format(type(toks))) + + t0 = time.monotonic() + if isinstance(vocab, PytextVocabulary): + for _ in range(num_iters): + _run_benchmark_pytext_vocab(tokens, vocab) + elif isinstance(vocab, PytextScriptVocabulary): + for _ in range(num_iters): + _run_benchmark_pytext_script_vocab(tokens, vocab) + elif isinstance(vocab, (ExperimentalScriptVocabulary, torch.jit._script.RecursiveScriptModule)): + for _ in range(num_iters): + _run_benchmark_experimental_script_vocab(tokens, vocab) + else: + raise RuntimeError("Received vocab of incorrect type {}.".format(type(vocab))) + + print("Lookup time:", time.monotonic() - t0) + + +def _run_benchmark_lookup_jit_for_loop(tokens: Union[List[str], List[List[str]]], vocab, num_iters=1): + @torch.jit.script + def _run_benchmark_pytext_script_vocab(toks: List[str], v: PytextScriptVocabulary): + for token in toks: + v.lookup_indices_1d([token]) + + @torch.jit.script + def _run_benchmark_experimental_script_vocab(toks: List[str], v: ExperimentalScriptVocabulary): + for token in toks: + v[token] + + @torch.jit.script + def _run_benchmark_lists_pytext_script_vocab(tok_lists: List[List[str]], v: PytextScriptVocabulary): + for tokens_list in tok_lists: + v.lookup_indices_1d(tokens_list) + + @torch.jit.script + def _run_benchmark_lists_experimental_script_vocab(tok_lists: List[List[str]], v: ExperimentalScriptVocabulary): + for tokens_list in tok_lists: + v.lookup_indices_1d(tokens_list) + + t0 = time.monotonic() + # list lookup + if isinstance(tokens, list) and isinstance(tokens[0], list): + if isinstance(vocab, PytextScriptVocabulary): + for _ in range(num_iters): + _run_benchmark_lists_pytext_script_vocab(tokens, vocab) + elif isinstance(vocab, (ExperimentalScriptVocabulary, torch.jit._script.RecursiveScriptModule)): + + for _ in range(num_iters): + _run_benchmark_lists_experimental_script_vocab(tokens, vocab) + else: + raise RuntimeError("Received vocab of incorrect type {}.".format(type(vocab))) + # single token lookup + elif isinstance(tokens, list): + if isinstance(vocab, PytextScriptVocabulary): + for _ in range(num_iters): + _run_benchmark_pytext_script_vocab(tokens, vocab) + elif isinstance(vocab, (ExperimentalScriptVocabulary, torch.jit._script.RecursiveScriptModule)): + for _ in range(num_iters): + _run_benchmark_experimental_script_vocab(tokens, vocab) + else: + raise RuntimeError("Received vocab of incorrect type {}.".format(type(vocab))) + else: + raise RuntimeError("Received tokens of incorrect type {}.".format(type(tokens))) + + print("Lookup time:", time.monotonic() - t0) + + +def benchmark_experimental_vocab(): + train, = AG_NEWS(data_select='train') + vocab = train.get_vocab() + tokens: List[str] = [] + tokens_lists: List[List[str]] = [] + + for (_, text) in train: + cur_tokens = [] + for id in text.tolist(): + cur_tokens.append(vocab.itos[id]) + tokens_lists.append(cur_tokens) + tokens += cur_tokens + + print("Tokens size:", len(tokens)) + print("Tokens list size:", len(tokens_lists)) + + counter = Counter(tokens) + sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) + + vocab_list = [pair[0] for pair in sorted_by_freq_tuples] + vocab_list.insert(0, "") + ordered_dict = OrderedDict(sorted_by_freq_tuples) + + # pytext vocab construction + print("Pytext Vocabulary") + t0 = time.monotonic() + pytext_vocab = PytextVocabulary(vocab_list) + print("Construction time:", time.monotonic() - t0) + + # pytext ScriptVocab construction + print("Pytext Script Vocabulary") + t0 = time.monotonic() + pytext_script_vocab = PytextScriptVocabulary(vocab_list) + print("Construction time:", time.monotonic() - t0) + jit_pytext_script_vocab = torch.jit.script(pytext_script_vocab) + + # experimental ScriptVocab construction + print("Experimental Script Vocabulary") + t0 = time.monotonic() + experimental_script_vocab = ExperimentalScriptVocabulary(ordered_dict, unk_token="") + print("Construction time:", time.monotonic() - t0) + jit_experimental_script_vocab = torch.jit.script(experimental_script_vocab) + + # pytext Vocab eager lookup + print("Pytext Vocabulary - Eager Mode") + _run_benchmark_lookup(tokens, pytext_vocab) + _run_benchmark_lookup([tokens], pytext_vocab) + _run_benchmark_lookup(tokens_lists, pytext_vocab) + + # pytext ScriptVocab eager lookup + print("Pytext ScriptVocab - Eager Mode") + _run_benchmark_lookup(tokens, pytext_script_vocab) + _run_benchmark_lookup([tokens], pytext_script_vocab) + _run_benchmark_lookup(tokens_lists, pytext_script_vocab) + + # experimental ScriptVocab eager lookup + print("Experimental ScriptVocab - Eager Mode") + _run_benchmark_lookup(tokens, experimental_script_vocab) + _run_benchmark_lookup([tokens], experimental_script_vocab) + _run_benchmark_lookup(tokens_lists, experimental_script_vocab) + + # pytext ScriptVocab jit lookup + print("Pytext ScriptVocab - Jit Mode") + _run_benchmark_lookup(tokens, jit_pytext_script_vocab) + _run_benchmark_lookup([tokens], jit_pytext_script_vocab) + _run_benchmark_lookup(tokens_lists, jit_pytext_script_vocab) + + # experimental ScriptVocab jit lookup + print("Experimental ScriptVocab - Jit Mode") + _run_benchmark_lookup(tokens, jit_experimental_script_vocab) + _run_benchmark_lookup([tokens], jit_experimental_script_vocab) + _run_benchmark_lookup(tokens_lists, jit_experimental_script_vocab) + + # pytext ScriptVocab JITed for loop + print("Pytext ScriptVocab - Jit For Loop") + _run_benchmark_lookup_jit_for_loop(tokens, jit_pytext_script_vocab) + _run_benchmark_lookup_jit_for_loop([tokens], jit_pytext_script_vocab) + _run_benchmark_lookup_jit_for_loop(tokens_lists, jit_pytext_script_vocab) + + # experimental ScriptVocab JITed for loop + print("Experimental ScriptVocab - Jit For Loop") + _run_benchmark_lookup_jit_for_loop(tokens, jit_experimental_script_vocab) + _run_benchmark_lookup_jit_for_loop([tokens], jit_experimental_script_vocab) + _run_benchmark_lookup_jit_for_loop(tokens_lists, jit_experimental_script_vocab) + + +if __name__ == "__main__": + benchmark_experimental_vocab() diff --git a/build_tools/setup_helpers/extension.py b/build_tools/setup_helpers/extension.py index 6c70940f22..4223b398d2 100644 --- a/build_tools/setup_helpers/extension.py +++ b/build_tools/setup_helpers/extension.py @@ -79,7 +79,8 @@ def _get_libraries(): return [ 'sentencepiece_train', 'sentencepiece', - 're2' + 're2', + 'double-conversion' ] diff --git a/docs/source/experimental_vocab.rst b/docs/source/experimental_vocab.rst new file mode 100644 index 0000000000..9e485136f9 --- /dev/null +++ b/docs/source/experimental_vocab.rst @@ -0,0 +1,20 @@ +.. role:: hidden + :class: hidden-section + +torchtext.experimental.vocab +============================== + +.. automodule:: torchtext.experimental.vocab +.. currentmodule:: torchtext.experimental.vocab + +:hidden:`Vocab` +~~~~~~~~~~~~~~~~ + +.. autoclass:: Vocab + :members: + :special-members: + +:hidden:`vocab_from_file_object` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: vocab_from_file_object diff --git a/docs/source/index.rst b/docs/source/index.rst index 7e965e5abf..e1ce8cfd27 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -20,6 +20,7 @@ popular datasets for natural language. experimental_functional experimental_transforms experimental_vectors + experimental_vocab examples .. automodule:: torchtext diff --git a/examples/BERT/README.rst b/examples/BERT/README.md similarity index 93% rename from examples/BERT/README.rst rename to examples/BERT/README.md index 8cf0a55281..edde1c42b0 100644 --- a/examples/BERT/README.rst +++ b/examples/BERT/README.md @@ -1,11 +1,9 @@ -BERT with torchtext -+++++++++ +# BERT with torchtext This example shows how to train a BERT model with PyTorch and torchtext only. Then, we fine-tune the pre-trained BERT for the question-answer task. -Generate pre-trained BERT -------------------------- +## Generate pre-trained BERT Train the BERT model with masked language modeling task and next-sentence task. Run the tasks on a local GPU or CPU: @@ -21,8 +19,7 @@ or run the tasks on a SLURM powered cluster with Distributed Data Parallel (DDP) The result ppl of mlm_task is 18.97899 for the test set. The result loss of ns_task is 0.05446 for the test set. -Fine-tune pre-trained BERT for question-answer task ---------------------------------------------------- +## Fine-tune pre-trained BERT for question-answer task With SQuAD dataset, the pre-trained BERT is used for question-answer task: @@ -30,9 +27,9 @@ With SQuAD dataset, the pre-trained BERT is used for question-answer task: The pre-trained BERT models and vocab are available: -* `bert_vocab.pt `_ -* `mlm_bert.pt `_ -* `ns_bert.pt `_ +* [bert_vocab.pt](https://pytorch.s3.amazonaws.com/models/text/torchtext_bert_example/bert_vocab.pt) +* [mlm_bert.pt](https://pytorch.s3.amazonaws.com/models/text/torchtext_bert_example/mlm_bert.pt) +* [ns_bert.pt](https://pytorch.s3.amazonaws.com/models/text/torchtext_bert_example/ns_bert.pt) An example train/valid/test printout with the pretrained BERT model in question-answer task: @@ -120,33 +117,27 @@ An example train/valid/test printout with the pretrained BERT model in question- | End of training | test loss 2.05 | exact 51.337% | f1 63.645% ========================================================================================= -Structure of the example -======================== +## Structure of the example -model.py --------- +### model.py This file defines the Transformer and MultiheadAttention models used for BERT. The embedding layer include PositionalEncoding and TokenTypeEncoding layers. MLMTask, NextSentenceTask, and QuestionAnswerTask are the models for the three tasks mentioned above. -data.py -------- +### data.py This file provides a few datasets required to train the BERT model and question-answer task. Please note that BookCorpus dataset is not available publicly. -mlm_task.py, ns_task.py, qa_task.py ------------------------------------ +### mlm_task.py, ns_task.py, qa_task.py Those three files define the train/valid/test process for the tasks. -metrics.py ----------- +### metrics.py This file provides two metrics (F1 and exact score) for question-answer task -utils.py --------- +### utils.py This file provides a few utils used by the three tasks. diff --git a/examples/data_pipeline/README.md b/examples/data_pipeline/README.md new file mode 100644 index 0000000000..440586c075 --- /dev/null +++ b/examples/data_pipeline/README.md @@ -0,0 +1,100 @@ +# Data processing pipelines with torchtext + +This example shows a few data processing pipelines with the building blocks (like tokenizer, vocab). The raw text data from `torchtext.experimental.datasets.raw.text_classification` are used as the inputs for performance benchmark. We also enable the JIT support if possible. + + +## SentencePiece + +This pipeline example shows the application with a pretrained sentencepiece model saved in `m_user.model`. The model is loaded to build tokenizer and vocabulary and the pipeline is composed of: + +* `PretrainedSPTokenizer` +* `PretrainedSPVocab` backed by `torchtext.experimental.vocab.Vocab` +* `ToLongTensor` to convert a list of integers to `torch.tensor` + +The command to run the pipeline: + + python pipelines.py --pipeline sentencepiece + +The lookup time: 25.09393248707056 (eager mode) vs. 18.71099873096682 (jit mode) + + +## Vocab from a text file + +This pipeline example shows the application with the vocab text file from Hugging Face ([link](https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-uncased-vocab.txt)). The experimental vocab in torchtext library is used here: + +* `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library +* `torchtext.experimental.vocab.Vocab` +* `ToLongTensor` to convert a list of integers to `torch.tensor` + +The command to run the pipeline: + + python pipelines.py --pipeline text_vocab + +The lookup time: 45.7489246588666 (eager mode) vs. 30.990019195945933 (jit mode) + + +## PyText + +This pipeline example shows the application with the existing `ScriptVocab` in pytext library. The `ScriptVocab` instance is built from a text file where a column of vocab tokens are read in sequence. + +* `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library +* `from pytext.torchscript.vocab.ScriptVocabulary` +* `ToLongTensor` to convert a list of integers to `torch.tensor` + +With the dependency of `pytext` library, the command to run the pipeline: + + python pipelines.py --pipeline pytext + +The lookup time: 43.51164810406044 (eager mode) vs. 26.57643914804794 (jit mode) + + +## Torchtext + +This pipeline example shows the application with the existing `Vocab` in torchtext library. The `Vocab` instance is built from a text file where a column of vocab tokens are read in sequence. + +* `basic_english` func from `torchtext.data.utils.get_tokenizer` +* `torchtext.vocab.Vocab` +* `torchtext.experimental.functional.totensor` to convert a list of integers to `torch.tensor` + +The command to run the pipeline: + + python pipelines.py --pipeline torchtext + +The lookup time: 6.821685338858515 (eager mode) + + +## Torchtext with a batch of data + +This pipeline example shows the application with the data batch as input. For the real-world text classification task, two separate pipelines are created for text and label. + +For the text pipeline: + +* `basic_english` func from `torchtext.data.utils.get_tokenizer` +* `torchtext.vocab.Vocab` +* `torchtext.experimental.functional.totensor` to convert a list of integers to `torch.tensor` + +For the label pipeline: + +* `torchtext.experimental.functional.totensor` to convert a list of strings to `torch.tensor` + +And the text and label pipeline are passed to TextClassificationPipeline. Since the incoming data are in the form of a batch, `run_batch_benchmark_lookup` func uses python built-in `map()` func to process a batch of raw text data according the pipeline. + +The command to run the pipeline: + + python pipelines.py --pipeline batch_torchtext + +The lookup time: 7.915330206044018 (eager mode) + + +## FastText pretrained word vectors + +This pipeline example shows the application with the pretained word vector from FastText: + +* `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library +* `torchtext.experimental.vectors.FastText` + +The command to run the pipeline: + + python pipelines.py --pipeline fasttext + +The lookup time: 45.74515324481763 (eager mode) vs. 32.64012925699353 (jit mode) diff --git a/examples/data_pipeline/dataset.py b/examples/data_pipeline/dataset.py new file mode 100644 index 0000000000..b166ef9e8f --- /dev/null +++ b/examples/data_pipeline/dataset.py @@ -0,0 +1,20 @@ +import torch +from torchtext.experimental.datasets.raw import text_classification as raw + + +class BatchTextClassificationData(torch.utils.data.IterableDataset): + + def __init__(self, dataset_name, batch_size=16): + super(BatchTextClassificationData, self).__init__() + self._iterator = raw.DATASETS[dataset_name]()[0] # Load train dataset only + self.batch_size = batch_size + + def __iter__(self): + _data = [] + for i, item in enumerate(self._iterator): + _data.append(item) + if len(_data) >= self.batch_size: + yield _data + _data = [] + if len(_data) > 0: + yield _data diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py new file mode 100644 index 0000000000..9af5e7efe0 --- /dev/null +++ b/examples/data_pipeline/pipelines.py @@ -0,0 +1,166 @@ +import torch +from transforms import ( + PretrainedSPTokenizer, + PretrainedSPVocab, + VocabTransform, + PyTextVocabTransform, + VectorTransform, + ToLongTensor, +) +from torchtext.experimental.transforms import ( + BasicEnglishNormalize, + TextSequentialTransforms, +) +from torchtext.experimental.vocab import vocab_from_file_object +from torchtext.experimental.vectors import FastText +import argparse +from torchtext.experimental.datasets.raw import text_classification as raw +import time +from dataset import BatchTextClassificationData + + +def build_sp_pipeline(spm_file): + tokenizer = PretrainedSPTokenizer(spm_file) + vocab = PretrainedSPVocab(spm_file) + + # Insert token in vocab to match a pretrained vocab + vocab.insert_token('', 1) + pipeline = TextSequentialTransforms(tokenizer, vocab, ToLongTensor()) + jit_pipeline = torch.jit.script(pipeline) + print('jit sentencepiece pipeline success!') + return pipeline, jit_pipeline + + +def build_torchtext_vocab(vocab_file): + from torchtext.data.utils import get_tokenizer + tokenizer = get_tokenizer("basic_english") + from torchtext.vocab import build_vocab_from_iterator + from torchtext.experimental.functional import totensor, vocab_func, sequential_transforms + + def token_iterator(vocab_file): + f = open(vocab_file, 'r') + for token in f: + yield token + vocab = build_vocab_from_iterator(token_iterator(vocab_file)) + pipeline = sequential_transforms(tokenizer, vocab_func(vocab), totensor(dtype=torch.long)) + return pipeline, None + + +def build_batch_torchtext_vocab(vocab_file): + from torchtext.data.utils import get_tokenizer + tokenizer = get_tokenizer("basic_english") + from torchtext.vocab import build_vocab_from_iterator + from transforms import TextClassificationPipeline + from torchtext.experimental.functional import totensor, vocab_func, sequential_transforms + + def token_iterator(vocab_file): + f = open(vocab_file, 'r') + for token in f: + yield token + vocab = build_vocab_from_iterator(token_iterator(vocab_file)) + text_pipeline = sequential_transforms(tokenizer, vocab_func(vocab), totensor(dtype=torch.long)) + label_pipeline = totensor(dtype=torch.long) + return TextClassificationPipeline(label_pipeline, text_pipeline), None + + +def build_text_vocab_pipeline(hf_vocab_file): + tokenizer = BasicEnglishNormalize() + f = open(hf_vocab_file, 'r') + vocab = vocab_from_file_object(f) + + # Insert token in vocab to match a pretrained vocab + pipeline = TextSequentialTransforms(tokenizer, VocabTransform(vocab), ToLongTensor()) + jit_pipeline = torch.jit.script(pipeline) + print('jit Hugging Face pipeline success!') + return pipeline, jit_pipeline + + +def build_pytext_vocab_pipeline(vocab_file): + from pytext.torchscript.vocab import ScriptVocabulary + tokenizer = BasicEnglishNormalize() + f = open(vocab_file, 'r') + vocab_list = [line.rstrip() for line in f] + + # Insert token in vocab to match a pretrained vocab + pipeline = TextSequentialTransforms(tokenizer, + PyTextVocabTransform(ScriptVocabulary(vocab_list)), + ToLongTensor()) + jit_pipeline = torch.jit.script(pipeline) + print('jit PyText pipeline success!') + return pipeline, jit_pipeline + + +def build_fasttext_vector_pipeline(): + tokenizer = BasicEnglishNormalize() + vector = FastText() + + # Insert token in vocab to match a pretrained vocab + pipeline = TextSequentialTransforms(tokenizer, VectorTransform(vector)) + jit_pipeline = torch.jit.script(pipeline) + print('jit fasttext pipeline success!') + return pipeline, jit_pipeline + + +def run_benchmark_lookup(text_classification_dataset, pipeline): + t0 = time.monotonic() + for (label, text) in text_classification_dataset: + text = pipeline(text) + print("Lookup time:", time.monotonic() - t0) + + +def run_batch_benchmark_lookup(text_classification_dataset, pipeline): + t0 = time.monotonic() + for items in text_classification_dataset: + items = list(map(pipeline, items)) + print("Lookup time:", time.monotonic() - t0) + + +def generate_dataset(args): + if args.pipeline == 'batch_torchtext': + train = BatchTextClassificationData(args.dataset) + test = None + else: + train, test = raw.DATASETS[args.dataset]() + return train, test + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Data procesing pipelines') + parser.add_argument('--pipeline', type=str, default='sentencepiece', + help='The name of pipeline') + parser.add_argument('--dataset', type=str, default='AG_NEWS', + help='Dataset for performance benchmark') + parser.add_argument('--spm-filename', type=str, default='m_user.model', + help='The filename of sentencepiece model') + parser.add_argument('--vocab-filename', type=str, default='vocab.txt', + help='The name of vocab filename') + args = parser.parse_args() + + if args.pipeline == 'sentencepiece': + pipeline, jit_pipeline = build_sp_pipeline(args.spm_filename) + elif args.pipeline == 'text_vocab': + pipeline, jit_pipeline = build_text_vocab_pipeline(args.vocab_filename) + elif args.pipeline == 'pytext': + pipeline, jit_pipeline = build_pytext_vocab_pipeline(args.vocab_filename) + elif args.pipeline == 'fasttext': + pipeline, jit_pipeline = build_fasttext_vector_pipeline() + elif args.pipeline == 'torchtext': + pipeline, jit_pipeline = build_torchtext_vocab(args.vocab_filename) + elif args.pipeline == 'batch_torchtext': + pipeline, jit_pipeline = build_batch_torchtext_vocab(args.vocab_filename) + else: + print("pipeline is not supported. Current pipelines include sentencepiece, text_vocab, " + + "fasttext, pytext, fasttext, torchtext, batch_torchtext") + + if pipeline is not None: + print("Test eager mode for pipeline", args.pipeline) + train, test = generate_dataset(args) + if args.pipeline == 'batch_torchtext': + run_batch_benchmark_lookup(train, pipeline) + else: + run_benchmark_lookup(train, pipeline) + + if jit_pipeline is not None: + print("Test jit mode for pipeline", args.pipeline) + train, test = generate_dataset(args) + run_benchmark_lookup(train, jit_pipeline) diff --git a/examples/data_pipeline/transforms.py b/examples/data_pipeline/transforms.py new file mode 100644 index 0000000000..8a88c22479 --- /dev/null +++ b/examples/data_pipeline/transforms.py @@ -0,0 +1,102 @@ +import torch.nn as nn +from torchtext.data.functional import load_sp_model +from torchtext.experimental.vocab import Vocab +from typing import List +from collections import OrderedDict +import torch +from torch import Tensor + + +class TextClassificationPipeline(nn.Module): + r"""Text classification pipeline template + """ + + def __init__(self, label_transform, text_transform): + super(TextClassificationPipeline, self).__init__() + self.label_transform = label_transform + self.text_transform = text_transform + + def forward(self, label_text_tuple): + return self.label_transform(label_text_tuple[0]), self.text_transform(label_text_tuple[1]) + + +class PretrainedSPTokenizer(nn.Module): + r"""Tokenizer based on a pretained sentencepiece model + """ + + def __init__(self, spm_file): + super(PretrainedSPTokenizer, self).__init__() + self.sp_model = load_sp_model(spm_file) + + def forward(self, line: str) -> List[str]: + r""" + + """ + + return self.sp_model.EncodeAsPieces(line) + + +class PretrainedSPVocab(nn.Module): + r"""Vocab based on a pretained sentencepiece model + """ + + def __init__(self, spm_file): + super(PretrainedSPVocab, self).__init__() + self.sp_model = load_sp_model(spm_file) + unk_id = self.sp_model.unk_id() + unk_token = self.sp_model.IdToPiece(unk_id) + vocab_list = [self.sp_model.IdToPiece(i) for i in range(self.sp_model.GetPieceSize())] + self.vocab = Vocab(OrderedDict([(token, 1) for token in vocab_list]), unk_token=unk_token) + + def forward(self, tokens: List[str]) -> List[int]: + return self.vocab.lookup_indices(tokens) + + def insert_token(self, token: str, index: int) -> None: + self.vocab.insert_token(token, index) + + +class VocabTransform(nn.Module): + r"""Vocab transform + """ + + def __init__(self, vocab): + super(VocabTransform, self).__init__() + self.vocab = vocab + + def forward(self, tokens: List[str]) -> List[int]: + return self.vocab.lookup_indices(tokens) + + +class PyTextVocabTransform(nn.Module): + r"""Vocab transform + """ + + def __init__(self, vocab): + super(PyTextVocabTransform, self).__init__() + self.vocab = vocab + + def forward(self, tokens: List[str]) -> List[int]: + return self.vocab.lookup_indices_1d(tokens) + + +class VectorTransform(nn.Module): + r"""Vector transform + """ + + def __init__(self, vector): + super(VectorTransform, self).__init__() + self.vector = vector + + def forward(self, tokens: List[str]) -> Tensor: + return self.vector.lookup_vectors(tokens) + + +class ToLongTensor(nn.Module): + r"""Convert a list of integers to long tensor + """ + + def __init__(self): + super(ToLongTensor, self).__init__() + + def forward(self, tokens: List[int]) -> Tensor: + return torch.tensor(tokens).to(torch.long) diff --git a/examples/vocab/pytext_vocab.py b/examples/vocab/pytext_vocab.py new file mode 100644 index 0000000000..9050696dc9 --- /dev/null +++ b/examples/vocab/pytext_vocab.py @@ -0,0 +1,182 @@ +from collections import OrderedDict + +from fairseq.data.dictionary import Dictionary +import torch +from torchtext.experimental.vocab import Vocab +from typing import Dict, List, Optional + + +def build_fairseq_vocab( + vocab_file: str, + dictionary_class: Dictionary = Dictionary, + special_token_replacements: Dict[str, str] = None, + unk_token: str = "", + max_vocab: int = -1, + min_count: int = -1, + tokens_to_add: Optional[List[str]] = None, +): + """Function builds a torchtext Vocab for models pre-trained using Fairseq + modules. + + The dictionary class can take any Fairseq Dictionary class and is + used to load the vocab file. + + """ + if not special_token_replacements: + special_token_replacements = { + "": "__PAD__", + "": "__BEGIN_OF_SENTENCE__", + "": "__END_OF_SENTENCE__", + "": "__UNKNOWN__", + "": "__MASK__", + } + unk_replacement = special_token_replacements[unk_token] if unk_token in special_token_replacements else unk_token + special_tokens_to_remove = [special_pair[0] for special_pair in special_token_replacements] + special_tokens_to_add = tuple(special_pair[1] for special_pair in special_token_replacements if special_pair[0] != unk_token) + + with open(vocab_file) as f: + dictionary = dictionary_class.load(f) + # finalize will sort the dict based on frequency so only do this if + # a min_count or max_vocab size is specified + if min_count > 0 or max_vocab > 0: + dictionary.finalize(threshold=min_count, nwords=max_vocab, padding_factor=1) + if tokens_to_add: + for token in tokens_to_add: + dictionary.add_symbol(token) + + dictionary_items = list(zip(dictionary.symbols, dictionary.count)) + + ordered_dict = OrderedDict() + # add special tokens to beginning of ordered_dict + for s in special_tokens_to_add: + ordered_dict[s] = 1 + + # add all other tokens from dictionary_items + for token, freq in dictionary_items: + ordered_dict[token] = freq + + # remove special_tokens_to_remove from dict + for s in special_tokens_to_remove: + if s in ordered_dict: + del ordered_dict[s] + + return Vocab(dictionary_items, unk_token=unk_replacement) + + +class ScriptVocab(Vocab): + r"""Creates a script vocab object which maps tokens to indices. + + Examples: + >>> token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + >>> sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + >>> c = OrderedDict(sorted_by_freq_tuples) + + >>> v = ScriptVocab(c) + >>> v = torch.jit.script(v) + + >>> print(v.lookup_word(0, possible_unk_token='unk')) + >>> print(v.lookup_indices_1d(['not_present', 'world', 'hello'])) + >>> print(v.lookup_indices_2d([['not_present', 'world', 'hello']])) + >>> print(v.lookup_words_1d(torch.tensor([0, 1, 2], dtype=torch.int32), [2])) + >>> print(v.lookup_words_1d_cycle_heuristic(torch.tensor([0, 1, 2, 0], dtype=torch.int32), [2], ['unk_a', 'unk_b'])) + >>> print(v.unk_idx, v.pad_idx, v.bos_idx, v.eos_idx, v.mask_idx) + """ + def __init__(self, + ordered_dict, + pad_token=None, + bos_token=None, + eos_token=None, + mask_token=None, + **kwargs): + super(ScriptVocab, self).__init__(ordered_dict, **kwargs) + self.unk_token: str = kwargs.get('unk_token', '') + + # init all special token indices + self.unk_idx: int = self.vocab[self.unk_token] + self.pad_idx: int = self.vocab[pad_token] if pad_token and self.vocab[pad_token] != self.unk_idx else -1 + self.bos_idx: int = self.vocab[bos_token] if bos_token and self.vocab[bos_token] != self.unk_idx else -1 + self.eos_idx: int = self.vocab[eos_token] if eos_token and self.vocab[eos_token] != self.unk_idx else -1 + self.mask_idx: int = self.vocab[mask_token] if mask_token and self.vocab[mask_token] != self.unk_idx else -1 + + @torch.jit.export + def lookup_indices_1d(self, values: List[str]) -> List[int]: + lookup_indices = self.lookup_indices(values) + return lookup_indices + + @torch.jit.export + def lookup_indices_2d(self, values: List[List[str]]) -> List[List[int]]: + result: List[List[int]] = [] + for value in values: + result.append(self.lookup_indices(value)) + return result + + @torch.jit.export + def lookup_word(self, idx: int, possible_unk_token: Optional[str] = None) -> str: + # print(idx, possible_unk_token) + word = self.lookup_token(idx) + print(word, self.unk_token) + if word != self.unk_token or possible_unk_token is None: + return word + return possible_unk_token + + @torch.jit.export + def lookup_words_1d( + self, + values: torch.Tensor, + filter_token_list: List[int] = (), + possible_unk_token: Optional[str] = None, + ) -> List[str]: + """If possible_unk_token is not None, then all UNK id's will be + replaced by possible_unk_token instead of the default UNK string which + is . + + This is a simple way to resolve UNK's when there's a + correspondence between source and target translations. + + """ + result: List[str] = [] + for idx in range(values.size(0)): + value = int(values[idx]) + if value not in filter_token_list: + token = self.lookup_token(value) + if token != self.unk_token or possible_unk_token is None: + result.append(token) + else: + result.append(possible_unk_token) + return result + + @torch.jit.export + def lookup_words_1d_cycle_heuristic( + self, + values: torch.Tensor, + filter_token_list: List[int], + ordered_unks_token: List[str], + ) -> List[str]: + """This function is a extension of the possible_unk_token heuristic in + lookup_words_1d, which fails in the case when multiple unks are + available. + + The way we deal with this is we increment every unk token in + ordered_unks_token everytime we substitute an unk token. This + solves a substantial amount of queries with multiple unk tokens. + + """ + unk_idx = 0 + unk_idx_length = len(ordered_unks_token) + vocab_length = len(self.vocab) + unk_copy = unk_idx_length != 0 + + result: List[str] = [] + for idx in range(values.size(0)): + value = int(values[idx]) + if value not in filter_token_list: + if value < vocab_length and value != self.unk_idx: + result.append(self.lookup_token(value)) + else: + if not unk_copy: + result.append(self.unk_token) + else: + unk_value = ordered_unks_token[unk_idx % unk_idx_length] + result.append(unk_value) + unk_idx += 1 + return result diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 9b93580f72..ce91ab48b1 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -1,8 +1,9 @@ import os -import uuid +import platform import shutil -import unittest import tempfile +import uuid +import unittest import sentencepiece as spm import torch @@ -79,76 +80,44 @@ def test_sentencepiece_tokenizer(self): self.assertEqual(list(spm_generator([test_sample]))[0], ref_results) - # TODO(Nayef211): uncomment and replace the test below with this once - # https://github.com/pytorch/pytorch/issues/38207 is closed - # def test_BasicEnglishNormalize(self): - # test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' - # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', - # 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] - - # basic_english_normalize = BasicEnglishNormalize() - # experimental_eager_tokens = basic_english_normalize(test_sample) - - # jit_basic_english_normalize = torch.jit.script(basic_english_normalize) - # experimental_jit_tokens = jit_basic_english_normalize(test_sample) - - # basic_english_tokenizer = data.get_tokenizer("basic_english") - # eager_tokens = basic_english_tokenizer(test_sample) - - # self.assertEqual(experimental_jit_tokens, ref_results) - # self.assertEqual(experimental_jit_tokens, eager_tokens) - # self.assertEqual(experimental_jit_tokens, experimental_eager_tokens) - + # TODO(Nayef211): remove decorator once # https://github.com/pytorch/pytorch/issues/38207 is closed + @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_BasicEnglishNormalize(self): - test_sample = 'Basic English Normalization for a Line of Text' - ref_results = ['basic', 'english', 'normalization', - 'for', 'a', 'line', 'of', 'text'] + test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' + ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', + 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] basic_english_normalize = BasicEnglishNormalize() experimental_eager_tokens = basic_english_normalize(test_sample) + jit_basic_english_normalize = torch.jit.script(basic_english_normalize) + experimental_jit_tokens = jit_basic_english_normalize(test_sample) + basic_english_tokenizer = data.get_tokenizer("basic_english") - tokens_eager = basic_english_tokenizer(test_sample) - - self.assertEqual(experimental_eager_tokens, ref_results) - self.assertEqual(experimental_eager_tokens, tokens_eager) - - # TODO(Nayef211): uncomment and replace the test below with this once - # https://github.com/pytorch/pytorch/issues/38207 is closed - # def test_RegexTokenizer(self): - # test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' - # ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', - # 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] - # patterns_list = [ - # (r'\'', ' \' '), - # (r'\"', ''), - # (r'\.', ' . '), - # (r'
', ' '), - # (r',', ' , '), - # (r'\(', ' ( '), - # (r'\)', ' ) '), - # (r'\!', ' ! '), - # (r'\?', ' ? '), - # (r'\;', ' '), - # (r'\:', ' '), - # (r'\s+', ' ')] - - # regex_tokenizer = RegexTokenizer(patterns_list) - # eager_tokens = regex_tokenizer(test_sample) - - # jit_regex_tokenizer = torch.jit.script(regex_tokenizer) - # jit_tokens = jit_regex_tokenizer(test_sample) - - # self.assertEqual(jit_tokens, ref_results) - # self.assertEqual(jit_tokens, eager_tokens) + eager_tokens = basic_english_tokenizer(test_sample) + self.assertEqual(experimental_jit_tokens, ref_results) + self.assertEqual(experimental_jit_tokens, eager_tokens) + self.assertEqual(experimental_jit_tokens, experimental_eager_tokens) + + # TODO(Nayef211): remove decorator once # https://github.com/pytorch/pytorch/issues/38207 is closed + @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_RegexTokenizer(self): - test_sample = '"Basic Regex Tokenization". For a Line of Text' - ref_results = ['Basic', 'Regex', 'Tokenization', '.', - 'For', 'a', 'Line', 'of', 'Text'] + test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' + ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', + 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] patterns_list = [ + (r'\'', ' \' '), (r'\"', ''), (r'\.', ' . '), + (r'
', ' '), + (r',', ' , '), + (r'\(', ' ( '), + (r'\)', ' ) '), + (r'\!', ' ! '), + (r'\?', ' ? '), + (r'\;', ' '), + (r'\:', ' '), (r'\s+', ' ')] regex_tokenizer = RegexTokenizer(patterns_list) @@ -157,8 +126,8 @@ def test_RegexTokenizer(self): jit_regex_tokenizer = torch.jit.script(regex_tokenizer) jit_tokens = jit_regex_tokenizer(test_sample) - self.assertEqual(jit_tokens, eager_tokens) self.assertEqual(jit_tokens, ref_results) + self.assertEqual(jit_tokens, eager_tokens) def test_custom_replace(self): custom_replace_transform = custom_replace([(r'S', 's'), (r'\s+', ' ')]) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 7769156f7f..371ccecf5b 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -10,7 +10,7 @@ from torchtext.experimental.vectors import ( FastText, GloVe, - Vectors, + vectors, vectors_from_file_object ) @@ -23,10 +23,10 @@ def tearDown(self): def test_empty_vectors(self): tokens = [] - vectors = torch.empty(0, dtype=torch.float) + vecs = torch.empty(0, dtype=torch.float) unk_tensor = torch.tensor([0], dtype=torch.float) - vectors_obj = Vectors(tokens, vectors, unk_tensor) + vectors_obj = vectors(tokens, vecs, unk_tensor) self.assertEqual(vectors_obj['not_in_it'], unk_tensor) def test_empty_unk(self): @@ -34,8 +34,8 @@ def test_empty_unk(self): expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a'] - vectors = tensorA.unsqueeze(0) - vectors_obj = Vectors(tokens, vectors) + vecs = tensorA.unsqueeze(0) + vectors_obj = vectors(tokens, vecs) self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) @@ -45,8 +45,8 @@ def test_vectors_basic(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] - vectors = torch.stack((tensorA, tensorB), 0) - vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + vecs = torch.stack((tensorA, tensorB), 0) + vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) self.assertEqual(vectors_obj['a'], tensorA) self.assertEqual(vectors_obj['b'], tensorB) @@ -58,8 +58,8 @@ def test_vectors_jit(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] - vectors = torch.stack((tensorA, tensorB), 0) - vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + vecs = torch.stack((tensorA, tensorB), 0) + vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) jit_vectors_obj = torch.jit.script(vectors_obj) self.assertEqual(vectors_obj['a'], jit_vectors_obj['a']) @@ -72,8 +72,8 @@ def test_vectors_lookup_vectors(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] - vectors = torch.stack((tensorA, tensorB), 0) - vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + vecs = torch.stack((tensorA, tensorB), 0) + vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) tokens_to_lookup = ['a', 'b', 'c'] expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) @@ -86,9 +86,8 @@ def test_vectors_add_item(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a'] - vectors = tensorA.unsqueeze(0) - print(vectors) - vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + vecs = tensorA.unsqueeze(0) + vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) tensorB = torch.tensor([0, 1], dtype=torch.float) vectors_obj['b'] = tensorB @@ -99,54 +98,59 @@ def test_vectors_add_item(self): def test_vectors_load_and_save(self): tensorA = torch.tensor([1, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1], dtype=torch.float) expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) - tokens = ['a'] - vectors = tensorA.unsqueeze(0) - vectors_obj = Vectors(tokens, vectors) + tokens = ['a', 'b'] + vecs = torch.stack((tensorA, tensorB), 0) + vectors_obj = vectors(tokens, vecs) + + tensorC = torch.tensor([1, 1], dtype=torch.float) + vectors_obj['b'] = tensorC vector_path = os.path.join(self.test_dir, 'vectors.pt') torch.save(vectors_obj, vector_path) loaded_vectors_obj = torch.load(vector_path) self.assertEqual(loaded_vectors_obj['a'], tensorA) + self.assertEqual(loaded_vectors_obj['b'], tensorC) self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) def test_errors(self): tokens = [] - vectors = torch.empty(0, dtype=torch.float) + vecs = torch.empty(0, dtype=torch.float) with self.assertRaises(ValueError): # Test proper error raised when passing in empty tokens and vectors and # not passing in a user defined unk_tensor - Vectors(tokens, vectors) + vectors(tokens, vecs) tensorA = torch.tensor([1, 0, 0], dtype=torch.float) tensorB = torch.tensor([0, 1, 0], dtype=torch.float) tokens = ['a', 'b', 'c'] - vectors = torch.stack((tensorA, tensorB,), 0) + vecs = torch.stack((tensorA, tensorB,), 0) with self.assertRaises(RuntimeError): # Test proper error raised when tokens and vectors have different sizes - Vectors(tokens, vectors) + vectors(tokens, vecs) tensorC = torch.tensor([0, 0, 1], dtype=torch.float) tokens = ['a', 'a', 'c'] - vectors = torch.stack((tensorA, tensorB, tensorC), 0) + vecs = torch.stack((tensorA, tensorB, tensorC), 0) with self.assertRaises(RuntimeError): # Test proper error raised when tokens have duplicates # TODO (Nayef211): use self.assertRaisesRegex() to check # the key of the duplicate token in the error message - Vectors(tokens, vectors) + vectors(tokens, vecs) tensorC = torch.tensor([0, 0, 1], dtype=torch.int8) tokens = ['a'] - vectors = tensorC.unsqueeze(0) + vecs = tensorC.unsqueeze(0) with self.assertRaises(TypeError): # Test proper error raised when vector is not of type torch.float - Vectors(tokens, vectors) + vectors(tokens, vecs) with tempfile.TemporaryDirectory() as dir_name: # Test proper error raised when incorrect filename or dim passed into GloVe @@ -199,61 +203,60 @@ def test_fast_text(self): self.assertEqual(vectors_obj[word][:3], expected_fasttext_simple_en[word]) self.assertEqual(jit_vectors_obj[word][:3], expected_fasttext_simple_en[word]) - # TODO: reenable test once the GloVe dataset url starts working - # def test_glove(self): - # # copy the asset file into the expected download location - # # note that this is just a zip file with the first 100 entries of the GloVe 840B dataset - # asset_name = 'glove.840B.300d.zip' - # asset_path = get_asset_path(asset_name) - - # with tempfile.TemporaryDirectory() as dir_name: - # data_path = os.path.join(dir_name, asset_name) - # shutil.copy(asset_path, data_path) - # vectors_obj = GloVe(root=dir_name, validate_file=False) - # jit_vectors_obj = torch.jit.script(vectors_obj) - - # # The first 3 entries in each vector. - # expected_glove = { - # 'the': [0.27204, -0.06203, -0.1884], - # 'people': [-0.19686, 0.11579, -0.41091], - # } - - # for word in expected_glove.keys(): - # self.assertEqual(vectors_obj[word][:3], expected_glove[word]) - # self.assertEqual(jit_vectors_obj[word][:3], expected_glove[word]) - - # def test_glove_different_dims(self): - # # copy the asset file into the expected download location - # # note that this is just a zip file with 1 line txt files used to test that the - # # correct files are being loaded - # asset_name = 'glove.6B.zip' - # asset_path = get_asset_path(asset_name) - - # with tempfile.TemporaryDirectory() as dir_name: - # data_path = os.path.join(dir_name, asset_name) - # shutil.copy(asset_path, data_path) - - # glove_50d = GloVe(name='6B', dim=50, root=dir_name, validate_file=False) - # glove_100d = GloVe(name='6B', dim=100, root=dir_name, validate_file=False) - # glove_200d = GloVe(name='6B', dim=200, root=dir_name, validate_file=False) - # glove_300d = GloVe(name='6B', dim=300, root=dir_name, validate_file=False) - # vectors_objects = [glove_50d, glove_100d, glove_200d, glove_300d] - - # # The first 3 entries in each vector. - # expected_glove_50d = { - # 'the': [0.418, 0.24968, -0.41242], - # } - # expected_glove_100d = { - # 'the': [-0.038194, -0.24487, 0.72812], - # } - # expected_glove_200d = { - # 'the': [-0.071549, 0.093459, 0.023738], - # } - # expected_glove_300d = { - # 'the': [0.04656, 0.21318, -0.0074364], - # } - # expected_gloves = [expected_glove_50d, expected_glove_100d, expected_glove_200d, expected_glove_300d] - - # for vectors_obj, expected_glove in zip(vectors_objects, expected_gloves): - # for word in expected_glove.keys(): - # self.assertEqual(vectors_obj[word][:3], expected_glove[word]) + def test_glove(self): + # copy the asset file into the expected download location + # note that this is just a zip file with the first 100 entries of the GloVe 840B dataset + asset_name = 'glove.840B.300d.zip' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + vectors_obj = GloVe(root=dir_name, validate_file=False) + jit_vectors_obj = torch.jit.script(vectors_obj) + + # The first 3 entries in each vector. + expected_glove = { + 'the': [0.27204, -0.06203, -0.1884], + 'people': [-0.19686, 0.11579, -0.41091], + } + + for word in expected_glove.keys(): + self.assertEqual(vectors_obj[word][:3], expected_glove[word]) + self.assertEqual(jit_vectors_obj[word][:3], expected_glove[word]) + + def test_glove_different_dims(self): + # copy the asset file into the expected download location + # note that this is just a zip file with 1 line txt files used to test that the + # correct files are being loaded + asset_name = 'glove.6B.zip' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + + glove_50d = GloVe(name='6B', dim=50, root=dir_name, validate_file=False) + glove_100d = GloVe(name='6B', dim=100, root=dir_name, validate_file=False) + glove_200d = GloVe(name='6B', dim=200, root=dir_name, validate_file=False) + glove_300d = GloVe(name='6B', dim=300, root=dir_name, validate_file=False) + vectors_objects = [glove_50d, glove_100d, glove_200d, glove_300d] + + # The first 3 entries in each vector. + expected_glove_50d = { + 'the': [0.418, 0.24968, -0.41242], + } + expected_glove_100d = { + 'the': [-0.038194, -0.24487, 0.72812], + } + expected_glove_200d = { + 'the': [-0.071549, 0.093459, 0.023738], + } + expected_glove_300d = { + 'the': [0.04656, 0.21318, -0.0074364], + } + expected_gloves = [expected_glove_50d, expected_glove_100d, expected_glove_200d, expected_glove_300d] + + for vectors_obj, expected_glove in zip(vectors_objects, expected_gloves): + for word in expected_glove.keys(): + self.assertEqual(vectors_obj[word][:3], expected_glove[word]) diff --git a/torchtext/csrc/sentencepiece.cpp b/torchtext/csrc/sentencepiece.cpp index 06237b5d32..59873d98a8 100644 --- a/torchtext/csrc/sentencepiece.cpp +++ b/torchtext/csrc/sentencepiece.cpp @@ -50,6 +50,16 @@ struct SentencePiece : torch::CustomClassHolder { } int64_t GetPieceSize() const { return processor_.GetPieceSize(); } + + int64_t unk_id() const { return processor_.unk_id(); } + + int64_t PieceToId(const std::string &piece) const { + return processor_.PieceToId(piece); + } + + std::string IdToPiece(const int64_t id) const { + return processor_.IdToPiece(id); + } }; // Registers our custom class with torch. @@ -59,6 +69,9 @@ static auto sentencepiece = .def("EncodeAsIds", &SentencePiece::EncodeAsIds) .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) .def("GetPieceSize", &SentencePiece::GetPieceSize) + .def("unk_id", &SentencePiece::unk_id) + .def("PieceToId", &SentencePiece::PieceToId) + .def("IdToPiece", &SentencePiece::IdToPiece) .def_pickle( // __setstate__ [](const c10::intrusive_ptr &self) -> std::string { diff --git a/torchtext/csrc/vectors.cpp b/torchtext/csrc/vectors.cpp index cf84b694f0..8597bba614 100644 --- a/torchtext/csrc/vectors.cpp +++ b/torchtext/csrc/vectors.cpp @@ -1,3 +1,13 @@ +#include // @manual +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -7,6 +17,11 @@ using c10::Dict; namespace torchtext { namespace { +typedef ska_ordered::order_preserving_flat_hash_map + VectorsMap; +typedef ska_ordered::order_preserving_flat_hash_map + IndexMap; +typedef std::vector StringList; typedef std::tuple, std::vector, std::vector> VectorsStates; @@ -15,16 +30,20 @@ struct Vectors : torch::CustomClassHolder { public: const std::string version_str_ = "0.0.1"; - Dict stovec_; - std::vector tokens_; + IndexMap stoindex_; + VectorsMap stovec_; + torch::Tensor vectors_; torch::Tensor unk_tensor_; + explicit Vectors(const IndexMap &stoindex, const torch::Tensor vectors, + const torch::Tensor &unk_tensor) + : stoindex_(stoindex), vectors_(vectors), unk_tensor_(unk_tensor) {} + explicit Vectors(const std::vector &tokens, const torch::Tensor &vectors, const torch::Tensor &unk_tensor) - : tokens_(std::move(tokens)), vectors_(std::move(vectors)), - unk_tensor_(std::move(unk_tensor)) { + : vectors_(std::move(vectors)), unk_tensor_(std::move(unk_tensor)) { // guarding against size mismatch of vectors and tokens if (static_cast(tokens.size()) != vectors.size(0)) { throw std::runtime_error( @@ -33,21 +52,30 @@ struct Vectors : torch::CustomClassHolder { ", size of vectors: " + std::to_string(vectors.size(0)) + "."); } + stoindex_.reserve(tokens.size()); stovec_.reserve(tokens.size()); for (std::size_t i = 0; i < tokens.size(); i++) { // tokens should not have any duplicates - if (stovec_.find(tokens[i]) != stovec_.end()) { + const auto &item_index = stoindex_.find(tokens[i]); + if (item_index != stoindex_.end()) { throw std::runtime_error("Duplicate token found in tokens list: " + tokens[i]); } - stovec_.insert(std::move(tokens[i]), vectors_.select(0, i)); + stoindex_[std::move(tokens[i])] = i; } } - torch::Tensor __getitem__(const std::string &token) const { + torch::Tensor __getitem__(const std::string &token) { const auto &item = stovec_.find(token); if (item != stovec_.end()) { - return item->value(); + return item->second; + } + + const auto &item_index = stoindex_.find(token); + if (item_index != stoindex_.end()) { + auto vector = vectors_[item_index->second]; + stovec_[token] = vector; + return vector; } return unk_tensor_; } @@ -62,23 +90,228 @@ struct Vectors : torch::CustomClassHolder { } void __setitem__(const std::string &token, const torch::Tensor &vector) { - const auto &item = stovec_.find(token); - if (item != stovec_.end()) { - item->value() = vector; + const auto &item_index = stoindex_.find(token); + if (item_index != stoindex_.end()) { + stovec_[token] = vector; + vectors_[item_index->second] = vector; } else { - tokens_.push_back(token); - vectors_ = torch::cat({vectors_, torch::unsqueeze(vector, /*dim=*/0)}, - /*dim=*/0); - stovec_.insert_or_assign(token, vectors_.select(0, stovec_.size())); + stoindex_[token] = vectors_.size(0); + stovec_[token] = vector; + // TODO: This could be done lazily during serialization (if necessary). + // We would cycle through the vectors and concatenate those that aren't + // views. + vectors_ = at::cat({vectors_, vector.unsqueeze(0)}); } } int64_t __len__() { return stovec_.size(); } }; +inline int64_t divup(int64_t x, int64_t y) { return (x + y - 1) / y; } + +std::tuple _infer_shape(const std::string &file_path, + const char delimiter) { + + int64_t num_header_lines = 0, num_lines = 0, vector_dim = -1; + std::vector vec_str; + std::string line, word; + + std::ifstream fin; + fin.open(file_path, std::ios::in); + + while (std::getline(fin, line)) { + vec_str.clear(); + if (vector_dim == -1) { + std::istringstream s(line); + + // get rid of the token + std::getline(s, word, delimiter); + // we assume entries for vector are always seperated by ' ' + while (std::getline(s, word, ' ')) { + vec_str.push_back(word); + } + + // assuming word, [vector] format + // the header present in some(w2v) formats contains two elements + if (vec_str.size() <= 2) { + num_header_lines++; + } else if (vec_str.size() > 2) { + vector_dim = vec_str.size(); + num_lines++; // first element read + } + } else { + num_lines++; + } + } + return std::make_tuple(num_lines, num_header_lines, vector_dim); +} + +void _infer_offsets(const std::string &file_path, int64_t num_lines, + int64_t chunk_size, int64_t num_header_lines, + std::vector &offsets) { + + std::ifstream fin; + fin.open(file_path, std::ios::in); + + while (num_header_lines > 0) { + fin.ignore(std::numeric_limits::max(), '\n'); + num_header_lines--; + } + offsets.push_back(fin.tellg()); + size_t offset = 0; + while (fin.ignore(std::numeric_limits::max(), '\n')) { + offset++; + if (offset % chunk_size == 0) { + offsets.push_back(fin.tellg()); + } + } +} + +void parse_chunk(const std::string &file_path, size_t offset, + const int64_t start_line, const int64_t end_line, + const int64_t vector_dim, const char delimiter, + std::shared_ptr tokens, float *data_ptr) { + std::ifstream fin; + fin.open(file_path, std::ios::in); + fin.seekg(offset); + + int converter_flags = double_conversion::StringToDoubleConverter::NO_FLAGS; + double_conversion::StringToDoubleConverter converter( + converter_flags, 0.0f, double_conversion::Single::NaN(), NULL, NULL); + + for (int64_t i = start_line; i < end_line; i++) { + std::string token; + // read the token + std::getline(fin, token, delimiter); + tokens->push_back(token); + + std::string vec_val; + int processed_characters_count; + // read the vector + for (int64_t j = 0; j < vector_dim; j++) { + fin >> vec_val; + const char *tmp_str = vec_val.c_str(); + data_ptr[i * vector_dim + j] = converter.StringToFloat( + tmp_str, strlen(tmp_str), &processed_characters_count); + TORCH_CHECK(processed_characters_count == strlen(tmp_str), + "Processed characters count didn't match vector string " + "length during string to float conversion!"); + } + fin >> std::ws; + } +} + +std::tuple +_concat_vectors(std::vector> chunk_tokens, + int64_t num_header_lines, int64_t num_lines) { + TORCH_CHECK(chunk_tokens.size() > 0, + "There must be at least 1 chunk to concatenate!"); + IndexMap tokens; + StringList dup_tokens; + tokens.reserve(num_lines); + + // concat all loaded tuples + int64_t count = num_header_lines; + for (size_t i = 0; i < chunk_tokens.size(); i++) { + auto &subset_tokens = *chunk_tokens[i]; + for (size_t j = 0; j < subset_tokens.size(); j++) { + const auto &token_index = tokens.find(subset_tokens[j]); + if (token_index != tokens.end()) { + dup_tokens.emplace_back(std::move(subset_tokens[j])); + } else { + tokens[std::move(subset_tokens[j])] = count; + } + count++; + } + } + return std::make_tuple(std::move(tokens), std::move(dup_tokens)); +} + +constexpr int64_t GRAIN_SIZE = 131072; +std::tuple, std::vector> +_load_token_and_vectors_from_file(const std::string &file_path, + const std::string delimiter_str, + int64_t num_cpus, + c10::optional opt_unk_tensor) { + TORCH_CHECK(delimiter_str.size() == 1, + "Only string delimeters of size 1 are supported."); + std::cerr << "[INFO] Reading file " << file_path << std::endl; + + const char delimiter = delimiter_str.at(0); + int64_t num_lines, num_header_lines, vector_dim; + std::tie(num_lines, num_header_lines, vector_dim) = + _infer_shape(file_path, delimiter); + + int64_t chunk_size = divup(num_lines, num_cpus); + // Launching a thread on less lines than this likely has too much overhead. + // TODO: Add explicit test beyond grain size to cover multithreading + chunk_size = std::max(chunk_size, GRAIN_SIZE); + + std::vector offsets; + _infer_offsets(file_path, num_lines, chunk_size, num_header_lines, offsets); + + torch::Tensor data_tensor = torch::empty({num_lines, vector_dim}); + float *data_ptr = data_tensor.data_ptr(); + std::vector> chunk_tokens; + + std::mutex m; + std::condition_variable cv; + std::atomic counter(0); + + // create threads + int64_t j = 0; + for (int64_t i = num_header_lines; i < num_lines; i += chunk_size) { + auto tokens_ptr = std::make_shared(); + + counter++; + at::launch([&, file_path, num_lines, chunk_size, vector_dim, delimiter, j, + i, tokens_ptr, data_ptr]() { + parse_chunk(file_path, offsets[j], i, std::min(num_lines, i + chunk_size), + vector_dim, delimiter, tokens_ptr, data_ptr); + std::lock_guard lk(m); + counter--; + cv.notify_all(); + }); + chunk_tokens.push_back(tokens_ptr); + j++; + } + + // block until all threads finish execution + std::unique_lock lock(m); + cv.wait(lock, [&counter] { return counter == 0; }); + + IndexMap stoindex; + StringList dup_tokens; + std::tie(stoindex, dup_tokens) = + _concat_vectors(chunk_tokens, num_header_lines, num_lines); + + torch::Tensor unk_tensor; + if (opt_unk_tensor) { + unk_tensor = *opt_unk_tensor; + } else { + unk_tensor = torch::zeros({vector_dim}, torch::kFloat32); + } + auto result = std::make_tuple( + c10::make_intrusive(Vectors(stoindex, data_tensor, unk_tensor)), + dup_tokens); + return result; +} + VectorsStates _set_vectors_states(const c10::intrusive_ptr &self) { - std::vector integers; - std::vector strings = self->tokens_; + std::vector tokens; + std::vector indices; + tokens.reserve(self->stoindex_.size()); + indices.reserve(self->stoindex_.size()); + + // construct tokens and index list + // we need to store indices because the `vectors_` tensor may have gaps + for (const auto &item : self->stoindex_) { + tokens.push_back(item.first); + indices.push_back(item.second); + } + + std::vector integers = std::move(indices); + std::vector strings = std::move(tokens); std::vector tensors{self->vectors_, self->unk_tensor_}; VectorsStates states = @@ -101,14 +334,21 @@ c10::intrusive_ptr _get_vectors_from_states(VectorsStates states) { auto &strings = std::get<2>(states); auto &tensors = std::get<3>(states); - // check integers are empty - if (integers.size() != 0) { - throw std::runtime_error("Expected `integers` states to be empty."); - } - if (version_str.compare("0.0.1") >= 0) { + // check integers and tokens are same size + if (integers.size() != strings.size()) { + throw std::runtime_error( + "Expected `integers` and `strings` states to be the same size."); + } + + IndexMap stoindex; + stoindex.reserve(integers.size()); + for (size_t i = 0; i < integers.size(); i++) { + stoindex[strings[i]] = integers[i]; + } + return c10::make_intrusive( - std::move(strings), std::move(tensors[0]), std::move(tensors[1])); + std::move(stoindex), std::move(tensors[0]), std::move(tensors[1])); } throw std::runtime_error( @@ -134,5 +374,11 @@ static auto vectors = return _get_vectors_from_states(states); }); +// Registers our custom op with torch. +TORCH_LIBRARY(torchtext, m) { + m.def("_load_token_and_vectors_from_file", + &_load_token_and_vectors_from_file); +} + } // namespace } // namespace torchtext diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index f7f53670be..c8048c1d40 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -112,3 +112,19 @@ def forward(self, line: str) -> List[str]: for regex, replacement_string in self.regex_and_replacement_string_pairs: line = regex.Sub(line, replacement_string) return line.split() + + +class TextSequentialTransforms(nn.Sequential): + r"""A container to host a sequential text transforms. + + Example: + >>> import torch + >>> from torchtext.experimental.transforms import BasicEnglishNormalize, TextSequentialTransforms + >>> tokenizer = BasicEnglishNormalize() + >>> txt_pipeline = TextSequentialTransforms(tokenizer) + >>> jit_txt_pipeline = torch.jit.script(txt_pipeline) + """ + def forward(self, input: str): + for module in self: + input = module(input) + return input diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index bd05801c16..b68487c6c3 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -4,7 +4,6 @@ import torch from torch import Tensor import torch.nn as nn -from tqdm import tqdm from typing import List from torchtext.utils import ( @@ -15,81 +14,17 @@ logger = logging.getLogger(__name__) -def _infer_shape(f, delimiter=" "): - num_lines, vector_dim = 0, None - for line in f: - if vector_dim is None: - # token and entries are seperated by delimeter - token, entries = line.rstrip().split(bytes(delimiter, "utf-8"), 1) - # we assume entries are always seperated by " " - vector = entries.split(b" ") - - # Assuming word, [vector] format - if len(vector) > 2: - # The header present in some (w2v) formats contains two elements. - vector_dim = len(vector) - num_lines += 1 # First element read - else: - num_lines += 1 - f.seek(0) - return num_lines, vector_dim - - -def _load_token_and_vectors_from_file(file_path, delimiter=" "): - with open(file_path, "rb") as f: - num_lines, dim = _infer_shape(f, delimiter=delimiter) - stoi, tokens, vectors, dup_tokens = {}, [], [], [] - - vectors = torch.zeros((num_lines, dim)) - vectors_loaded = 0 - - for line in tqdm(f, unit_scale=0, unit="lines", total=num_lines): - # token and entries are seperated by delimeter - token, entries = line.rstrip().split(bytes(delimiter, "utf-8"), 1) - # we assume entries are always seperated by " " - entries = entries.split(b" ") - - if dim is None and len(entries) > 1: - dim = len(entries) - elif len(entries) == 1: - logger.warning("Skipping token {} with 1-dimensional " - "vector {}; likely a header".format(token, entries)) - continue - elif dim != len(entries): - raise RuntimeError( - "Vector for token {} has {} dimensions, but previously " - "read vectors have {} dimensions. All vectors must have " - "the same number of dimensions.".format(token, len(entries), - dim)) - try: - if isinstance(token, bytes): - token = token.decode("utf-8") - except UnicodeDecodeError: - logger.info("Skipping non-UTF8 token {}".format(repr(token))) - continue - - if token in stoi: - dup_tokens.append((token, len(vectors) + 1)) - continue - - stoi[token] = len(vectors) - tokens.append(token) - vectors[vectors_loaded] = torch.tensor([float(c) for c in entries], dtype=torch.float) - vectors_loaded += 1 - vectors = vectors[:vectors_loaded] - return tokens, vectors, dup_tokens - - -def FastText(language="en", unk_tensor=None, root=".data", validate_file=True): +def FastText(language="en", unk_tensor=None, root=".data", validate_file=True, num_cpus=32): r"""Create a FastText Vectors object. Args: language (str): the language to use for FastText. The list of supported languages options can be found at https://fasttext.cc/docs/en/language-identification.html unk_tensor (Tensor): a 1d tensor representing the vector associated with an unknown token - root (str): folder used to store downloaded files in (.data) + root (str): folder used to store downloaded files in. Default: '.data'. validate_file (bool): flag to determine whether to validate the downloaded files checksum. Should be `False` when running tests with a local asset. + num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. Returns: Vectors: a Vectors object. @@ -111,17 +46,17 @@ def FastText(language="en", unk_tensor=None, root=".data", validate_file=True): checksum = CHECKSUMS_FAST_TEXT.get(url, None) downloaded_file_path = download_from_url(url, root=root, hash_value=checksum) - tokens, vectors, dup_tokens = _load_token_and_vectors_from_file(downloaded_file_path) + cpp_vectors_obj, dup_tokens = torch.ops.torchtext._load_token_and_vectors_from_file(downloaded_file_path, ' ', num_cpus, unk_tensor) if dup_tokens: raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) - vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + vectors_obj = Vectors(cpp_vectors_obj) torch.save(vectors_obj, cached_vectors_file_path) return vectors_obj -def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=True): +def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=True, num_cpus=32): r"""Create a GloVe Vectors object. Args: @@ -149,6 +84,7 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru root (str): folder used to store downloaded files in (.data) validate_file (bool): flag to determine whether to validate the downloaded files checksum. Should be `False` when running tests with a local asset. + num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. Returns: Vectors: a Vectors object. @@ -156,11 +92,11 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru ValueError: if unexpected duplicate tokens are found in GloVe file. """ - dup_token_glove_840b = [("����������������������������������������������������������������������" - "����������������������������������������������������������������������" - "����������������������������������������������������������������������" - "����������������������������������������������������������������������" - "������������������������������������������������������", 140649)] + dup_token_glove_840b = ["����������������������������������������������������������������������" + "����������������������������������������������������������������������" + "����������������������������������������������������������������������" + "����������������������������������������������������������������������" + "������������������������������������������������������"] urls = { "42B": "https://nlp.stanford.edu/data/glove.42B.300d.zip", "840B": "https://nlp.stanford.edu/data/glove.840B.300d.zip", @@ -199,18 +135,18 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru extracted_file_paths = extract_archive(downloaded_file_path) # need to get the full path to the correct file in the case when multiple files are extracted with different dims extracted_file_path_with_correct_dim = [path for path in extracted_file_paths if file_name in path][0] - tokens, vectors, dup_tokens = _load_token_and_vectors_from_file(extracted_file_path_with_correct_dim) + cpp_vectors_obj, dup_tokens = torch.ops.torchtext._load_token_and_vectors_from_file(extracted_file_path_with_correct_dim, ' ', num_cpus, unk_tensor) # Ensure there is only 1 expected duplicate token present for 840B dataset if dup_tokens and dup_tokens != dup_token_glove_840b: raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) - vectors_obj = Vectors(tokens, vectors, unk_tensor=unk_tensor) + vectors_obj = Vectors(cpp_vectors_obj) torch.save(vectors_obj, cached_vectors_file_path) return vectors_obj -def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None): +def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None, num_cpus=10): r"""Create a Vectors object from a csv file like object. Note that the tensor corresponding to each vector is of type `torch.float`. @@ -225,6 +161,7 @@ def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None): file_like_object (FileObject): a file like object to read data from. delimiter (char): a character to delimit between the token and the vector. Default value is "," unk_tensor (Tensor): a 1d tensor representing the vector associated with an unknown token. + num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. Returns: Vectors: a Vectors object. @@ -233,37 +170,38 @@ def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None): ValueError: if duplicate tokens are found in FastText file. """ - tokens, vectors, dup_tokens = _load_token_and_vectors_from_file(file_like_object.name, delimiter=delimiter) + vectors_obj, dup_tokens = torch.ops.torchtext._load_token_and_vectors_from_file(file_like_object.name, delimiter, num_cpus, unk_tensor) if dup_tokens: raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) - return Vectors(tokens, vectors, unk_tensor=unk_tensor) + return Vectors(vectors_obj) + + +def vectors(tokens, vectors, unk_tensor=None): + if unk_tensor is None and (vectors is None or not len(vectors)): + raise ValueError("The vectors list is empty and a default unk_tensor wasn't provided.") + + if not vectors.dtype == torch.float: + raise TypeError("`vectors` should be of data type `torch.float`.") + + unk_tensor = unk_tensor if unk_tensor is not None else torch.zeros(vectors[0].size(), dtype=torch.float) + return Vectors(torch.classes.torchtext.Vectors(tokens, vectors, unk_tensor)) class Vectors(nn.Module): r"""Creates a vectors object which maps tokens to vectors. - Arguments: tokens (List[str]): a list of tokens. vectors (torch.Tensor): a 2d tensor representing the vector associated with each token. unk_tensor (torch.Tensor): a 1d tensors representing the vector associated with an unknown token. - Raises: ValueError: if `vectors` is empty and a default `unk_tensor` isn't provided. RuntimeError: if `tokens` and `vectors` have different sizes or `tokens` has duplicates. TypeError: if all tensors within`vectors` are not of data type `torch.float`. """ - def __init__(self, tokens, vectors, unk_tensor=None): + def __init__(self, vectors): super(Vectors, self).__init__() - - if unk_tensor is None and (vectors is None or not len(vectors)): - raise ValueError("The vectors list is empty and a default unk_tensor wasn't provided.") - - if not vectors.dtype == torch.float: - raise TypeError("`vectors` should be of data type `torch.float`.") - - unk_tensor = unk_tensor if unk_tensor is not None else torch.zeros(vectors[0].size(), dtype=torch.float) - self.vectors = torch.classes.torchtext.Vectors(tokens, vectors, unk_tensor) + self.vectors = vectors @torch.jit.export def __getitem__(self, token: str) -> Tensor: @@ -286,7 +224,7 @@ def __setitem__(self, token: str, vector: Tensor) -> None: TypeError: if `vector` is not of data type `torch.float`. """ if vector.dtype != torch.float: - raise TypeError("`vector` should be of data type `torch.float` but it's of type " + vector.dtype) + raise TypeError("`vector` should be of data type `torch.float` but it's of type " + str(vector.dtype)) self.vectors[token] = vector.float() From d7762a03fcf090a0e6091c9b79d82eb678ce8bb3 Mon Sep 17 00:00:00 2001 From: Nayef Ahmed Date: Wed, 19 Aug 2020 16:02:58 -0700 Subject: [PATCH 21/68] Import torchtext 2020/08/18 Summary: Import from github torchtext/master Reviewed By: cpuhrsch Differential Revision: D23190596 fbshipit-source-id: 1568a25a5bd6431bcef3c6539f64a3ab1f5bccd7 --- .../benchmark_basic_english_normalize.py | 37 ++ benchmark/benchmark_experimental_vectors.py | 3 +- benchmark/benchmark_experimental_vocab.py | 121 ++++-- build_tools/setup_helpers/extension.py | 16 +- test/data/test_functional.py | 52 ++- test/experimental/test_vectors.py | 65 +-- test/experimental/test_vocab.py | 89 +++-- test/test_utils.py | 14 + torchtext/csrc/common.cpp | 34 ++ torchtext/csrc/common.h | 9 + torchtext/csrc/regex.cpp | 43 +- torchtext/csrc/regex.h | 16 + torchtext/csrc/regex_tokenizer.cpp | 47 +++ torchtext/csrc/regex_tokenizer.h | 23 ++ torchtext/csrc/register_bindings.cpp | 175 +++++++++ torchtext/csrc/sentencepiece.cpp | 112 ++---- torchtext/csrc/sentencepiece.h | 34 ++ torchtext/csrc/vectors.cpp | 267 +++++-------- torchtext/csrc/vectors.h | 42 ++ torchtext/csrc/vocab.cpp | 371 ++++++++++++------ torchtext/csrc/vocab.h | 44 +++ torchtext/experimental/transforms.py | 129 +++--- torchtext/experimental/vectors.py | 71 ++-- torchtext/experimental/vocab.py | 107 ++--- torchtext/utils.py | 9 + torchtext/vocab.py | 4 + 26 files changed, 1320 insertions(+), 614 deletions(-) create mode 100644 benchmark/benchmark_basic_english_normalize.py create mode 100644 torchtext/csrc/common.cpp create mode 100644 torchtext/csrc/common.h create mode 100644 torchtext/csrc/regex.h create mode 100644 torchtext/csrc/regex_tokenizer.cpp create mode 100644 torchtext/csrc/regex_tokenizer.h create mode 100644 torchtext/csrc/register_bindings.cpp create mode 100644 torchtext/csrc/sentencepiece.h create mode 100644 torchtext/csrc/vectors.h create mode 100644 torchtext/csrc/vocab.h diff --git a/benchmark/benchmark_basic_english_normalize.py b/benchmark/benchmark_basic_english_normalize.py new file mode 100644 index 0000000000..d719e748a5 --- /dev/null +++ b/benchmark/benchmark_basic_english_normalize.py @@ -0,0 +1,37 @@ +import time + +import torch +from torchtext.experimental.datasets.raw import AG_NEWS +from torchtext.experimental.transforms import basic_english_normalize +from torchtext.data.utils import get_tokenizer + + +def benchmark_basic_english_normalize(): + def _run_benchmark_lookup(train, tokenizer): + t0 = time.monotonic() + for (_, text) in train: + tokenizer(text) + print("Tokenization time:", time.monotonic() - t0) + + existing_basic_english_tokenizer = get_tokenizer("basic_english") + experimental_basic_english_normalize = basic_english_normalize() + experimental_jit_basic_english_normalize = torch.jit.script(experimental_basic_english_normalize.to_ivalue()) + + # existing eager lookup + train, _ = AG_NEWS() + print("BasicEnglishNormalize - Eager Mode") + _run_benchmark_lookup(train, existing_basic_english_tokenizer) + + # experimental eager lookup + train, _ = AG_NEWS() + print("BasicEnglishNormalize Experimental - Eager Mode") + _run_benchmark_lookup(train, experimental_basic_english_normalize) + + # experimental jit lookup + train, _ = AG_NEWS() + print("BasicEnglishNormalize Experimental - Jit Mode") + _run_benchmark_lookup(train, experimental_jit_basic_english_normalize) + + +if __name__ == "__main__": + benchmark_basic_english_normalize() diff --git a/benchmark/benchmark_experimental_vectors.py b/benchmark/benchmark_experimental_vectors.py index f2e77b02bb..42fc008370 100644 --- a/benchmark/benchmark_experimental_vectors.py +++ b/benchmark/benchmark_experimental_vectors.py @@ -3,7 +3,6 @@ import torch from torchtext.experimental.datasets import AG_NEWS from torchtext.experimental.vectors import FastText as FastTextExperimental - from torchtext.vocab import FastText @@ -43,7 +42,7 @@ def _run_benchmark_lookup(tokens, vector): # experimental FastText jit lookup print("FastText Experimental - Jit Mode") - jit_fast_text_experimental = torch.jit.script(fast_text_experimental) + jit_fast_text_experimental = torch.jit.script(fast_text_experimental.to_ivalue()) _run_benchmark_lookup(tokens, jit_fast_text_experimental) diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index d1106da7bb..250abc46e2 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -1,55 +1,124 @@ +import argparse from collections import (Counter, OrderedDict) import time import torch from torchtext.experimental.datasets import AG_NEWS -from torchtext.experimental.vocab import Vocab as VocabExperimental -from torchtext.vocab import Vocab +from torchtext.experimental.vocab import ( + vocab as VocabExperimental, + vocab_from_file_object +) +from torchtext.vocab import ( + Vocab, + build_vocab_from_iterator +) -def benchmark_experimental_vocab(): +def benchmark_experimental_vocab_construction(vocab_file_path, num_iters=100): + f = open(vocab_file_path, 'r') + t0 = time.monotonic() + for _ in range(num_iters): + vocab_from_file_object(f) + print("Construction time:", time.monotonic() - t0) + + +def benchmark_experimental_vocab_lookup(vocab_file_path=None): def _run_benchmark_lookup(tokens, vocab): t0 = time.monotonic() - for token in tokens: - vocab[token] + # list lookup + if isinstance(tokens, list) and isinstance(tokens[0], list): + for tokens_list in tokens: + vocab.lookup_indices(tokens_list) + # single token lookup + elif isinstance(tokens, list): + for token in tokens: + vocab[token] + else: + raise RuntimeError("Received tokens of incorrect type {}.".format(type(tokens))) print("Lookup time:", time.monotonic() - t0) + tokens = [] + tokens_lists = [] + train, = AG_NEWS(data_select='train') vocab = train.get_vocab() - tokens = [] - for (label, text) in train: + for (_, text) in train: + cur_tokens = [] for id in text.tolist(): - tokens.append(vocab.itos[id]) + cur_tokens.append(vocab.itos[id]) + tokens_lists.append(cur_tokens) + tokens += cur_tokens - counter = Counter(tokens) - sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) - ordered_dict = OrderedDict(sorted_by_freq_tuples) + if vocab_file_path: + print("Loading Vocab from file {}".format(vocab_file_path)) - # existing Vocab construction - print("Vocab") - t0 = time.monotonic() - v_existing = Vocab(counter) - print("Construction time:", time.monotonic() - t0) + def token_iterator(file_path): + f = open(file_path, 'r') + for token in f: + yield token - # experimental Vocab construction - print("Vocab Experimental") - t0 = time.monotonic() - v_experimental = VocabExperimental(ordered_dict) - print("Construction time:", time.monotonic() - t0) + # existing Vocab construction + print("Vocab") + t0 = time.monotonic() + v_existing = build_vocab_from_iterator(token_iterator(vocab_file_path)) + print("Construction time:", time.monotonic() - t0) + + # experimental Vocab construction + print("Vocab Experimental") + t0 = time.monotonic() + f = open(vocab_file_path, 'r') + v_experimental = vocab_from_file_object(f) + print("Construction time:", time.monotonic() - t0) + else: + print("Loading Vocab from AG News") + counter = Counter(tokens) + sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) + ordered_dict = OrderedDict(sorted_by_freq_tuples) + + # existing Vocab construction + print("Vocab") + t0 = time.monotonic() + v_existing = Vocab(counter) + print("Construction time:", time.monotonic() - t0) + + # experimental Vocab construction + print("Vocab Experimental") + t0 = time.monotonic() + v_experimental = VocabExperimental(ordered_dict) + print("Construction time:", time.monotonic() - t0) jit_v_experimental = torch.jit.script(v_experimental) - # existing Vocab not jit lookup - print("Vocab - Not Jit Mode") + # existing Vocab eager lookup + print("Vocab - Eager Mode") _run_benchmark_lookup(tokens, v_existing) + _run_benchmark_lookup([tokens], v_existing) + _run_benchmark_lookup(tokens_lists, v_existing) - # experimental Vocab not jit lookup - print("Vocab Experimental - Not Jit Mode") + # experimental Vocab eager lookup + print("Vocab Experimental - Eager Mode") _run_benchmark_lookup(tokens, v_experimental) + _run_benchmark_lookup([tokens], v_experimental) + _run_benchmark_lookup(tokens_lists, v_experimental) + jit_v_experimental = torch.jit.script(v_experimental.to_ivalue()) # experimental Vocab jit lookup print("Vocab Experimental - Jit Mode") _run_benchmark_lookup(tokens, jit_v_experimental) + _run_benchmark_lookup([tokens], jit_v_experimental) + _run_benchmark_lookup(tokens_lists, jit_v_experimental) if __name__ == "__main__": - benchmark_experimental_vocab() + parser = argparse.ArgumentParser(description='Data procesing pipelines') + parser.add_argument('--run-construction-benchmark', type=bool, default=False, + help='run benchmark for constructing a vocab (default=False)') + parser.add_argument('--vocab-filename-construction', type=str, default='vocab.txt', + help='The name of vocab file used for construction') + parser.add_argument('--vocab-filename-lookup', type=str, default=None, + help='The name of vocab file used for lookup') + args = parser.parse_args() + + if args.run_construction_benchmark: + benchmark_experimental_vocab_construction(args.vocab_filename_construction) + else: + benchmark_experimental_vocab_lookup(args.vocab_filename_lookup) diff --git a/build_tools/setup_helpers/extension.py b/build_tools/setup_helpers/extension.py index 4223b398d2..f3a2097313 100644 --- a/build_tools/setup_helpers/extension.py +++ b/build_tools/setup_helpers/extension.py @@ -84,6 +84,15 @@ def _get_libraries(): ] +def _get_cxx11_abi(): + try: + import torch + value = int(torch._C._GLIBCXX_USE_CXX11_ABI) + except ImportError: + value = 0 + return '-D_GLIBCXX_USE_CXX11_ABI=' + str(value) + + def _build_third_party(debug): build_dir = _TP_BASE_DIR / 'build' build_dir.mkdir(exist_ok=True) @@ -96,7 +105,7 @@ def _build_third_party(debug): build_env.setdefault('CC', 'cl') build_env.setdefault('CXX', 'cl') else: - extra_args = ['-DCMAKE_CXX_FLAGS=-fPIC'] + extra_args = ['-DCMAKE_CXX_FLAGS=-fPIC ' + _get_cxx11_abi()] subprocess.run( args=[ 'cmake', @@ -113,7 +122,7 @@ def _build_third_party(debug): print('*** Command list Thirdparty ***') with open(build_dir / 'compile_commands.json', 'r') as fileobj: print(fileobj.read()) - print(f'running cmake --build', flush=True) + print('running cmake --build', flush=True) subprocess.run( args=['cmake', '--build', '.', '--target', 'install', '--config', config], cwd=str(build_dir), @@ -134,7 +143,8 @@ def _build_sentence_piece(debug): else: extra_args = [] subprocess.run( - args=['cmake', f'-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}', + args=['cmake', '-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}', + '-DCMAKE_CXX_FLAGS=' + _get_cxx11_abi(), f'-DCMAKE_BUILD_TYPE={config}'] + extra_args + ['..'], cwd=str(build_dir), check=True, diff --git a/test/data/test_functional.py b/test/data/test_functional.py index ce91ab48b1..6057c02769 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -17,8 +17,8 @@ simple_space_split, ) from torchtext.experimental.transforms import ( - BasicEnglishNormalize, - RegexTokenizer + basic_english_normalize, + regex_tokenizer ) from ..common.torchtext_test_case import TorchtextTestCase @@ -80,27 +80,38 @@ def test_sentencepiece_tokenizer(self): self.assertEqual(list(spm_generator([test_sample]))[0], ref_results) - # TODO(Nayef211): remove decorator once # https://github.com/pytorch/pytorch/issues/38207 is closed + # TODO(Nayef211): remove decorator once https://github.com/pytorch/pytorch/issues/38207 is closed @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_BasicEnglishNormalize(self): test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] - basic_english_normalize = BasicEnglishNormalize() - experimental_eager_tokens = basic_english_normalize(test_sample) + basic_eng_norm = basic_english_normalize() + experimental_eager_tokens = basic_eng_norm(test_sample) - jit_basic_english_normalize = torch.jit.script(basic_english_normalize) - experimental_jit_tokens = jit_basic_english_normalize(test_sample) + jit_basic_eng_norm = torch.jit.script(basic_eng_norm.to_ivalue()) + experimental_jit_tokens = jit_basic_eng_norm(test_sample) basic_english_tokenizer = data.get_tokenizer("basic_english") eager_tokens = basic_english_tokenizer(test_sample) + assert not basic_eng_norm.is_jitable + assert basic_eng_norm.to_ivalue().is_jitable + self.assertEqual(experimental_jit_tokens, ref_results) - self.assertEqual(experimental_jit_tokens, eager_tokens) - self.assertEqual(experimental_jit_tokens, experimental_eager_tokens) + self.assertEqual(eager_tokens, ref_results) + self.assertEqual(experimental_eager_tokens, ref_results) + + # test load and save + save_path = os.path.join(self.test_dir, 'basic_english_normalize.pt') + torch.save(basic_eng_norm.to_ivalue(), save_path) + loaded_basic_eng_norm = torch.load(save_path) + + loaded_eager_tokens = loaded_basic_eng_norm(test_sample) + self.assertEqual(loaded_eager_tokens, ref_results) - # TODO(Nayef211): remove decorator once # https://github.com/pytorch/pytorch/issues/38207 is closed + # TODO(Nayef211): remove decorator once https://github.com/pytorch/pytorch/issues/38207 is closed @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_RegexTokenizer(self): test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' @@ -120,14 +131,25 @@ def test_RegexTokenizer(self): (r'\:', ' '), (r'\s+', ' ')] - regex_tokenizer = RegexTokenizer(patterns_list) - eager_tokens = regex_tokenizer(test_sample) + r_tokenizer = regex_tokenizer(patterns_list) + eager_tokens = r_tokenizer(test_sample) - jit_regex_tokenizer = torch.jit.script(regex_tokenizer) - jit_tokens = jit_regex_tokenizer(test_sample) + jit_r_tokenizer = torch.jit.script(r_tokenizer.to_ivalue()) + jit_tokens = jit_r_tokenizer(test_sample) + assert not r_tokenizer.is_jitable + assert r_tokenizer.to_ivalue().is_jitable + + self.assertEqual(eager_tokens, ref_results) self.assertEqual(jit_tokens, ref_results) - self.assertEqual(jit_tokens, eager_tokens) + + # test load and save + save_path = os.path.join(self.test_dir, 'regex.pt') + torch.save(r_tokenizer.to_ivalue(), save_path) + loaded_r_tokenizer = torch.load(save_path) + + loaded_eager_tokens = loaded_r_tokenizer(test_sample) + self.assertEqual(loaded_eager_tokens, ref_results) def test_custom_replace(self): custom_replace_transform = custom_replace([(r'S', 's'), (r'\s+', ' ')]) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 371ccecf5b..61f428329c 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- import os +import platform import shutil import tempfile - import torch +import unittest + from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase @@ -60,7 +62,10 @@ def test_vectors_jit(self): tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) - jit_vectors_obj = torch.jit.script(vectors_obj) + jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + + assert not vectors_obj.is_jitable + assert vectors_obj.to_ivalue().is_jitable self.assertEqual(vectors_obj['a'], jit_vectors_obj['a']) self.assertEqual(vectors_obj['b'], jit_vectors_obj['b']) @@ -81,6 +86,21 @@ def test_vectors_lookup_vectors(self): self.assertEqual(expected_vectors, vectors_by_tokens) + def test_vectors_call_method(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1], dtype=torch.float) + + unk_tensor = torch.tensor([0, 0], dtype=torch.float) + tokens = ['a', 'b'] + vecs = torch.stack((tensorA, tensorB), 0) + vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) + + tokens_to_lookup = ['a', 'b', 'c'] + expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) + vectors_by_tokens = vectors_obj(tokens_to_lookup) + + self.assertEqual(expected_vectors, vectors_by_tokens) + def test_vectors_add_item(self): tensorA = torch.tensor([1, 0], dtype=torch.float) unk_tensor = torch.tensor([0, 0], dtype=torch.float) @@ -109,44 +129,41 @@ def test_vectors_load_and_save(self): vectors_obj['b'] = tensorC vector_path = os.path.join(self.test_dir, 'vectors.pt') - torch.save(vectors_obj, vector_path) + torch.save(vectors_obj.to_ivalue(), vector_path) loaded_vectors_obj = torch.load(vector_path) self.assertEqual(loaded_vectors_obj['a'], tensorA) self.assertEqual(loaded_vectors_obj['b'], tensorC) self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) - def test_errors(self): - tokens = [] - vecs = torch.empty(0, dtype=torch.float) - - with self.assertRaises(ValueError): - # Test proper error raised when passing in empty tokens and vectors and - # not passing in a user defined unk_tensor - vectors(tokens, vecs) - + # we separate out these errors because Windows runs into seg faults when propagating + # exceptions from C++ using pybind11 + @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") + def test_errors_vectors_cpp(self): tensorA = torch.tensor([1, 0, 0], dtype=torch.float) tensorB = torch.tensor([0, 1, 0], dtype=torch.float) - tokens = ['a', 'b', 'c'] - vecs = torch.stack((tensorA, tensorB,), 0) - - with self.assertRaises(RuntimeError): - # Test proper error raised when tokens and vectors have different sizes - vectors(tokens, vecs) - tensorC = torch.tensor([0, 0, 1], dtype=torch.float) tokens = ['a', 'a', 'c'] vecs = torch.stack((tensorA, tensorB, tensorC), 0) with self.assertRaises(RuntimeError): # Test proper error raised when tokens have duplicates - # TODO (Nayef211): use self.assertRaisesRegex() to check + # TODO: use self.assertRaisesRegex() to check # the key of the duplicate token in the error message vectors(tokens, vecs) - tensorC = torch.tensor([0, 0, 1], dtype=torch.int8) + def test_errors_vectors_python(self): + tokens = [] + vecs = torch.empty(0, dtype=torch.float) + + with self.assertRaises(ValueError): + # Test proper error raised when passing in empty tokens and vectors and + # not passing in a user defined unk_tensor + vectors(tokens, vecs) + + tensorA = torch.tensor([1, 0, 0], dtype=torch.int8) tokens = ['a'] - vecs = tensorC.unsqueeze(0) + vecs = tensorA.unsqueeze(0) with self.assertRaises(TypeError): # Test proper error raised when vector is not of type torch.float @@ -191,7 +208,7 @@ def test_fast_text(self): data_path = os.path.join(dir_name, asset_name) shutil.copy(asset_path, data_path) vectors_obj = FastText(root=dir_name, validate_file=False) - jit_vectors_obj = torch.jit.script(vectors_obj) + jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) # The first 3 entries in each vector. expected_fasttext_simple_en = { @@ -213,7 +230,7 @@ def test_glove(self): data_path = os.path.join(dir_name, asset_name) shutil.copy(asset_path, data_path) vectors_obj = GloVe(root=dir_name, validate_file=False) - jit_vectors_obj = torch.jit.script(vectors_obj) + jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) # The first 3 entries in each vector. expected_glove = { diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index abcb151ff0..fcc0056754 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -1,12 +1,14 @@ # -*- coding: utf-8 -*- from collections import OrderedDict import os +import platform import torch +import unittest from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vocab import ( - Vocab, + vocab, vocab_from_file_object ) @@ -19,7 +21,7 @@ def tearDown(self): def test_has_unk(self): c = OrderedDict() - v = Vocab(c) + v = vocab(c) # check if unk is mapped to the first index self.assertEqual(v['not_in_it'], 0) @@ -27,7 +29,7 @@ def test_has_unk(self): def test_new_unk(self): c = OrderedDict() - v = Vocab(c, unk_token="") + v = vocab(c, unk_token="") # check if new_unk is mapped to the first index self.assertEqual(v[''], 0) @@ -37,7 +39,7 @@ def test_vocab_get_item(self): token_to_freq = {'': 2, 'a': 2, 'b': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, min_freq=2) + v = vocab(c, min_freq=2) self.assertEqual(v[''], 0) self.assertEqual(v['a'], 1) @@ -47,7 +49,7 @@ def test_vocab_insert_token(self): c = OrderedDict({'': 2, 'a': 2}) # add item to end - v = Vocab(c) + v = vocab(c) v.insert_token('b', 2) expected_itos = ['', 'a', 'b'] @@ -57,7 +59,7 @@ def test_vocab_insert_token(self): self.assertEqual(dict(v.get_stoi()), expected_stoi) # add item to middle - v = Vocab(c) + v = vocab(c) v.insert_token('b', 0) expected_itos = ['b', '', 'a'] @@ -68,17 +70,20 @@ def test_vocab_insert_token(self): def test_vocab_append_token(self): c = OrderedDict({'a': 2}) - v = Vocab(c) + v = vocab(c) v.append_token('b') - self.assertEqual(len(v), 3) - self.assertEqual(v['b'], 2) + expected_itos = ['', 'a', 'b'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) def test_vocab_len(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c) + v = vocab(c) self.assertEqual(len(v), 4) @@ -87,9 +92,9 @@ def test_vocab_basic(self): sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, min_freq=3) + v = vocab(c, min_freq=3) - expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) @@ -100,12 +105,15 @@ def test_vocab_jit(self): sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, min_freq=3) - jit_v = torch.jit.script(v) + v = vocab(c, min_freq=3) + jit_v = torch.jit.script(v.to_ivalue()) - expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} + assert not v.is_jitable + assert v.to_ivalue().is_jitable + self.assertEqual(jit_v.get_itos(), expected_itos) self.assertEqual(dict(jit_v.get_stoi()), expected_stoi) @@ -113,17 +121,17 @@ def test_vocab_lookup_token(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c) + v = vocab(c) - self.assertEqual(v.lookup_token(0), 'a') + self.assertEqual(v.lookup_token(1), 'a') def test_vocab_lookup_tokens(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c) + v = vocab(c) - indices = [1, 0, 2] + indices = [2, 1, 3] expected_tokens = ['b', 'a', 'c'] self.assertEqual(v.lookup_tokens(indices), expected_tokens) @@ -132,47 +140,66 @@ def test_vocab_lookup_indices(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c) + v = vocab(c) tokens = ['b', 'a', 'c'] - expected_indices = [1, 0, 2] + expected_indices = [2, 1, 3] self.assertEqual(v.lookup_indices(tokens), expected_indices) - def test_errors(self): - token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + def test_vocab_call_method(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c) - with self.assertRaises(ValueError): - # Test proper error raised when setting unk token to None - Vocab(c, unk_token=None) + tokens = ['b', 'a', 'c'] + expected_indices = [2, 1, 3] + + self.assertEqual(v(tokens), expected_indices) + + # we separate out these errors because Windows runs into seg faults when propagating + # exceptions from C++ using pybind11 + @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") + def test_errors_vocab_cpp(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) with self.assertRaises(RuntimeError): # Test proper error raised when setting a token out of bounds - v = Vocab(c, min_freq=3) + v = vocab(c, min_freq=3) v.insert_token('new_token', 100) with self.assertRaises(RuntimeError): # Test proper error raised when looking up a token out of bounds - v = Vocab(c) + v = vocab(c) v.lookup_token(100) + def test_errors_vocab_python(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + + with self.assertRaises(ValueError): + # Test proper error raised when setting unk token to None + vocab(c, unk_token=None) + def test_vocab_load_and_save(self): token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) c = OrderedDict(sorted_by_freq_tuples) - v = Vocab(c, min_freq=3) + v = vocab(c, min_freq=3) - expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) vocab_path = os.path.join(self.test_dir, 'vocab.pt') - torch.save(v, vocab_path) + torch.save(v.to_ivalue(), vocab_path) loaded_v = torch.load(vocab_path) self.assertEqual(v.get_itos(), expected_itos) diff --git a/test/test_utils.py b/test/test_utils.py index 73ee992de3..1f9f75369c 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -3,6 +3,8 @@ import os from torchtext import utils from .common.torchtext_test_case import TorchtextTestCase +from test.common.assets import get_asset_path +import shutil def conditional_remove(f): @@ -104,6 +106,18 @@ def test_download_extract_zip(self): os.rmdir(os.path.join(root, 'en-ud-v2')) conditional_remove(archive_path) + def test_no_download(self): + asset_name = 'glove.840B.300d.zip' + asset_path = get_asset_path(asset_name) + root = '.data' + if not os.path.exists(root): + os.makedirs(root) + data_path = os.path.join('.data', asset_name) + shutil.copy(asset_path, data_path) + file_path = utils.download_from_url('fakedownload/glove.840B.300d.zip') + self.assertEqual(file_path, data_path) + conditional_remove(data_path) + def test_download_extract_to_path(self): # create root directory for downloading data root = '.data' diff --git a/torchtext/csrc/common.cpp b/torchtext/csrc/common.cpp new file mode 100644 index 0000000000..dfa41e068f --- /dev/null +++ b/torchtext/csrc/common.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include + +namespace torchtext { +namespace impl { + +int64_t divup(int64_t x, int64_t y) { return (x + y - 1) / y; } + +void infer_offsets(const std::string &file_path, int64_t num_lines, + int64_t chunk_size, std::vector &offsets, + int64_t num_header_lines) { + std::ifstream fin; + fin.open(file_path, std::ios::in); + + while (num_header_lines > 0) { + fin.ignore(std::numeric_limits::max(), '\n'); + num_header_lines--; + } + offsets.push_back(fin.tellg()); + size_t offset = 0; + while (fin.ignore(std::numeric_limits::max(), '\n')) { + offset++; + if (offset % chunk_size == 0) { + offsets.push_back(fin.tellg()); + } + } +} + +} // namespace impl +} // namespace torchtext diff --git a/torchtext/csrc/common.h b/torchtext/csrc/common.h new file mode 100644 index 0000000000..20c975a351 --- /dev/null +++ b/torchtext/csrc/common.h @@ -0,0 +1,9 @@ +namespace torchtext { + +namespace impl { +int64_t divup(int64_t x, int64_t y); +void infer_offsets(const std::string &file_path, int64_t num_lines, + int64_t chunk_size, std::vector &offsets, + int64_t num_header_lines = 0); +} // namespace impl +} // namespace torchtext diff --git a/torchtext/csrc/regex.cpp b/torchtext/csrc/regex.cpp index 1638c1f8e0..f2051e0de0 100644 --- a/torchtext/csrc/regex.cpp +++ b/torchtext/csrc/regex.cpp @@ -1,41 +1,14 @@ -#include -#include -#include +#include namespace torchtext { -namespace { -struct Regex : torch::CustomClassHolder { -public: - // re_str_ holds the serialized regex string passed at the initialization. - // We need this because we need to be able to serialize the model so that we - // can save the scripted object. pickle will get the - // serialized model from this re_str_ member, thus it needs to be public. - std::string re_str_; +Regex::Regex(const std::string &re_str) : re_str_(re_str) { + compiled_pattern_ = new RE2(re_str_); +} - Regex(const std::string &re_str) : re_str_(re_str) {} +std::string Regex::Sub(std::string str, const std::string &repl) const { + RE2::GlobalReplace(&str, *compiled_pattern_, repl); + return str; +} - std::string Sub(const std::string &str, const std::string &repl) const { - std::string mutable_str = str; - RE2::GlobalReplace(&mutable_str, re_str_, repl); - return mutable_str; - } -}; - -// Registers our custom class with torch. -static auto regex = - torch::class_("torchtext", "Regex") - .def(torch::init()) - .def("Sub", &Regex::Sub) - .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> std::string { - return self->re_str_; - }, - // __setstate__ - [](std::string state) -> c10::intrusive_ptr { - return c10::make_intrusive(std::move(state)); - }); - -} // namespace } // namespace torchtext diff --git a/torchtext/csrc/regex.h b/torchtext/csrc/regex.h new file mode 100644 index 0000000000..c5d871479c --- /dev/null +++ b/torchtext/csrc/regex.h @@ -0,0 +1,16 @@ +#include +#include +#include + +namespace torchtext { +struct Regex : torch::CustomClassHolder { +private: + RE2 *compiled_pattern_; + +public: + std::string re_str_; + + Regex(const std::string &re_str); + std::string Sub(std::string str, const std::string &repl) const; +}; +} // namespace torchtext diff --git a/torchtext/csrc/regex_tokenizer.cpp b/torchtext/csrc/regex_tokenizer.cpp new file mode 100644 index 0000000000..3ab73e587c --- /dev/null +++ b/torchtext/csrc/regex_tokenizer.cpp @@ -0,0 +1,47 @@ +#include "regex_tokenizer.h" +#include + +namespace torchtext { + +RegexTokenizer::RegexTokenizer(const std::vector &patterns, + const std::vector &replacements, + const bool to_lower = false) + : patterns_(std::move(patterns)), replacements_(std::move(replacements)), + to_lower_(to_lower) { + TORCH_CHECK(patterns.size() == replacements.size(), + "Expected `patterns` and `replacements` to have same size!"); + + for (const auto &pattern : patterns_) { + compiled_patterns_.push_back(new RE2(pattern)); + } +} + +std::vector RegexTokenizer::forward(std::string str) const { + // str tolower + if (to_lower_) { + std::transform(str.begin(), str.end(), str.begin(), + [](unsigned char c) { return std::tolower(c); }); + } + + for (size_t i = 0; i < compiled_patterns_.size(); i++) { + RE2::GlobalReplace(&str, *compiled_patterns_[i], replacements_[i]); + } + + std::vector tokens; + split_(str, tokens); + return tokens; +} + +void RegexTokenizer::split_(std::string &str, std::vector &tokens, + const char &delimiter) const { + std::stringstream ss(str); + std::string token; + + while (std::getline(ss, token, delimiter)) { + if (!token.empty()) { + tokens.push_back(token); + } + } +} + +} // namespace torchtext diff --git a/torchtext/csrc/regex_tokenizer.h b/torchtext/csrc/regex_tokenizer.h new file mode 100644 index 0000000000..d0d9cfbb62 --- /dev/null +++ b/torchtext/csrc/regex_tokenizer.h @@ -0,0 +1,23 @@ +#include +#include + +namespace torchtext { + +struct RegexTokenizer : torch::CustomClassHolder { +private: + std::vector compiled_patterns_; + void split_(std::string &str, std::vector &tokens, + const char &delimiter = ' ') const; + +public: + std::vector patterns_; + std::vector replacements_; + bool to_lower_; + + explicit RegexTokenizer(const std::vector &patterns, + const std::vector &replacements, + const bool to_lower); + std::vector forward(std::string str) const; +}; + +} // namespace torchtext diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp new file mode 100644 index 0000000000..28bb239cd5 --- /dev/null +++ b/torchtext/csrc/register_bindings.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include "regex_tokenizer.h" +#include "sentencepiece.h" +#include // @manual +#include +#include "vectors.h" +#include "vocab.h" + +namespace torchtext { + +namespace py = pybind11; +// Registers our custom classes with pybind11. +PYBIND11_MODULE(_torchtext, m) { + // Classes + py::class_(m, "Regex") + .def(py::init()) + .def("Sub", &Regex::Sub); + + py::class_(m, "RegexTokenizer") + .def_readonly("patterns_", &RegexTokenizer::patterns_) + .def_readonly("replacements_", &RegexTokenizer::replacements_) + .def_readonly("to_lower_", &RegexTokenizer::to_lower_) + .def(py::init, std::vector, bool>()) + .def("forward", &RegexTokenizer::forward); + + py::class_(m, "SentencePiece") + .def("Encode", &SentencePiece::Encode) + .def("EncodeAsIds", &SentencePiece::EncodeAsIds) + .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) + .def("GetPieceSize", &SentencePiece::GetPieceSize) + .def("unk_id", &SentencePiece::unk_id) + .def("PieceToId", &SentencePiece::PieceToId) + .def("IdToPiece", &SentencePiece::IdToPiece); + + py::class_(m, "Vectors") + .def(py::init, std::vector, + torch::Tensor, torch::Tensor>()) + .def_readonly("vectors_", &Vectors::vectors_) + .def_readonly("unk_tensor_", &Vectors::unk_tensor_) + .def("get_stoi", &Vectors::get_stoi) + .def("__getitem__", &Vectors::__getitem__) + .def("lookup_vectors", &Vectors::lookup_vectors) + .def("__setitem__", &Vectors::__setitem__) + .def("__len__", &Vectors::__len__); + + py::class_(m, "Vocab") + .def(py::init, std::string>()) + .def_readonly("itos_", &Vocab::itos_) + .def_readonly("unk_token_", &Vocab::unk_token_) + .def("__getitem__", &Vocab::__getitem__) + .def("__len__", &Vocab::__len__) + .def("insert_token", &Vocab::insert_token) + .def("append_token", &Vocab::append_token) + .def("lookup_token", &Vocab::lookup_token) + .def("lookup_tokens", &Vocab::lookup_tokens) + .def("lookup_indices", &Vocab::lookup_indices) + .def("get_stoi", &Vocab::get_stoi) + .def("get_itos", &Vocab::get_itos); + + // Functions + m.def("_load_token_and_vectors_from_file", + &_load_token_and_vectors_from_file); + m.def("_load_vocab_from_file", &_load_vocab_from_file); +} + +// Registers our custom classes with torch. +static auto regex = + torch::class_("torchtext", "Regex") + .def(torch::init()) + .def("Sub", &Regex::Sub) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return self->re_str_; + }, + // __setstate__ + [](std::string state) -> c10::intrusive_ptr { + return c10::make_intrusive(std::move(state)); + }); + +static auto regex_tokenizer = + torch::class_("torchtext", "RegexTokenizer") + .def(torch::init, std::vector, + bool>()) + .def("forward", &RegexTokenizer::forward) + .def_pickle( + // __setstate__ + [](const c10::intrusive_ptr &self) + -> std::tuple, + std::vector, bool> { + return std::make_tuple(self->patterns_, self->replacements_, + self->to_lower_); + }, + // __getstate__ + [](std::tuple, std::vector, + bool> + states) -> c10::intrusive_ptr { + auto patterns = std::get<0>(states); + auto replacements = std::get<1>(states); + auto to_lower = std::get<2>(states); + + return c10::make_intrusive( + std::move(patterns), std::move(replacements), to_lower); + }); + +static auto sentencepiece = + torch::class_("torchtext", "SentencePiece") + .def("Encode", &SentencePiece::Encode) + .def("EncodeAsIds", &SentencePiece::EncodeAsIds) + .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) + .def("GetPieceSize", &SentencePiece::GetPieceSize) + .def("unk_id", &SentencePiece::unk_id) + .def("PieceToId", &SentencePiece::PieceToId) + .def("IdToPiece", &SentencePiece::IdToPiece) + .def_pickle( + // __setstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return self->content_; + }, + // __getstate__ + [](std::string state) -> c10::intrusive_ptr { + return c10::make_intrusive(std::move(state)); + }); + +static auto vocab = + torch::class_("torchtext", "Vocab") + .def(torch::init()) + .def("__getitem__", &Vocab::__getitem__) + .def("__len__", &Vocab::__len__) + .def("insert_token", &Vocab::insert_token) + .def("append_token", &Vocab::append_token) + .def("lookup_token", &Vocab::lookup_token) + .def("lookup_tokens", &Vocab::lookup_tokens) + .def("lookup_indices", &Vocab::lookup_indices) + .def("get_stoi", &Vocab::get_stoi) + .def("get_itos", &Vocab::get_itos) + .def_pickle( + // __setstate__ + [](const c10::intrusive_ptr &self) -> VocabStates { + return _set_vocab_states(self); + }, + // __getstate__ + [](VocabStates states) -> c10::intrusive_ptr { + return _get_vocab_from_states(states); + }); + +static auto vectors = + torch::class_("torchtext", "Vectors") + .def(torch::init, std::vector, + torch::Tensor, torch::Tensor>()) + .def("__getitem__", &Vectors::__getitem__) + .def("lookup_vectors", &Vectors::lookup_vectors) + .def("__setitem__", &Vectors::__setitem__) + .def("__len__", &Vectors::__len__) + .def_pickle( + // __setstate__ + [](const c10::intrusive_ptr &self) -> VectorsStates { + return _set_vectors_states(self); + }, + // __getstate__ + [](VectorsStates states) -> c10::intrusive_ptr { + return _get_vectors_from_states(states); + }); + +// Registers our custom op with torch. +static auto registry = + torch::RegisterOperators() + .op("torchtext::generate_sp_model", &generate_sp_model) + .op(torch::RegisterOperators::options() + .schema("torchtext::load_sp_model(str path) -> " + "__torch__.torch.classes.torchtext.SentencePiece model") + .catchAllKernel()); +} // namespace torchtext diff --git a/torchtext/csrc/sentencepiece.cpp b/torchtext/csrc/sentencepiece.cpp index 59873d98a8..5d2f28eb7d 100644 --- a/torchtext/csrc/sentencepiece.cpp +++ b/torchtext/csrc/sentencepiece.cpp @@ -1,86 +1,45 @@ -#include -#include -#include - -#ifdef _WIN32 -#include -PyMODINIT_FUNC PyInit__torchtext(void) { - // No need to do anything. - // extension.py will run on load - return NULL; -} -#endif +#include "sentencepiece.h" namespace torchtext { -namespace { - -struct SentencePiece : torch::CustomClassHolder { -private: - sentencepiece::SentencePieceProcessor processor_; - -public: - // content_ holds the serialized model data passed at the initialization. - // We need this because the underlying SentencePieceProcessor class does not - // provide serialization mechanism, yet we still need to be able to serialize - // the model so that we can save the scripted object. pickle will get the - // serialized model from this content_ member, thus it needs to be public. - const std::string content_; - - explicit SentencePiece(const std::string &content) : content_(content) { - const auto status = processor_.LoadFromSerializedProto(content_); - if (!status.ok()) { - throw std::runtime_error("Failed to load SentencePiece model. Error: " + - status.ToString()); - } - } - std::vector Encode(const std::string &input) const { - std::vector pieces; - processor_.Encode(input, &pieces); - return pieces; +SentencePiece::SentencePiece(const std::string &content) : content_(content) { + const auto status = processor_.LoadFromSerializedProto(content_); + if (!status.ok()) { + throw std::runtime_error("Failed to load SentencePiece model. Error: " + + status.ToString()); } +} - std::vector EncodeAsIds(const std::string &input) const { - const auto val = processor_.EncodeAsIds(input); - return std::vector(val.begin(), val.end()); - } +std::vector SentencePiece::Encode(const std::string &input) const { + std::vector pieces; + processor_.Encode(input, &pieces); + return pieces; +} - std::vector EncodeAsPieces(const std::string &input) const { - return processor_.EncodeAsPieces(input); - } +std::vector +SentencePiece::EncodeAsIds(const std::string &input) const { + const auto val = processor_.EncodeAsIds(input); + return std::vector(val.begin(), val.end()); +} - int64_t GetPieceSize() const { return processor_.GetPieceSize(); } +std::vector +SentencePiece::EncodeAsPieces(const std::string &input) const { + return processor_.EncodeAsPieces(input); +} - int64_t unk_id() const { return processor_.unk_id(); } +int64_t SentencePiece::GetPieceSize() const { + return processor_.GetPieceSize(); +} - int64_t PieceToId(const std::string &piece) const { - return processor_.PieceToId(piece); - } +int64_t SentencePiece::unk_id() const { return processor_.unk_id(); } - std::string IdToPiece(const int64_t id) const { - return processor_.IdToPiece(id); - } -}; +int64_t SentencePiece::PieceToId(const std::string &piece) const { + return processor_.PieceToId(piece); +} -// Registers our custom class with torch. -static auto sentencepiece = - torch::class_("torchtext", "SentencePiece") - .def("Encode", &SentencePiece::Encode) - .def("EncodeAsIds", &SentencePiece::EncodeAsIds) - .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) - .def("GetPieceSize", &SentencePiece::GetPieceSize) - .def("unk_id", &SentencePiece::unk_id) - .def("PieceToId", &SentencePiece::PieceToId) - .def("IdToPiece", &SentencePiece::IdToPiece) - .def_pickle( - // __setstate__ - [](const c10::intrusive_ptr &self) -> std::string { - return self->content_; - }, - // __getstate__ - [](std::string state) -> c10::intrusive_ptr { - return c10::make_intrusive(std::move(state)); - }); +std::string SentencePiece::IdToPiece(const int64_t id) const { + return processor_.IdToPiece(id); +} void generate_sp_model(const std::string &filename, const int64_t &vocab_size, const std::string &model_type, @@ -105,13 +64,4 @@ c10::intrusive_ptr load_sp_model(const std::string &path) { return c10::make_intrusive(std::move(content)); } -static auto registry = - torch::RegisterOperators() - .op("torchtext::generate_sp_model", &generate_sp_model) - .op(torch::RegisterOperators::options() - .schema("torchtext::load_sp_model(str path) -> " - "__torch__.torch.classes.torchtext.SentencePiece model") - .catchAllKernel()); - -} // namespace } // namespace torchtext diff --git a/torchtext/csrc/sentencepiece.h b/torchtext/csrc/sentencepiece.h new file mode 100644 index 0000000000..b6786eab29 --- /dev/null +++ b/torchtext/csrc/sentencepiece.h @@ -0,0 +1,34 @@ +#include +#include +#include + +namespace torchtext { + +struct SentencePiece : torch::CustomClassHolder { +private: + sentencepiece::SentencePieceProcessor processor_; + +public: + // content_ holds the serialized model data passed at the initialization. + // We need this because the underlying SentencePieceProcessor class does not + // provide serialization mechanism, yet we still need to be able to serialize + // the model so that we can save the scripted object. pickle will get the + // serialized model from this content_ member, thus it needs to be public. + const std::string content_; + + explicit SentencePiece(const std::string &content); + std::vector Encode(const std::string &input) const; + std::vector EncodeAsIds(const std::string &input) const; + std::vector EncodeAsPieces(const std::string &input) const; + int64_t GetPieceSize() const; + int64_t unk_id() const; + int64_t PieceToId(const std::string &piece) const; + std::string IdToPiece(const int64_t id) const; +}; + +void generate_sp_model(const std::string &filename, const int64_t &vocab_size, + const std::string &model_type, + const std::string &model_prefix); +c10::intrusive_ptr load_sp_model(const std::string &path); + +} // namespace torchtext diff --git a/torchtext/csrc/vectors.cpp b/torchtext/csrc/vectors.cpp index 8597bba614..f115c7b9b9 100644 --- a/torchtext/csrc/vectors.cpp +++ b/torchtext/csrc/vectors.cpp @@ -1,5 +1,6 @@ #include // @manual #include +#include #include #include #include @@ -10,104 +11,101 @@ #include #include #include -#include - -using c10::Dict; +#include "vectors.h" namespace torchtext { -namespace { - -typedef ska_ordered::order_preserving_flat_hash_map - VectorsMap; -typedef ska_ordered::order_preserving_flat_hash_map - IndexMap; -typedef std::vector StringList; -typedef std::tuple, std::vector, - std::vector> - VectorsStates; - -struct Vectors : torch::CustomClassHolder { -public: - const std::string version_str_ = "0.0.1"; - - IndexMap stoindex_; - VectorsMap stovec_; - - torch::Tensor vectors_; - torch::Tensor unk_tensor_; - - explicit Vectors(const IndexMap &stoindex, const torch::Tensor vectors, - const torch::Tensor &unk_tensor) - : stoindex_(stoindex), vectors_(vectors), unk_tensor_(unk_tensor) {} - - explicit Vectors(const std::vector &tokens, - const torch::Tensor &vectors, - const torch::Tensor &unk_tensor) - : vectors_(std::move(vectors)), unk_tensor_(std::move(unk_tensor)) { - // guarding against size mismatch of vectors and tokens - if (static_cast(tokens.size()) != vectors.size(0)) { - throw std::runtime_error( - "Mismatching sizes for tokens and vectors. Size of tokens: " + - std::to_string(tokens.size()) + - ", size of vectors: " + std::to_string(vectors.size(0)) + "."); - } - stoindex_.reserve(tokens.size()); - stovec_.reserve(tokens.size()); - for (std::size_t i = 0; i < tokens.size(); i++) { - // tokens should not have any duplicates - const auto &item_index = stoindex_.find(tokens[i]); - if (item_index != stoindex_.end()) { - throw std::runtime_error("Duplicate token found in tokens list: " + - tokens[i]); - } - stoindex_[std::move(tokens[i])] = i; - } +Vectors::Vectors(const IndexMap &stoi, const torch::Tensor vectors, + const torch::Tensor &unk_tensor) + : stoi_(stoi), vectors_(vectors), unk_tensor_(unk_tensor) {} + +Vectors::Vectors(const std::vector &tokens, + const std::vector &indices, + const torch::Tensor &vectors, const torch::Tensor &unk_tensor) + : vectors_(std::move(vectors)), unk_tensor_(std::move(unk_tensor)) { + // guarding against size mismatch of tokens and indices + if (static_cast(tokens.size()) != indices.size()) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Mismatching sizes for tokens and indices. " + "Size of tokens: " + << tokens.size() << ", size of indices: " << indices.size() + << std::endl; +#endif + throw std::runtime_error( + "Mismatching sizes for tokens and indices. Size of tokens: " + + std::to_string(tokens.size()) + + ", size of indices: " + std::to_string(indices.size()) + "."); } - torch::Tensor __getitem__(const std::string &token) { - const auto &item = stovec_.find(token); - if (item != stovec_.end()) { - return item->second; + stoi_.reserve(tokens.size()); + stovec_.reserve(tokens.size()); + for (std::size_t i = 0; i < tokens.size(); i++) { + // tokens should not have any duplicates + const auto &item_index = stoi_.find(tokens[i]); + if (item_index != stoi_.end()) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Duplicate token found in tokens list: " + << tokens[i] << std::endl; +#endif + throw std::runtime_error("Duplicate token found in tokens list: " + + tokens[i]); } + stoi_[tokens[i]] = indices[i]; + } +} - const auto &item_index = stoindex_.find(token); - if (item_index != stoindex_.end()) { - auto vector = vectors_[item_index->second]; - stovec_[token] = vector; - return vector; - } - return unk_tensor_; +torch::Tensor Vectors::__getitem__(const std::string &token) { + const auto &item = stovec_.find(token); + if (item != stovec_.end()) { + return item->second; } - torch::Tensor lookup_vectors(const std::vector &tokens) { - std::vector vectors; - for (const std::string &token : tokens) { - vectors.push_back(__getitem__(token)); - } + const auto &item_index = stoi_.find(token); + if (item_index != stoi_.end()) { + auto vector = vectors_[item_index->second]; + stovec_[token] = vector; + return vector; + } + return unk_tensor_; +} - return torch::stack(vectors, 0); +torch::Tensor Vectors::lookup_vectors(const std::vector &tokens) { + std::vector vectors; + for (const std::string &token : tokens) { + vectors.push_back(__getitem__(token)); } + return torch::stack(vectors, 0); +} - void __setitem__(const std::string &token, const torch::Tensor &vector) { - const auto &item_index = stoindex_.find(token); - if (item_index != stoindex_.end()) { - stovec_[token] = vector; - vectors_[item_index->second] = vector; - } else { - stoindex_[token] = vectors_.size(0); - stovec_[token] = vector; - // TODO: This could be done lazily during serialization (if necessary). - // We would cycle through the vectors and concatenate those that aren't - // views. - vectors_ = at::cat({vectors_, vector.unsqueeze(0)}); - } +void Vectors::__setitem__(const std::string &token, + const torch::Tensor &vector) { + const auto &item_index = stoi_.find(token); + if (item_index != stoi_.end()) { + stovec_[token] = vector; + vectors_[item_index->second] = vector; + } else { + stoi_[token] = vectors_.size(0); + stovec_[token] = vector; + // TODO: This could be done lazily during serialization (if necessary). + // We would cycle through the vectors and concatenate those that aren't + // views. + vectors_ = at::cat({vectors_, vector.unsqueeze(0)}); } +} + +int64_t Vectors::__len__() { return stovec_.size(); } - int64_t __len__() { return stovec_.size(); } -}; +std::unordered_map Vectors::get_stoi() { + std::unordered_map stoi; + stoi.reserve(stoi_.size()); -inline int64_t divup(int64_t x, int64_t y) { return (x + y - 1) / y; } + // construct tokens and index list + for (const auto &item : stoi_) { + stoi[item.first] = item.second; + } + + return stoi; +} std::tuple _infer_shape(const std::string &file_path, const char delimiter) { @@ -146,31 +144,10 @@ std::tuple _infer_shape(const std::string &file_path, return std::make_tuple(num_lines, num_header_lines, vector_dim); } -void _infer_offsets(const std::string &file_path, int64_t num_lines, - int64_t chunk_size, int64_t num_header_lines, - std::vector &offsets) { - - std::ifstream fin; - fin.open(file_path, std::ios::in); - - while (num_header_lines > 0) { - fin.ignore(std::numeric_limits::max(), '\n'); - num_header_lines--; - } - offsets.push_back(fin.tellg()); - size_t offset = 0; - while (fin.ignore(std::numeric_limits::max(), '\n')) { - offset++; - if (offset % chunk_size == 0) { - offsets.push_back(fin.tellg()); - } - } -} - -void parse_chunk(const std::string &file_path, size_t offset, - const int64_t start_line, const int64_t end_line, - const int64_t vector_dim, const char delimiter, - std::shared_ptr tokens, float *data_ptr) { +void parse_vectors_chunk(const std::string &file_path, size_t offset, + const int64_t start_line, const int64_t end_line, + const int64_t vector_dim, const char delimiter, + std::shared_ptr tokens, float *data_ptr) { std::ifstream fin; fin.open(file_path, std::ios::in); fin.seekg(offset); @@ -203,7 +180,7 @@ void parse_chunk(const std::string &file_path, size_t offset, std::tuple _concat_vectors(std::vector> chunk_tokens, - int64_t num_header_lines, int64_t num_lines) { + const int64_t num_header_lines, const int64_t num_lines) { TORCH_CHECK(chunk_tokens.size() > 0, "There must be at least 1 chunk to concatenate!"); IndexMap tokens; @@ -228,11 +205,10 @@ _concat_vectors(std::vector> chunk_tokens, } constexpr int64_t GRAIN_SIZE = 131072; -std::tuple, std::vector> -_load_token_and_vectors_from_file(const std::string &file_path, - const std::string delimiter_str, - int64_t num_cpus, - c10::optional opt_unk_tensor) { +std::tuple> _load_token_and_vectors_from_file( + const std::string &file_path, const std::string delimiter_str, + int64_t num_cpus, c10::optional opt_unk_tensor) { + TORCH_CHECK(delimiter_str.size() == 1, "Only string delimeters of size 1 are supported."); std::cerr << "[INFO] Reading file " << file_path << std::endl; @@ -242,13 +218,14 @@ _load_token_and_vectors_from_file(const std::string &file_path, std::tie(num_lines, num_header_lines, vector_dim) = _infer_shape(file_path, delimiter); - int64_t chunk_size = divup(num_lines, num_cpus); + int64_t chunk_size = impl::divup(num_lines, num_cpus); // Launching a thread on less lines than this likely has too much overhead. // TODO: Add explicit test beyond grain size to cover multithreading chunk_size = std::max(chunk_size, GRAIN_SIZE); std::vector offsets; - _infer_offsets(file_path, num_lines, chunk_size, num_header_lines, offsets); + impl::infer_offsets(file_path, num_lines, chunk_size, offsets, + num_header_lines); torch::Tensor data_tensor = torch::empty({num_lines, vector_dim}); float *data_ptr = data_tensor.data_ptr(); @@ -266,8 +243,9 @@ _load_token_and_vectors_from_file(const std::string &file_path, counter++; at::launch([&, file_path, num_lines, chunk_size, vector_dim, delimiter, j, i, tokens_ptr, data_ptr]() { - parse_chunk(file_path, offsets[j], i, std::min(num_lines, i + chunk_size), - vector_dim, delimiter, tokens_ptr, data_ptr); + parse_vectors_chunk(file_path, offsets[j], i, + std::min(num_lines, i + chunk_size), vector_dim, + delimiter, tokens_ptr, data_ptr); std::lock_guard lk(m); counter--; cv.notify_all(); @@ -280,9 +258,9 @@ _load_token_and_vectors_from_file(const std::string &file_path, std::unique_lock lock(m); cv.wait(lock, [&counter] { return counter == 0; }); - IndexMap stoindex; + IndexMap stoi; StringList dup_tokens; - std::tie(stoindex, dup_tokens) = + std::tie(stoi, dup_tokens) = _concat_vectors(chunk_tokens, num_header_lines, num_lines); torch::Tensor unk_tensor; @@ -291,21 +269,21 @@ _load_token_and_vectors_from_file(const std::string &file_path, } else { unk_tensor = torch::zeros({vector_dim}, torch::kFloat32); } - auto result = std::make_tuple( - c10::make_intrusive(Vectors(stoindex, data_tensor, unk_tensor)), - dup_tokens); + + auto result = + std::make_tuple(Vectors(stoi, data_tensor, unk_tensor), dup_tokens); return result; } VectorsStates _set_vectors_states(const c10::intrusive_ptr &self) { std::vector tokens; std::vector indices; - tokens.reserve(self->stoindex_.size()); - indices.reserve(self->stoindex_.size()); + tokens.reserve(self->stoi_.size()); + indices.reserve(self->stoi_.size()); // construct tokens and index list // we need to store indices because the `vectors_` tensor may have gaps - for (const auto &item : self->stoindex_) { + for (const auto &item : self->stoi_) { tokens.push_back(item.first); indices.push_back(item.second); } @@ -341,44 +319,17 @@ c10::intrusive_ptr _get_vectors_from_states(VectorsStates states) { "Expected `integers` and `strings` states to be the same size."); } - IndexMap stoindex; - stoindex.reserve(integers.size()); + IndexMap stoi; + stoi.reserve(integers.size()); for (size_t i = 0; i < integers.size(); i++) { - stoindex[strings[i]] = integers[i]; + stoi[strings[i]] = integers[i]; } - return c10::make_intrusive( - std::move(stoindex), std::move(tensors[0]), std::move(tensors[1])); + return c10::make_intrusive(std::move(stoi), std::move(tensors[0]), + std::move(tensors[1])); } throw std::runtime_error( "Found unexpected version for serialized Vector: " + version_str + "."); } - -// Registers our custom class with torch. -static auto vectors = - torch::class_("torchtext", "Vectors") - .def(torch::init, torch::Tensor, - torch::Tensor>()) - .def("__getitem__", &Vectors::__getitem__) - .def("lookup_vectors", &Vectors::lookup_vectors) - .def("__setitem__", &Vectors::__setitem__) - .def("__len__", &Vectors::__len__) - .def_pickle( - // __setstate__ - [](const c10::intrusive_ptr &self) -> VectorsStates { - return _set_vectors_states(self); - }, - // __getstate__ - [](VectorsStates states) -> c10::intrusive_ptr { - return _get_vectors_from_states(states); - }); - -// Registers our custom op with torch. -TORCH_LIBRARY(torchtext, m) { - m.def("_load_token_and_vectors_from_file", - &_load_token_and_vectors_from_file); -} - -} // namespace } // namespace torchtext diff --git a/torchtext/csrc/vectors.h b/torchtext/csrc/vectors.h new file mode 100644 index 0000000000..fde1f257f0 --- /dev/null +++ b/torchtext/csrc/vectors.h @@ -0,0 +1,42 @@ +#include + +namespace torchtext { + +typedef std::vector StringList; +typedef ska_ordered::order_preserving_flat_hash_map + VectorsMap; +typedef ska_ordered::order_preserving_flat_hash_map + IndexMap; +typedef std::tuple, std::vector, + std::vector> + VectorsStates; + +struct Vectors : torch::CustomClassHolder { +public: + const std::string version_str_ = "0.0.1"; + IndexMap stoi_; + VectorsMap stovec_; + torch::Tensor vectors_; + torch::Tensor unk_tensor_; + + explicit Vectors(const IndexMap &stoi, const torch::Tensor vectors, + const torch::Tensor &unk_tensor); + explicit Vectors(const std::vector &tokens, + const std::vector &indices, + const torch::Tensor &vectors, + const torch::Tensor &unk_tensor); + std::unordered_map get_stoi(); + torch::Tensor __getitem__(const std::string &token); + torch::Tensor lookup_vectors(const std::vector &tokens); + void __setitem__(const std::string &token, const torch::Tensor &vector); + int64_t __len__(); +}; + +c10::intrusive_ptr _get_vectors_from_states(VectorsStates states); +VectorsStates _set_vectors_states(const c10::intrusive_ptr &self); + +std::tuple> _load_token_and_vectors_from_file( + const std::string &file_path, const std::string delimiter_str, + const int64_t num_cpus, c10::optional opt_unk_tensor); + +} // namespace torchtext diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 656d1c3bff..78fcf3e1e9 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -1,119 +1,275 @@ +#include // @manual +#include #include #include -#include +#include "vocab.h" namespace torchtext { -namespace { - -using c10::Dict; - -typedef std::tuple, std::vector, - std::vector> - VocabStates; - -struct Vocab : torch::CustomClassHolder { -private: - int64_t unk_index_; - Dict stoi_; - -public: - const std::string version_str_ = "0.0.1"; - std::vector itos_; - std::string unk_token_; - - explicit Vocab(const std::vector &tokens, - const std::string &unk_token) - : itos_(std::move(tokens)), unk_token_(std::move(unk_token)) { - stoi_.reserve(tokens.size()); - for (std::size_t i = 0; i < tokens.size(); i++) { - // tokens should not have any duplicates - if (stoi_.find(tokens[i]) != stoi_.end()) { - throw std::runtime_error("Duplicate token found in tokens list: " + - tokens[i]); - } - stoi_.insert(std::move(tokens[i]), i); + +Vocab::Vocab(const StringList &tokens, const IndexDict &stoi, + const std::string &unk_token, const int64_t unk_index) + : unk_index_(std::move(unk_index)), stoi_(std::move(stoi)), + itos_(std::move(tokens)), unk_token_(std::move(unk_token)) {} + +Vocab::Vocab(const StringList &tokens, const std::string &unk_token) + : itos_(std::move(tokens)), unk_token_(std::move(unk_token)) { + stoi_.reserve(tokens.size()); + for (std::size_t i = 0; i < tokens.size(); i++) { + // tokens should not have any duplicates + if (stoi_.find(tokens[i]) != stoi_.end()) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Duplicate token found in tokens list: " + << tokens[i] << std::endl; +#endif + throw std::runtime_error("Duplicate token found in tokens list: " + + tokens[i]); } - unk_index_ = stoi_.find(unk_token)->value(); + stoi_[std::move(tokens[i])] = i; } + unk_index_ = stoi_.find(unk_token)->second; +} - int64_t __len__() const { return stoi_.size(); } +int64_t Vocab::__len__() const { return stoi_.size(); } - int64_t __getitem__(const std::string &token) const { - const auto &item = stoi_.find(token); - if (item != stoi_.end()) { - return item->value(); - } - return unk_index_; +int64_t Vocab::__getitem__(const std::string &token) const { + const auto &item = stoi_.find(token); + if (item != stoi_.end()) { + return item->second; } + return unk_index_; +} - void append_token(const std::string &token) { - if (stoi_.find(token) == stoi_.end()) { - stoi_.insert(std::move(token), stoi_.size()); - } +void Vocab::append_token(const std::string &token) { + if (stoi_.find(token) == stoi_.end()) { + // Note: we can't do `stoi_[token] = stoi_.size()` because of a bug + // on Windows where the size gets updated before the assign occurs. + // For example if the size of `stoi_` is 2, doing + // `stoi_["test"] = stoi_.size()` will set `stoi_["test"]` to a + // value of 3 instead of 2 on Windows stoi_[token] = itos_.size(); + stoi_[token] = itos_.size(); + itos_.push_back(token); } +} - void insert_token(const std::string &token, const int64_t &index) { - if (index < 0 || index > static_cast(stoi_.size())) { - throw std::runtime_error( - "Specified index " + std::to_string(index) + - " is out of bounds of the size of stoi dictionary: " + - std::to_string(stoi_.size()) + "."); - } +void Vocab::insert_token(const std::string &token, const int64_t &index) { + if (index < 0 || index > static_cast(stoi_.size())) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Specified index " << index + << " is out of bounds of the size of stoi dictionary: " + << stoi_.size() << std::endl; +#endif + throw std::runtime_error( + "Specified index " + std::to_string(index) + + " is out of bounds of the size of stoi dictionary: " + + std::to_string(stoi_.size()) + "."); + } - const auto &item = stoi_.find(token); - // if item already in stoi we throw an error - if (item != stoi_.end()) { - throw std::runtime_error("Token " + token + - " already exists in the Vocab with index: " + - std::to_string(item->value()) + "."); - } + const auto &item = stoi_.find(token); + // if item already in stoi we throw an error + if (item != stoi_.end()) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Token " << token + << " already exists in the Vocab with index: " << item->second + << std::endl; +#endif + throw std::runtime_error("Token " + token + + " already exists in the Vocab with index: " + + std::to_string(item->second) + "."); + } - // need to offset all tokens greater than or equal index by 1 - for (size_t i = index; i < itos_.size(); i++) { - stoi_.insert_or_assign(itos_[i], std::move(i + 1)); - } - stoi_.insert(std::move(token), std::move(index)); - itos_.insert(itos_.begin() + index, std::move(token)); + // need to offset all tokens greater than or equal index by 1 + for (size_t i = index; i < itos_.size(); i++) { + stoi_[itos_[i]] = i + 1; + } - // need to update unk_index in case token equals unk_token or token inserted - // before unk_token - unk_index_ = stoi_.find(unk_token_)->value(); + stoi_[token] = index; + itos_.insert(itos_.begin() + index, token); + + // need to update unk_index in case token equals unk_token or token + // inserted before unk_token + unk_index_ = stoi_.find(unk_token_)->second; +} + +std::string Vocab::lookup_token(const int64_t &index) { + if (index < 0 || index > static_cast(itos_.size())) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Specified index " << index + << " is out of bounds of the size of itos dictionary: " + << stoi_.size() << std::endl; +#endif + throw std::runtime_error( + "Specified index " + std::to_string(index) + + " is out of bounds of the size of itos dictionary: " + + std::to_string(itos_.size()) + "."); } - std::string lookup_token(const int64_t &index) { - if (index < 0 || index > static_cast(itos_.size())) { - throw std::runtime_error( - "Specified index " + std::to_string(index) + - " is out of bounds of the size of itos dictionary: " + - std::to_string(itos_.size()) + "."); - } + return itos_[index]; +} + +StringList Vocab::lookup_tokens(const std::vector &indices) { + std::vector tokens(indices.size()); + for (int64_t i = 0; i < static_cast(indices.size()); i++) { + tokens[i] = lookup_token(indices[i]); + } + return tokens; +} + +std::vector Vocab::lookup_indices(const StringList &tokens) { + std::vector indices(tokens.size()); + for (int64_t i = 0; i < static_cast(tokens.size()); i++) { + indices[i] = __getitem__(tokens[i]); + } + return indices; +} + +std::unordered_map Vocab::get_stoi() const { + std::unordered_map stoi; + stoi.reserve(stoi_.size()); + + // construct tokens and index list + for (const auto &item : stoi_) { + stoi[item.first] = item.second; + } + return stoi; +} + +StringList Vocab::get_itos() const { return itos_; } - return itos_[index]; +int64_t _infer_lines(const std::string &file_path) { + int64_t num_lines = 0; + std::ifstream fin; + fin.open(file_path, std::ios::in); + + while (fin.ignore(std::numeric_limits::max(), '\n')) { + num_lines++; } + return num_lines; +} - std::vector lookup_tokens(const std::vector &indices) { - std::vector tokens(indices.size()); - for (int64_t i = 0; i < static_cast(indices.size()); i++) { - tokens[i] = lookup_token(indices[i]); +void parse_vocab_chunk(const std::string &file_path, size_t offset, + const int64_t start_line, const int64_t end_line, + std::shared_ptr tokens) { + std::ifstream fin; + fin.open(file_path, std::ios::in); + fin.seekg(offset); + + for (int64_t i = start_line; i < end_line; i++) { + std::string token; + fin >> token; + fin >> std::ws; + + tokens->push_back(token); + } +} + +std::tuple +_concat_tokens(std::vector> chunk_tokens, + const std::string &unk_token, const int64_t min_freq, + const int64_t num_lines) { + TORCH_CHECK(chunk_tokens.size() > 0, + "There must be at least 1 chunk to concatenate!"); + + std::unordered_map tokens_freq; + IndexDict stoi; + StringList tokens; + stoi.reserve(num_lines); + tokens.reserve(num_lines); + + // create tokens frequency map + for (size_t i = 0; i < chunk_tokens.size(); i++) { + auto &subset_tokens = *chunk_tokens[i]; + for (size_t j = 0; j < subset_tokens.size(); j++) { + // const auto &item = tokens_freq.find(subset_tokens[j]); + if (tokens_freq.find(subset_tokens[j]) != tokens_freq.end()) { + tokens_freq[subset_tokens[j]]++; + } else { + tokens_freq[subset_tokens[j]] = 1; + } } - return tokens; } - std::vector lookup_indices(const std::vector &tokens) { - std::vector indices(tokens.size()); - for (int64_t i = 0; i < static_cast(tokens.size()); i++) { - indices[i] = __getitem__(tokens[i]); + int64_t index = 0; + // insert unk_token if not present + if (tokens_freq.find(unk_token) == tokens_freq.end()) { + std::cerr << "The `unk_token` " << unk_token + << " wasn't found in the `ordered_dict`. Adding the `unk_token` " + "to the beginning of the Vocab." + << std::endl; + + tokens.emplace_back(unk_token); + stoi[unk_token] = index; + } + + // create tokens list and stoi map + for (size_t i = 0; i < chunk_tokens.size(); i++) { + auto &subset_tokens = *chunk_tokens[i]; + for (size_t j = 0; j < subset_tokens.size(); j++) { + if (tokens_freq[subset_tokens[j]] >= min_freq && + stoi.find(subset_tokens[j]) == stoi.end()) { + tokens.emplace_back(subset_tokens[j]); + stoi[subset_tokens[j]] = index; + index++; + } } - return indices; } + return std::make_tuple(std::move(stoi), std::move(tokens)); +} + +constexpr int64_t GRAIN_SIZE = 13107; +Vocab _load_vocab_from_file(const std::string &file_path, + const std::string &unk_token, + const int64_t min_freq, const int64_t num_cpus) { + + std::cerr << "[INFO] Reading file " << file_path << std::endl; + + int64_t num_lines = _infer_lines(file_path); + int64_t chunk_size = impl::divup(num_lines, num_cpus); + // Launching a thread on less lines than this likely has too much overhead. + // TODO: Add explicit test beyond grain size to cover multithreading + chunk_size = std::max(chunk_size, GRAIN_SIZE); + + std::vector offsets; + impl::infer_offsets(file_path, num_lines, chunk_size, offsets); + + std::vector> chunk_tokens; + + std::mutex m; + std::condition_variable cv; + std::atomic counter(0); - Dict get_stoi() const { return stoi_; } - std::vector get_itos() const { return itos_; } -}; + // create threads + int64_t j = 0; + for (int64_t i = 0; i < num_lines; i += chunk_size) { + auto tokens_ptr = std::make_shared(); + + counter++; + at::launch([&, file_path, num_lines, chunk_size, j, i, tokens_ptr]() { + parse_vocab_chunk(file_path, offsets[j], i, + std::min(num_lines, i + chunk_size), tokens_ptr); + std::lock_guard lk(m); + counter--; + cv.notify_all(); + }); + chunk_tokens.push_back(tokens_ptr); + j++; + } + + // block until all threads finish execution + std::unique_lock lock(m); + cv.wait(lock, [&counter] { return counter == 0; }); + + IndexDict stoi; + StringList tokens; + std::tie(stoi, tokens) = + _concat_tokens(chunk_tokens, unk_token, min_freq, num_lines); + int64_t unk_index = stoi.find(unk_token)->second; + + return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); +} VocabStates _set_vocab_states(const c10::intrusive_ptr &self) { std::vector integers; - std::vector strings = self->itos_; + StringList strings = self->itos_; strings.push_back(self->unk_token_); std::vector tensors; @@ -125,8 +281,13 @@ VocabStates _set_vocab_states(const c10::intrusive_ptr &self) { c10::intrusive_ptr _get_vocab_from_states(VocabStates states) { auto state_size = std::tuple_size::value; if (state_size != 4) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Expected deserialized Vocab to have 4 states " + "but found " + << state_size << " states." << std::endl; +#endif throw std::runtime_error( - "Expected deserialized Vocab to have 4 states but found only " + + "Expected deserialized Vocab to have 4 states but found " + std::to_string(state_size) + " states."); } @@ -137,6 +298,11 @@ c10::intrusive_ptr _get_vocab_from_states(VocabStates states) { // check integers and tensors are empty if (integers.size() != 0 || tensors.size() != 0) { +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Expected `integers` and `tensors` states to " + "be empty." + << std::endl; +#endif throw std::runtime_error( "Expected `integers` and `tensors` states to be empty."); } @@ -147,33 +313,12 @@ c10::intrusive_ptr _get_vocab_from_states(VocabStates states) { return c10::make_intrusive(std::move(strings), std::move(unk_token)); } - +#ifdef _MSC_VER + std::cerr << "[RuntimeError] Found unexpected version for serialized Vocab: " + << version_str << std::endl; +#endif throw std::runtime_error( "Found unexpected version for serialized Vocab: " + version_str + "."); } -// Registers our custom class with torch. -static auto vocab = - torch::class_("torchtext", "Vocab") - .def(torch::init, std::string>()) - .def("__getitem__", &Vocab::__getitem__) - .def("__len__", &Vocab::__len__) - .def("insert_token", &Vocab::insert_token) - .def("append_token", &Vocab::append_token) - .def("lookup_token", &Vocab::lookup_token) - .def("lookup_tokens", &Vocab::lookup_tokens) - .def("lookup_indices", &Vocab::lookup_indices) - .def("get_stoi", &Vocab::get_stoi) - .def("get_itos", &Vocab::get_itos) - .def_pickle( - // __setstate__ - [](const c10::intrusive_ptr &self) -> VocabStates { - return _set_vocab_states(self); - }, - // __getstate__ - [](VocabStates states) -> c10::intrusive_ptr { - return _get_vocab_from_states(states); - }); - -} // namespace } // namespace torchtext diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h new file mode 100644 index 0000000000..0d3738aa54 --- /dev/null +++ b/torchtext/csrc/vocab.h @@ -0,0 +1,44 @@ +#include + +namespace torchtext { + +typedef std::vector StringList; +typedef ska_ordered::order_preserving_flat_hash_map + IndexDict; +typedef std::tuple, std::vector, + std::vector> + VocabStates; + +struct Vocab : torch::CustomClassHolder { +private: + int64_t unk_index_; + IndexDict stoi_; + +public: + const std::string version_str_ = "0.0.1"; + StringList itos_; + std::string unk_token_; + + explicit Vocab(const std::vector &tokens, + const std::string &unk_token); + explicit Vocab(const StringList &tokens, const IndexDict &stoi, + + const std::string &unk_token, const int64_t unk_index); + int64_t __len__() const; + int64_t __getitem__(const std::string &token) const; + void append_token(const std::string &token); + void insert_token(const std::string &token, const int64_t &index); + std::string lookup_token(const int64_t &index); + std::vector lookup_tokens(const std::vector &indices); + std::vector lookup_indices(const std::vector &tokens); + std::unordered_map get_stoi() const; + std::vector get_itos() const; +}; + +c10::intrusive_ptr _get_vocab_from_states(VocabStates states); +VocabStates _set_vocab_states(const c10::intrusive_ptr &self); +Vocab _load_vocab_from_file(const std::string &file_path, + const std::string &unk_token, + const int64_t min_freq, const int64_t num_cpus); + +} // namespace torchtext diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index c8048c1d40..5b22871220 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -1,7 +1,8 @@ import torch import torch.nn as nn -from typing import List, Tuple +from typing import List +from torchtext._torchtext import RegexTokenizer as RegexTokenizerPybind __all__ = [ 'BasicEnglishNormalize', @@ -9,7 +10,7 @@ ] -class BasicEnglishNormalize(nn.Module): +def basic_english_normalize(): r"""Basic normalization for a string sentence. Normalization includes @@ -30,34 +31,67 @@ class BasicEnglishNormalize(nn.Module): Examples: >>> import torch - >>> from torchtext.experimental.transforms import BasicEnglishNormalize + >>> from torchtext.experimental.transforms import basic_english_normalize >>> test_sample = 'Basic English Normalization for a Line of Text' - >>> basic_english_normalize = BasicEnglishNormalize() - >>> jit_basic_english_normalize = torch.jit.script(basic_english_normalize) - >>> tokens = jit_basic_english_normalize(test_sample) + >>> basic_eng_norm = basic_english_normalize() + >>> jit_basic_eng_norm = torch.jit.script(basic_eng_norm.to_ivalue()) + >>> tokens = jit_basic_eng_norm(test_sample) """ + patterns_list = [ + (r'\'', ' \' '), + (r'\"', ''), + (r'\.', ' . '), + (r'
', ' '), + (r',', ' , '), + (r'\(', ' ( '), + (r'\)', ' ) '), + (r'\!', ' ! '), + (r'\?', ' ? '), + (r'\;', ' '), + (r'\:', ' '), + (r'\s+', ' ')] + + patterns = [pair[0] for pair in patterns_list] + replacements = [pair[1] for pair in patterns_list] + return BasicEnglishNormalize(RegexTokenizerPybind(patterns, replacements, True)) + + +def regex_tokenizer(patterns_list): + r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. - regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] + Args: + patterns_list (List[Tuple[str, str]]): a list of tuples (ordered pairs) which contain the regex pattern string + as the first element and the replacement string as the second element. - def __init__(self): - super(BasicEnglishNormalize, self).__init__() - patterns_list = [ + Examples: + >>> import torch + >>> from torchtext.experimental.transforms import regex_tokenizer + >>> test_sample = 'Basic Regex Tokenization for a Line of Text' + >>> patterns_list = [ (r'\'', ' \' '), - (r'\"', ''), - (r'\.', ' . '), - (r'
', ' '), - (r',', ' , '), - (r'\(', ' ( '), - (r'\)', ' ) '), - (r'\!', ' ! '), - (r'\?', ' ? '), - (r'\;', ' '), - (r'\:', ' '), - (r'\s+', ' ')] - - regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) - replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) - self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) + (r'\"', '')] + >>> reg_tokenizer = regex_tokenizer(patterns_list) + >>> jit_reg_tokenizer = torch.jit.script(reg_tokenizer) + >>> tokens = jit_reg_tokenizer(test_sample) + """ + patterns = [pair[0] for pair in patterns_list] + replacements = [pair[1] for pair in patterns_list] + return RegexTokenizer(RegexTokenizerPybind(patterns, replacements, False)) + + +class BasicEnglishNormalize(nn.Module): + r"""Basic normalization for a string sentence. + + Args: + regex_tokenizer (torch.classes.torchtext.RegexTokenizer or torchtext._torchtext.RegexTokenizer): a cpp regex tokenizer object. + """ + def __init__(self, regex_tokenizer): + super(BasicEnglishNormalize, self).__init__() + self.regex_tokenizer = regex_tokenizer + + @property + def is_jitable(self): + return not isinstance(self.regex_tokenizer, RegexTokenizerPybind) def forward(self, line: str) -> List[str]: r""" @@ -66,40 +100,28 @@ def forward(self, line: str) -> List[str]: Returns: List[str]: a list of tokens after normalizing and splitting on whitespace. """ + return self.regex_tokenizer.forward(line) - line = line.lower() - for regex, replacement_string in self.regex_and_replacement_string_pairs: - line = regex.Sub(line, replacement_string) - return line.split() + def to_ivalue(self): + r"""Return a JITable BasicEnglishNormalize. + """ + regex_tokenizer = torch.classes.torchtext.RegexTokenizer(self.regex_tokenizer.patterns_, self.regex_tokenizer.replacements_, True) + return BasicEnglishNormalize(regex_tokenizer) class RegexTokenizer(nn.Module): r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. Args: - patterns_list (List[Tuple[str, str]]): a list of tuples (ordered pairs) which contain the regex pattern string - as the first element and the replacement string as the second element. - - Examples: - >>> import torch - >>> from torchtext.experimental.transforms import RegexTokenizer - >>> test_sample = 'Basic Regex Tokenization for a Line of Text' - >>> patterns_list = [ - (r'\'', ' \' '), - (r'\"', '')] - >>> regex_tokenizer = RegexTokenizer(patterns_list) - >>> jit_regex_tokenizer = torch.jit.script(regex_tokenizer) - >>> tokens = jit_regex_tokenizer(test_sample) + regex_tokenizer (torch.classes.torchtext.RegexTokenizer or torchtext._torchtext.RegexTokenizer): a cpp regex tokenizer object. """ - - regex_and_replacement_string_pairs: List[Tuple[torch.classes.torchtext.Regex, str]] - - def __init__(self, patterns_list: List[Tuple[str, str]]): + def __init__(self, regex_tokenzier): super(RegexTokenizer, self).__init__() + self.regex_tokenizer = regex_tokenzier - regex_objects = map(lambda pattern_tuple: torch.classes.torchtext.Regex(pattern_tuple[0]), patterns_list) - replacement_strings = map(lambda pattern_tuple: pattern_tuple[1], patterns_list) - self.regex_and_replacement_string_pairs = list(zip(regex_objects, replacement_strings)) + @property + def is_jitable(self): + return not isinstance(self.regex_tokenizer, RegexTokenizerPybind) def forward(self, line: str) -> List[str]: r""" @@ -108,10 +130,13 @@ def forward(self, line: str) -> List[str]: Returns: List[str]: a list of tokens after normalizing and splitting on whitespace. """ + return self.regex_tokenizer.forward(line) - for regex, replacement_string in self.regex_and_replacement_string_pairs: - line = regex.Sub(line, replacement_string) - return line.split() + def to_ivalue(self): + r"""Return a JITable RegexTokenizer. + """ + regex_tokenizer = torch.classes.torchtext.RegexTokenizer(self.regex_tokenizer.patterns_, self.regex_tokenizer.replacements_, False) + return RegexTokenizer(regex_tokenizer) class TextSequentialTransforms(nn.Sequential): diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index b68487c6c3..45f1adc312 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -1,5 +1,4 @@ import logging -import os import torch from torch import Tensor @@ -10,6 +9,10 @@ download_from_url, extract_archive ) +from torchtext._torchtext import ( + Vectors as VectorsPybind, + _load_token_and_vectors_from_file +) logger = logging.getLogger(__name__) @@ -34,25 +37,18 @@ def FastText(language="en", unk_tensor=None, root=".data", validate_file=True, n """ url = "https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.{}.vec".format(language) - file_name = os.path.basename(url) - - cached_vectors_file_path = os.path.join(root, file_name + ".pt") - if os.path.isfile(cached_vectors_file_path): - logger.info("Loading from cached file {}".format(str(cached_vectors_file_path))) - return torch.load(cached_vectors_file_path) checksum = None if validate_file: checksum = CHECKSUMS_FAST_TEXT.get(url, None) downloaded_file_path = download_from_url(url, root=root, hash_value=checksum) - cpp_vectors_obj, dup_tokens = torch.ops.torchtext._load_token_and_vectors_from_file(downloaded_file_path, ' ', num_cpus, unk_tensor) + cpp_vectors_obj, dup_tokens = _load_token_and_vectors_from_file(downloaded_file_path, ' ', num_cpus, unk_tensor) if dup_tokens: raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) vectors_obj = Vectors(cpp_vectors_obj) - torch.save(vectors_obj, cached_vectors_file_path) return vectors_obj @@ -122,11 +118,6 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru "are valid.".format(str(file_name))) url = urls[name] - cached_vectors_file_path = os.path.join(root, file_name + '.pt') - if os.path.isfile(cached_vectors_file_path): - logger.info("Loading from cached file {}".format(str(cached_vectors_file_path))) - return torch.load(cached_vectors_file_path) - checksum = None if validate_file: checksum = CHECKSUMS_GLOVE.get(url, None) @@ -135,14 +126,13 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru extracted_file_paths = extract_archive(downloaded_file_path) # need to get the full path to the correct file in the case when multiple files are extracted with different dims extracted_file_path_with_correct_dim = [path for path in extracted_file_paths if file_name in path][0] - cpp_vectors_obj, dup_tokens = torch.ops.torchtext._load_token_and_vectors_from_file(extracted_file_path_with_correct_dim, ' ', num_cpus, unk_tensor) + cpp_vectors_obj, dup_tokens = _load_token_and_vectors_from_file(extracted_file_path_with_correct_dim, ' ', num_cpus, unk_tensor) # Ensure there is only 1 expected duplicate token present for 840B dataset if dup_tokens and dup_tokens != dup_token_glove_840b: raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) vectors_obj = Vectors(cpp_vectors_obj) - torch.save(vectors_obj, cached_vectors_file_path) return vectors_obj @@ -170,39 +160,59 @@ def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None, n ValueError: if duplicate tokens are found in FastText file. """ - vectors_obj, dup_tokens = torch.ops.torchtext._load_token_and_vectors_from_file(file_like_object.name, delimiter, num_cpus, unk_tensor) + vectors_obj, dup_tokens = _load_token_and_vectors_from_file(file_like_object.name, delimiter, num_cpus, unk_tensor) if dup_tokens: raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) return Vectors(vectors_obj) def vectors(tokens, vectors, unk_tensor=None): + r"""Factory method for creating a vectors object which maps tokens to vectors. + Arguments: + tokens (List[str]): a list of tokens. + vectors (torch.Tensor): a 2d tensor representing the vector associated with each token. + unk_tensor (torch.Tensor): a 1d tensors representing the vector associated with an unknown token. + Raises: + ValueError: if `vectors` is empty and a default `unk_tensor` isn't provided. + RuntimeError: if `tokens` and `vectors` have different sizes or `tokens` has duplicates. + TypeError: if all tensors within`vectors` are not of data type `torch.float`. + """ if unk_tensor is None and (vectors is None or not len(vectors)): raise ValueError("The vectors list is empty and a default unk_tensor wasn't provided.") if not vectors.dtype == torch.float: raise TypeError("`vectors` should be of data type `torch.float`.") + indices = [i for i in range(len(tokens))] unk_tensor = unk_tensor if unk_tensor is not None else torch.zeros(vectors[0].size(), dtype=torch.float) - return Vectors(torch.classes.torchtext.Vectors(tokens, vectors, unk_tensor)) + return Vectors(VectorsPybind(tokens, indices, vectors, unk_tensor)) class Vectors(nn.Module): r"""Creates a vectors object which maps tokens to vectors. - Arguments: - tokens (List[str]): a list of tokens. - vectors (torch.Tensor): a 2d tensor representing the vector associated with each token. - unk_tensor (torch.Tensor): a 1d tensors representing the vector associated with an unknown token. - Raises: - ValueError: if `vectors` is empty and a default `unk_tensor` isn't provided. - RuntimeError: if `tokens` and `vectors` have different sizes or `tokens` has duplicates. - TypeError: if all tensors within`vectors` are not of data type `torch.float`. + Args: + vectors (torch.classes.torchtext.Vectors or torchtext._torchtext.Vectors): a cpp vectors object. """ def __init__(self, vectors): super(Vectors, self).__init__() self.vectors = vectors + @property + def is_jitable(self): + return not isinstance(self.vectors, VectorsPybind) + + @torch.jit.export + def __call__(self, tokens: List[str]) -> Tensor: + r"""Calls the `lookup_vectors` method + Args: + tokens: a list of tokens + + Returns: + vectors (Tensor): returns a 2-D tensor of shape=(len(tokens), vector_dim) or an empty tensor if `tokens` is empty + """ + return self.lookup_vectors(tokens) + @torch.jit.export def __getitem__(self, token: str) -> Tensor: r""" @@ -240,7 +250,7 @@ def __len__(self) -> int: @torch.jit.export def lookup_vectors(self, tokens: List[str]) -> Tensor: """Look up embedding vectors for a list of tokens. - Arguments: + Args: tokens: a list of tokens Returns: @@ -256,6 +266,13 @@ def lookup_vectors(self, tokens: List[str]) -> Tensor: return self.vectors.lookup_vectors(tokens) + def to_ivalue(self): + r"""Return a JITable Vectors. + """ + stoi = self.vectors.get_stoi() + cpp_vectors = torch.classes.torchtext.Vectors(list(stoi.keys()), list(stoi.values()), self.vectors.vectors_, self.vectors.unk_tensor_) + return(Vectors(cpp_vectors)) + CHECKSUMS_GLOVE = { "https://nlp.stanford.edu/data/glove.42B.300d.zip": diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 5e9dc32e50..b0fa2ce46e 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -1,62 +1,46 @@ -from collections import OrderedDict import logging from typing import Dict, List import warnings import torch import torch.nn as nn -from tqdm import tqdm - +from torchtext._torchtext import ( + Vocab as VocabPybind, + _load_vocab_from_file +) logger = logging.getLogger(__name__) -def _infer_shape(f): - num_lines = 0 - for line in f: - num_lines += 1 - f.seek(0) - return num_lines - - -def vocab_from_file_object(file_like_object, **kwargs): +def vocab_from_file_object(file_like_object, min_freq=1, unk_token='', num_cpus=1): r"""Create a `Vocab` object from a file like object. - The `file_like_object` should contain tokens seperated by new lines. Note that the vocab will be created in the order that the tokens first appear in the file (and not by the frequency of tokens). - Format for txt file: token1 token2 ... token_n - Args: file_like_object (FileObject): a file like object to read data from. - Remaining keyword arguments: Passed to the constructor of Vocab class. + min_freq: The minimum frequency needed to include a token in the vocabulary. + Values less than 1 will be set to 1. Default: 1. + unk_token: The default unknown token to use. Default: ''. + num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. Returns: Vocab: a `Vocab` object. - Examples: >>> from torchtext.experimental.vocab import vocab_from_file_object >>> f = open('vocab.txt', 'r') - >>> v = vocab_from_file_object(f, specials=('', '', ''), specials_first=False) + >>> v = vocab_from_file_object(f) """ - ordered_dict = OrderedDict() - num_lines = _infer_shape(file_like_object) - for line in tqdm(file_like_object, unit_scale=0, unit="lines", total=num_lines): - token = line.rstrip() - if token in ordered_dict: - ordered_dict[token] += 1 - else: - ordered_dict[token] = 1 - - return Vocab(ordered_dict, **kwargs) + vocab_obj = _load_vocab_from_file(file_like_object.name, unk_token, min_freq, num_cpus) + return Vocab(vocab_obj) -class Vocab(nn.Module): - r"""Creates a vocab object which maps tokens to indices. +def vocab(ordered_dict, min_freq=1, unk_token=''): + r"""Factory method for creating a vocab object which maps tokens to indices. Note that the ordering in which key value pairs were inserted in the `ordered_dict` will be respected when building the vocab. Therefore if sorting by token frequency is important to the user, the `ordered_dict` should be created in a way to reflect this. @@ -68,41 +52,64 @@ class Vocab(nn.Module): Values less than 1 will be set to 1. Default: 1. unk_token: The default unknown token to use. Default: ''. - Raises: ValueError: if a default `unk_token` isn't provided. Examples: - >>> from torchtext.experimental.vocab import Vocab + >>> from torchtext.experimental.vocab import vocab >>> from collections import Counter, OrderedDict >>> counter = Counter(["a", "a", "b", "b", "b"]) >>> sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) >>> ordered_dict = OrderedDict(sorted_by_freq_tuples) - >>> v1 = Vocab(ordered_dict) + >>> v1 = vocab(ordered_dict) >>> tokens = ['e', 'd', 'c', 'b', 'a'] - >>> v2 = Vocab(OrderedDict([(token, 1) for token in tokens])) + >>> v2 = vocab(OrderedDict([(token, 1) for token in tokens])) """ + if not unk_token: + raise ValueError("A default unk token wasn't provided.") + + tokens = [] + for token, freq in ordered_dict.items(): + if freq >= min_freq: + tokens.append(token) + + if unk_token not in tokens: + tokens.insert(0, unk_token) + warnings.warn("The `unk_token` '{}' wasn't found in the `ordered_dict`. Adding the `unk_token` " + "to the beginning of the Vocab.".format(unk_token), RuntimeWarning) + return Vocab(VocabPybind(tokens, unk_token)) + - def __init__(self, ordered_dict, min_freq=1, unk_token=''): +class Vocab(nn.Module): + r"""Creates a vocab object which maps tokens to indices. + + Arguments: + vocab (torch.classes.torchtext.Vocab or torchtext._torchtext.Vocab): a cpp vocab object. + """ + + def __init__(self, vocab): super(Vocab, self).__init__() + self.vocab = vocab - if not unk_token: - raise ValueError("A default unk token wasn't provided.") + @property + def is_jitable(self): + return not isinstance(self.vocab, VocabPybind) - tokens = [] - for token, freq in ordered_dict.items(): - if freq >= min_freq: - tokens.append(token) + @torch.jit.export + def __call__(self, tokens: List[str]) -> List[int]: + r"""Calls the `lookup_indices` method + Args: + tokens (List[str]): the tokens used to lookup their corresponding `indices`. - if unk_token not in tokens: - tokens.append(unk_token) - warnings.warn("The `unk_token` '{}' wasn't found in the `ordered_dict`. Adding the `unk_token` " - "to the end of the Vocab.".format(unk_token), RuntimeWarning) - self.vocab = torch.classes.torchtext.Vocab(tokens, unk_token) + Returns: + indices (List[int]): the 'indices` associated with `tokens`. + """ + return self.lookup_indices(tokens) @torch.jit.export def __len__(self) -> int: - r"""Returns: + r""" + Returns: length (int): the length of the vocab """ return len(self.vocab) @@ -192,3 +199,9 @@ def get_itos(self) -> List[str]: itos (dict): dictionary mapping indices to tokens. """ return self.vocab.get_itos() + + def to_ivalue(self): + r"""Return a JITable Vocab. + """ + cpp_vocab = torch.classes.torchtext.Vocab(self.vocab.itos_, self.vocab.unk_token_) + return Vocab(cpp_vocab) diff --git a/torchtext/utils.py b/torchtext/utils.py index d8348e840b..1e4974df21 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -100,6 +100,15 @@ def _process_response(r, root, filename): print("Can't create the download directory {}.".format(root)) raise + if filename is not None: + path = os.path.join(root, filename) + # skip requests.get if path exists and not overwrite. + if os.path.exists(path): + logging.info('File %s already exists.' % path) + if not overwrite: + _check_hash(path) + return path + if 'drive.google.com' not in url: response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'}, stream=True) return _process_response(response, root, filename) diff --git a/torchtext/vocab.py b/torchtext/vocab.py index 61848d05ca..3a03317b69 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -136,6 +136,10 @@ def __eq__(self, other): def __len__(self): return len(self.itos) + def lookup_indices(self, tokens): + indices = [self.__getitem__(token) for token in tokens] + return indices + def extend(self, v, sort=False): words = sorted(v.itos) if sort else v.itos for w in words: From 4a7bc10a9a9cfd444d97a32cc559c6cd5c6bd223 Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Tue, 1 Sep 2020 15:55:29 -0700 Subject: [PATCH 22/68] Import torchtext from 8aecbb9 Reviewed By: hudeven Differential Revision: D23451795 fbshipit-source-id: 73e6130c16716919c77862cef4ca4c8048428670 --- benchmark/benchmark_experimental_vocab.py | 26 +++- docs/source/experimental_transforms.rst | 24 +++- docs/source/experimental_vectors.rst | 5 + docs/source/experimental_vocab.rst | 14 +- examples/BERT/README.md | 124 +++++++++--------- examples/data_pipeline/README.md | 20 ++- examples/data_pipeline/pipelines.py | 61 +++++---- examples/data_pipeline/transforms.py | 40 ++++-- test/experimental/test_transforms.py | 38 ++++++ test/experimental/test_vectors.py | 18 +++ test/experimental/test_vocab.py | 48 ++++++- torchtext/csrc/regex_tokenizer.cpp | 2 +- torchtext/csrc/register_bindings.cpp | 9 +- torchtext/csrc/sentencepiece.cpp | 2 +- torchtext/csrc/vectors.cpp | 2 +- torchtext/csrc/vocab.cpp | 91 ++++++++++++- torchtext/csrc/vocab.h | 6 + .../datasets/text_classification.py | 2 +- torchtext/experimental/transforms.py | 86 +++++++++++- torchtext/experimental/vectors.py | 2 +- torchtext/experimental/vocab.py | 52 ++++++-- 21 files changed, 526 insertions(+), 146 deletions(-) create mode 100644 test/experimental/test_transforms.py diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 250abc46e2..78c25070ca 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -6,20 +6,30 @@ from torchtext.experimental.datasets import AG_NEWS from torchtext.experimental.vocab import ( vocab as VocabExperimental, - vocab_from_file_object + vocab_from_file_object, + vocab_from_raw_text_file_object ) from torchtext.vocab import ( Vocab, build_vocab_from_iterator ) +from torchtext.experimental.transforms import basic_english_normalize -def benchmark_experimental_vocab_construction(vocab_file_path, num_iters=100): +def benchmark_experimental_vocab_construction(vocab_file_path, is_raw_text=True, num_iters=1): f = open(vocab_file_path, 'r') t0 = time.monotonic() - for _ in range(num_iters): - vocab_from_file_object(f) - print("Construction time:", time.monotonic() - t0) + if is_raw_text: + print("Loading from raw text file with basic_english_normalize tokenizer") + for _ in range(num_iters): + tokenizer = basic_english_normalize() + jited_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + vocab_from_raw_text_file_object(f, jited_tokenizer) + print("Construction time:", time.monotonic() - t0) + else: + for _ in range(num_iters): + vocab_from_file_object(f) + print("Construction time:", time.monotonic() - t0) def benchmark_experimental_vocab_lookup(vocab_file_path=None): @@ -86,7 +96,7 @@ def token_iterator(file_path): t0 = time.monotonic() v_experimental = VocabExperimental(ordered_dict) print("Construction time:", time.monotonic() - t0) - jit_v_experimental = torch.jit.script(v_experimental) + jit_v_experimental = torch.jit.script(v_experimental.to_ivalue()) # existing Vocab eager lookup print("Vocab - Eager Mode") @@ -112,6 +122,8 @@ def token_iterator(file_path): parser = argparse.ArgumentParser(description='Data procesing pipelines') parser.add_argument('--run-construction-benchmark', type=bool, default=False, help='run benchmark for constructing a vocab (default=False)') + parser.add_argument('--is-raw-text', type=bool, default=True, + help='construct vocab from raw text file (default=True)') parser.add_argument('--vocab-filename-construction', type=str, default='vocab.txt', help='The name of vocab file used for construction') parser.add_argument('--vocab-filename-lookup', type=str, default=None, @@ -119,6 +131,6 @@ def token_iterator(file_path): args = parser.parse_args() if args.run_construction_benchmark: - benchmark_experimental_vocab_construction(args.vocab_filename_construction) + benchmark_experimental_vocab_construction(args.vocab_filename_construction, is_raw_text=args.is_raw_text) else: benchmark_experimental_vocab_lookup(args.vocab_filename_lookup) diff --git a/docs/source/experimental_transforms.rst b/docs/source/experimental_transforms.rst index ff00b374ef..b8fce62dd0 100644 --- a/docs/source/experimental_transforms.rst +++ b/docs/source/experimental_transforms.rst @@ -19,4 +19,26 @@ torchtext.experimental.transforms .. autoclass:: RegexTokenizer :members: - :special-members: __init__ \ No newline at end of file + :special-members: __init__ + + +:hidden:`TextSequentialTransforms` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: TextSequentialTransforms + :members: + :special-members: __init__ + +:hidden:`VocabTransform` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: VocabTransform + :members: + :special-members: __init__ + +:hidden:`VectorTransform` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: VectorTransform + :members: + :special-members: __init__ diff --git a/docs/source/experimental_vectors.rst b/docs/source/experimental_vectors.rst index b901abac80..c07cfd7822 100644 --- a/docs/source/experimental_vectors.rst +++ b/docs/source/experimental_vectors.rst @@ -14,6 +14,11 @@ torchtext.experimental.vectors :members: :special-members: +:hidden:`vectors` +~~~~~~~~~~~~~~~~~ + +.. autofunction:: vectors + :hidden:`vectors_from_file_object` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/experimental_vocab.rst b/docs/source/experimental_vocab.rst index 9e485136f9..c2025bf631 100644 --- a/docs/source/experimental_vocab.rst +++ b/docs/source/experimental_vocab.rst @@ -14,7 +14,17 @@ torchtext.experimental.vocab :members: :special-members: -:hidden:`vocab_from_file_object` +:hidden:`vocab` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. autofunction:: vocab_from_file_object +.. autofunction:: vocab + +:hidden:`vocab_from_file` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: vocab_from_file + +:hidden:`vocab_from_raw_text_file` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: vocab_from_raw_text_file diff --git a/examples/BERT/README.md b/examples/BERT/README.md index edde1c42b0..3089efed65 100644 --- a/examples/BERT/README.md +++ b/examples/BERT/README.md @@ -27,94 +27,94 @@ With SQuAD dataset, the pre-trained BERT is used for question-answer task: The pre-trained BERT models and vocab are available: -* [bert_vocab.pt](https://pytorch.s3.amazonaws.com/models/text/torchtext_bert_example/bert_vocab.pt) +* [torchtext_bert_vocab.pt](https://pytorch.s3.amazonaws.com/models/text/torchtext_bert_example/torchtext_bert_vocab.pt) * [mlm_bert.pt](https://pytorch.s3.amazonaws.com/models/text/torchtext_bert_example/mlm_bert.pt) * [ns_bert.pt](https://pytorch.s3.amazonaws.com/models/text/torchtext_bert_example/ns_bert.pt) An example train/valid/test printout with the pretrained BERT model in question-answer task: - | epoch 1 | 200/ 1055 batches | lr 5.00000 | ms/batch 746.33 | loss 3.70 | ppl 40.45 - | epoch 1 | 400/ 1055 batches | lr 5.00000 | ms/batch 746.78 | loss 3.06 | ppl 21.25 - | epoch 1 | 600/ 1055 batches | lr 5.00000 | ms/batch 746.83 | loss 2.84 | ppl 17.15 - | epoch 1 | 800/ 1055 batches | lr 5.00000 | ms/batch 746.55 | loss 2.69 | ppl 14.73 - | epoch 1 | 1000/ 1055 batches | lr 5.00000 | ms/batch 745.48 | loss 2.55 | ppl 12.85 + | epoch 1 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.82 | loss 3.75 | ppl 42.32 + | epoch 1 | 400/ 1055 batches | lr 5.00000 | ms/batch 746.04 | loss 3.46 | ppl 31.85 + | epoch 1 | 600/ 1055 batches | lr 5.00000 | ms/batch 748.82 | loss 3.09 | ppl 21.90 + | epoch 1 | 800/ 1055 batches | lr 5.00000 | ms/batch 743.96 | loss 2.77 | ppl 15.89 + | epoch 1 | 1000/ 1055 batches | lr 5.00000 | ms/batch 743.21 | loss 2.30 | ppl 9.99 ----------------------------------------------------------------------------------------- - | end of epoch 1 | time: 821.25s | valid loss 2.33 | exact 40.052% | f1 52.595% + | end of epoch 1 | time: 821.76s | valid loss 1.92 | exact 49.945% | f1 62.056% ----------------------------------------------------------------------------------------- - | epoch 2 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.17 | loss 2.33 | ppl 10.25 - | epoch 2 | 400/ 1055 batches | lr 5.00000 | ms/batch 745.52 | loss 2.28 | ppl 9.75 - | epoch 2 | 600/ 1055 batches | lr 5.00000 | ms/batch 745.50 | loss 2.24 | ppl 9.37 - | epoch 2 | 800/ 1055 batches | lr 5.00000 | ms/batch 745.10 | loss 2.22 | ppl 9.18 - | epoch 2 | 1000/ 1055 batches | lr 5.00000 | ms/batch 744.61 | loss 2.16 | ppl 8.66 + | epoch 2 | 200/ 1055 batches | lr 5.00000 | ms/batch 749.20 | loss 1.81 | ppl 6.10 + | epoch 2 | 400/ 1055 batches | lr 5.00000 | ms/batch 743.78 | loss 1.72 | ppl 5.61 + | epoch 2 | 600/ 1055 batches | lr 5.00000 | ms/batch 744.54 | loss 1.66 | ppl 5.28 + | epoch 2 | 800/ 1055 batches | lr 5.00000 | ms/batch 744.99 | loss 1.64 | ppl 5.17 + | epoch 2 | 1000/ 1055 batches | lr 5.00000 | ms/batch 744.06 | loss 1.60 | ppl 4.96 ----------------------------------------------------------------------------------------- - | end of epoch 2 | time: 820.75s | valid loss 2.12 | exact 44.632% | f1 57.965% + | end of epoch 2 | time: 821.15s | valid loss 1.58 | exact 59.221% | f1 71.034% ----------------------------------------------------------------------------------------- - | epoch 3 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.88 | loss 2.00 | ppl 7.41 - | epoch 3 | 400/ 1055 batches | lr 5.00000 | ms/batch 746.46 | loss 1.99 | ppl 7.29 - | epoch 3 | 600/ 1055 batches | lr 5.00000 | ms/batch 745.35 | loss 1.99 | ppl 7.30 - | epoch 3 | 800/ 1055 batches | lr 5.00000 | ms/batch 746.03 | loss 1.98 | ppl 7.27 - | epoch 3 | 1000/ 1055 batches | lr 5.00000 | ms/batch 746.01 | loss 1.98 | ppl 7.26 + | epoch 3 | 200/ 1055 batches | lr 5.00000 | ms/batch 747.07 | loss 1.41 | ppl 4.10 + | epoch 3 | 400/ 1055 batches | lr 5.00000 | ms/batch 743.91 | loss 1.39 | ppl 4.03 + | epoch 3 | 600/ 1055 batches | lr 5.00000 | ms/batch 743.71 | loss 1.39 | ppl 4.03 + | epoch 3 | 800/ 1055 batches | lr 5.00000 | ms/batch 744.33 | loss 1.39 | ppl 4.03 + | epoch 3 | 1000/ 1055 batches | lr 5.00000 | ms/batch 744.86 | loss 1.40 | ppl 4.05 ----------------------------------------------------------------------------------------- - | end of epoch 3 | time: 821.98s | valid loss 1.96 | exact 48.001% | f1 61.036% + | end of epoch 3 | time: 820.46s | valid loss 1.46 | exact 62.612% | f1 73.513% ----------------------------------------------------------------------------------------- - | epoch 4 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.72 | loss 1.82 | ppl 6.19 - | epoch 4 | 400/ 1055 batches | lr 5.00000 | ms/batch 745.86 | loss 1.84 | ppl 6.28 - | epoch 4 | 600/ 1055 batches | lr 5.00000 | ms/batch 745.63 | loss 1.85 | ppl 6.34 - | epoch 4 | 800/ 1055 batches | lr 5.00000 | ms/batch 745.59 | loss 1.82 | ppl 6.20 - | epoch 4 | 1000/ 1055 batches | lr 5.00000 | ms/batch 745.55 | loss 1.83 | ppl 6.21 + | epoch 4 | 200/ 1055 batches | lr 5.00000 | ms/batch 749.89 | loss 1.20 | ppl 3.33 + | epoch 4 | 400/ 1055 batches | lr 5.00000 | ms/batch 748.50 | loss 1.20 | ppl 3.32 + | epoch 4 | 600/ 1055 batches | lr 5.00000 | ms/batch 745.78 | loss 1.24 | ppl 3.47 + | epoch 4 | 800/ 1055 batches | lr 5.00000 | ms/batch 744.94 | loss 1.24 | ppl 3.45 + | epoch 4 | 1000/ 1055 batches | lr 5.00000 | ms/batch 744.22 | loss 1.25 | ppl 3.48 ----------------------------------------------------------------------------------------- - | end of epoch 4 | time: 821.10s | valid loss 1.95 | exact 49.149% | f1 62.040% + | end of epoch 4 | time: 822.04s | valid loss 1.47 | exact 62.758% | f1 73.744% ----------------------------------------------------------------------------------------- - | epoch 5 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.40 | loss 1.66 | ppl 5.24 - | epoch 5 | 400/ 1055 batches | lr 5.00000 | ms/batch 756.09 | loss 1.69 | ppl 5.44 - | epoch 5 | 600/ 1055 batches | lr 5.00000 | ms/batch 769.19 | loss 1.70 | ppl 5.46 - | epoch 5 | 800/ 1055 batches | lr 5.00000 | ms/batch 764.96 | loss 1.72 | ppl 5.58 - | epoch 5 | 1000/ 1055 batches | lr 5.00000 | ms/batch 773.25 | loss 1.70 | ppl 5.49 + | epoch 5 | 200/ 1055 batches | lr 5.00000 | ms/batch 747.76 | loss 1.05 | ppl 2.87 + | epoch 5 | 400/ 1055 batches | lr 5.00000 | ms/batch 743.78 | loss 1.08 | ppl 2.94 + | epoch 5 | 600/ 1055 batches | lr 5.00000 | ms/batch 743.69 | loss 1.09 | ppl 2.97 + | epoch 5 | 800/ 1055 batches | lr 5.00000 | ms/batch 743.58 | loss 1.10 | ppl 3.01 + | epoch 5 | 1000/ 1055 batches | lr 5.00000 | ms/batch 743.05 | loss 1.13 | ppl 3.08 ----------------------------------------------------------------------------------------- - | end of epoch 5 | time: 844.20s | valid loss 1.99 | exact 49.509% | f1 61.994% + | end of epoch 5 | time: 819.86s | valid loss 1.49 | exact 63.372% | f1 74.179% ----------------------------------------------------------------------------------------- - | epoch 6 | 200/ 1055 batches | lr 0.50000 | ms/batch 765.25 | loss 1.50 | ppl 4.49 - | epoch 6 | 400/ 1055 batches | lr 0.50000 | ms/batch 749.64 | loss 1.45 | ppl 4.25 - | epoch 6 | 600/ 1055 batches | lr 0.50000 | ms/batch 768.16 | loss 1.40 | ppl 4.06 - | epoch 6 | 800/ 1055 batches | lr 0.50000 | ms/batch 745.69 | loss 1.43 | ppl 4.18 - | epoch 6 | 1000/ 1055 batches | lr 0.50000 | ms/batch 744.90 | loss 1.40 | ppl 4.07 + | epoch 6 | 200/ 1055 batches | lr 5.00000 | ms/batch 748.29 | loss 0.93 | ppl 2.54 + | epoch 6 | 400/ 1055 batches | lr 5.00000 | ms/batch 744.01 | loss 0.96 | ppl 2.62 + | epoch 6 | 600/ 1055 batches | lr 5.00000 | ms/batch 744.13 | loss 0.97 | ppl 2.63 + | epoch 6 | 800/ 1055 batches | lr 5.00000 | ms/batch 744.19 | loss 0.99 | ppl 2.68 + | epoch 6 | 1000/ 1055 batches | lr 5.00000 | ms/batch 744.10 | loss 1.00 | ppl 2.73 ----------------------------------------------------------------------------------------- - | end of epoch 6 | time: 829.55s | valid loss 1.97 | exact 51.182% | f1 63.437% + | end of epoch 6 | time: 820.67s | valid loss 1.52 | exact 62.902% | f1 73.918% ----------------------------------------------------------------------------------------- - | epoch 7 | 200/ 1055 batches | lr 0.50000 | ms/batch 747.73 | loss 1.36 | ppl 3.89 - | epoch 7 | 400/ 1055 batches | lr 0.50000 | ms/batch 744.50 | loss 1.37 | ppl 3.92 - | epoch 7 | 600/ 1055 batches | lr 0.50000 | ms/batch 744.20 | loss 1.35 | ppl 3.86 - | epoch 7 | 800/ 1055 batches | lr 0.50000 | ms/batch 743.85 | loss 1.36 | ppl 3.89 - | epoch 7 | 1000/ 1055 batches | lr 0.50000 | ms/batch 744.01 | loss 1.34 | ppl 3.83 + | epoch 7 | 200/ 1055 batches | lr 0.50000 | ms/batch 748.94 | loss 0.74 | ppl 2.09 + | epoch 7 | 400/ 1055 batches | lr 0.50000 | ms/batch 743.26 | loss 0.70 | ppl 2.01 + | epoch 7 | 600/ 1055 batches | lr 0.50000 | ms/batch 745.73 | loss 0.68 | ppl 1.97 + | epoch 7 | 800/ 1055 batches | lr 0.50000 | ms/batch 745.74 | loss 0.67 | ppl 1.96 + | epoch 7 | 1000/ 1055 batches | lr 0.50000 | ms/batch 744.42 | loss 0.65 | ppl 1.92 ----------------------------------------------------------------------------------------- - | end of epoch 7 | time: 820.02s | valid loss 2.01 | exact 51.507% | f1 63.885% + | end of epoch 7 | time: 820.97s | valid loss 1.60 | exact 65.965% | f1 76.315% ----------------------------------------------------------------------------------------- - | epoch 8 | 200/ 1055 batches | lr 0.50000 | ms/batch 747.40 | loss 1.31 | ppl 3.72 - | epoch 8 | 400/ 1055 batches | lr 0.50000 | ms/batch 744.33 | loss 1.30 | ppl 3.68 - | epoch 8 | 600/ 1055 batches | lr 0.50000 | ms/batch 745.76 | loss 1.31 | ppl 3.69 - | epoch 8 | 800/ 1055 batches | lr 0.50000 | ms/batch 745.04 | loss 1.31 | ppl 3.69 - | epoch 8 | 1000/ 1055 batches | lr 0.50000 | ms/batch 745.13 | loss 1.31 | ppl 3.72 + | epoch 8 | 200/ 1055 batches | lr 0.50000 | ms/batch 748.37 | loss 0.61 | ppl 1.85 + | epoch 8 | 400/ 1055 batches | lr 0.50000 | ms/batch 747.32 | loss 0.60 | ppl 1.82 + | epoch 8 | 600/ 1055 batches | lr 0.50000 | ms/batch 746.12 | loss 0.60 | ppl 1.82 + | epoch 8 | 800/ 1055 batches | lr 0.50000 | ms/batch 745.98 | loss 0.60 | ppl 1.83 + | epoch 8 | 1000/ 1055 batches | lr 0.50000 | ms/batch 744.58 | loss 0.60 | ppl 1.82 ----------------------------------------------------------------------------------------- - | end of epoch 8 | time: 820.40s | valid loss 2.02 | exact 51.260% | f1 63.762% + | end of epoch 8 | time: 821.95s | valid loss 1.64 | exact 65.214% | f1 76.046% ----------------------------------------------------------------------------------------- - | epoch 9 | 200/ 1055 batches | lr 0.05000 | ms/batch 748.36 | loss 1.26 | ppl 3.54 - | epoch 9 | 400/ 1055 batches | lr 0.05000 | ms/batch 744.55 | loss 1.26 | ppl 3.52 - | epoch 9 | 600/ 1055 batches | lr 0.05000 | ms/batch 745.46 | loss 1.23 | ppl 3.44 - | epoch 9 | 800/ 1055 batches | lr 0.05000 | ms/batch 745.23 | loss 1.26 | ppl 3.52 - | epoch 9 | 1000/ 1055 batches | lr 0.05000 | ms/batch 744.69 | loss 1.24 | ppl 3.47 + | epoch 9 | 200/ 1055 batches | lr 0.05000 | ms/batch 748.68 | loss 0.55 | ppl 1.74 + | epoch 9 | 400/ 1055 batches | lr 0.05000 | ms/batch 743.93 | loss 0.54 | ppl 1.71 + | epoch 9 | 600/ 1055 batches | lr 0.05000 | ms/batch 744.58 | loss 0.55 | ppl 1.72 + | epoch 9 | 800/ 1055 batches | lr 0.05000 | ms/batch 744.37 | loss 0.56 | ppl 1.75 + | epoch 9 | 1000/ 1055 batches | lr 0.05000 | ms/batch 744.40 | loss 0.54 | ppl 1.72 ----------------------------------------------------------------------------------------- - | end of epoch 9 | time: 820.41s | valid loss 2.02 | exact 51.578% | f1 63.704% + | end of epoch 9 | time: 820.87s | valid loss 1.66 | exact 65.272% | f1 75.929% ----------------------------------------------------------------------------------------- - | epoch 10 | 200/ 1055 batches | lr 0.00500 | ms/batch 749.25 | loss 1.25 | ppl 3.50 - | epoch 10 | 400/ 1055 batches | lr 0.00500 | ms/batch 745.81 | loss 1.24 | ppl 3.47 - | epoch 10 | 600/ 1055 batches | lr 0.00500 | ms/batch 744.89 | loss 1.26 | ppl 3.51 - | epoch 10 | 800/ 1055 batches | lr 0.00500 | ms/batch 746.02 | loss 1.23 | ppl 3.42 - | epoch 10 | 1000/ 1055 batches | lr 0.00500 | ms/batch 746.61 | loss 1.25 | ppl 3.50 + | epoch 10 | 200/ 1055 batches | lr 0.00500 | ms/batch 748.50 | loss 0.54 | ppl 1.72 + | epoch 10 | 400/ 1055 batches | lr 0.00500 | ms/batch 744.92 | loss 0.55 | ppl 1.72 + | epoch 10 | 600/ 1055 batches | lr 0.00500 | ms/batch 745.06 | loss 0.55 | ppl 1.73 + | epoch 10 | 800/ 1055 batches | lr 0.00500 | ms/batch 745.30 | loss 0.54 | ppl 1.71 + | epoch 10 | 1000/ 1055 batches | lr 0.00500 | ms/batch 746.06 | loss 0.54 | ppl 1.72 ----------------------------------------------------------------------------------------- - | end of epoch 10 | time: 821.85s | valid loss 2.05 | exact 51.648% | f1 63.811% + | end of epoch 10 | time: 821.62s | valid loss 1.67 | exact 65.382% | f1 76.090% ----------------------------------------------------------------------------------------- ========================================================================================= - | End of training | test loss 2.05 | exact 51.337% | f1 63.645% + | End of training | test loss 1.61 | exact 66.124% | f1 76.373% ========================================================================================= ## Structure of the example diff --git a/examples/data_pipeline/README.md b/examples/data_pipeline/README.md index 440586c075..6a6f45e586 100644 --- a/examples/data_pipeline/README.md +++ b/examples/data_pipeline/README.md @@ -15,7 +15,9 @@ The command to run the pipeline: python pipelines.py --pipeline sentencepiece -The lookup time: 25.09393248707056 (eager mode) vs. 18.71099873096682 (jit mode) +The lookup time: 30.770548372063786 (eager mode with pybind) +The lookup time: 34.36592311505228 (eager mode with torchbind) +The lookup time: 23.43273439211771 (jit mode) ## Vocab from a text file @@ -30,7 +32,9 @@ The command to run the pipeline: python pipelines.py --pipeline text_vocab -The lookup time: 45.7489246588666 (eager mode) vs. 30.990019195945933 (jit mode) +The lookup time: 10.21763815311715 (eager mode with pybind) +The lookup time: 17.28485624492168 (eager mode with torchbind) +The lookup time: 10.25370063772425 (jit mode) ## PyText @@ -45,7 +49,9 @@ With the dependency of `pytext` library, the command to run the pipeline: python pipelines.py --pipeline pytext -The lookup time: 43.51164810406044 (eager mode) vs. 26.57643914804794 (jit mode) +The lookup time: 18.07144843228161 (eager mode with pybind) +The lookup time: 22.16066740499809 (eager mode with torchbind) +The lookup time: 13.41519635310396 (jit mode) ## Torchtext @@ -60,7 +66,7 @@ The command to run the pipeline: python pipelines.py --pipeline torchtext -The lookup time: 6.821685338858515 (eager mode) +The lookup time: 8.690132656134665 (eager mode) ## Torchtext with a batch of data @@ -83,7 +89,7 @@ The command to run the pipeline: python pipelines.py --pipeline batch_torchtext -The lookup time: 7.915330206044018 (eager mode) +The lookup time: 10.05315054487437 (eager mode) ## FastText pretrained word vectors @@ -97,4 +103,6 @@ The command to run the pipeline: python pipelines.py --pipeline fasttext -The lookup time: 45.74515324481763 (eager mode) vs. 32.64012925699353 (jit mode) +The lookup time: 16.45024944096803 (eager mode with pybind) +The lookup time: 23.96459424262866 (eager mode with torchbind) +The lookup time: 19.34995342604816 (jit mode) diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index 9af5e7efe0..b3954ff295 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -2,14 +2,14 @@ from transforms import ( PretrainedSPTokenizer, PretrainedSPVocab, - VocabTransform, PyTextVocabTransform, - VectorTransform, ToLongTensor, ) from torchtext.experimental.transforms import ( - BasicEnglishNormalize, + basic_english_normalize, TextSequentialTransforms, + VocabTransform, + VectorTransform, ) from torchtext.experimental.vocab import vocab_from_file_object from torchtext.experimental.vectors import FastText @@ -17,18 +17,19 @@ from torchtext.experimental.datasets.raw import text_classification as raw import time from dataset import BatchTextClassificationData +from torchtext.data.functional import load_sp_model def build_sp_pipeline(spm_file): - tokenizer = PretrainedSPTokenizer(spm_file) - vocab = PretrainedSPVocab(spm_file) + tokenizer = PretrainedSPTokenizer(load_sp_model(spm_file)) + vocab = PretrainedSPVocab(load_sp_model(spm_file)) # Insert token in vocab to match a pretrained vocab vocab.insert_token('', 1) pipeline = TextSequentialTransforms(tokenizer, vocab, ToLongTensor()) - jit_pipeline = torch.jit.script(pipeline) + jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit sentencepiece pipeline success!') - return pipeline, jit_pipeline + return pipeline, pipeline.to_ivalue(), jit_pipeline def build_torchtext_vocab(vocab_file): @@ -43,7 +44,7 @@ def token_iterator(vocab_file): yield token vocab = build_vocab_from_iterator(token_iterator(vocab_file)) pipeline = sequential_transforms(tokenizer, vocab_func(vocab), totensor(dtype=torch.long)) - return pipeline, None + return pipeline, None, None def build_batch_torchtext_vocab(vocab_file): @@ -60,24 +61,24 @@ def token_iterator(vocab_file): vocab = build_vocab_from_iterator(token_iterator(vocab_file)) text_pipeline = sequential_transforms(tokenizer, vocab_func(vocab), totensor(dtype=torch.long)) label_pipeline = totensor(dtype=torch.long) - return TextClassificationPipeline(label_pipeline, text_pipeline), None + return TextClassificationPipeline(label_pipeline, text_pipeline), None, None def build_text_vocab_pipeline(hf_vocab_file): - tokenizer = BasicEnglishNormalize() + tokenizer = basic_english_normalize() f = open(hf_vocab_file, 'r') vocab = vocab_from_file_object(f) # Insert token in vocab to match a pretrained vocab pipeline = TextSequentialTransforms(tokenizer, VocabTransform(vocab), ToLongTensor()) - jit_pipeline = torch.jit.script(pipeline) - print('jit Hugging Face pipeline success!') - return pipeline, jit_pipeline + jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + print('jit text vocab pipeline success!') + return pipeline, pipeline.to_ivalue(), jit_pipeline def build_pytext_vocab_pipeline(vocab_file): from pytext.torchscript.vocab import ScriptVocabulary - tokenizer = BasicEnglishNormalize() + tokenizer = basic_english_normalize() f = open(vocab_file, 'r') vocab_list = [line.rstrip() for line in f] @@ -85,20 +86,20 @@ def build_pytext_vocab_pipeline(vocab_file): pipeline = TextSequentialTransforms(tokenizer, PyTextVocabTransform(ScriptVocabulary(vocab_list)), ToLongTensor()) - jit_pipeline = torch.jit.script(pipeline) + jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit PyText pipeline success!') - return pipeline, jit_pipeline + return pipeline, pipeline.to_ivalue(), jit_pipeline def build_fasttext_vector_pipeline(): - tokenizer = BasicEnglishNormalize() + tokenizer = basic_english_normalize() vector = FastText() # Insert token in vocab to match a pretrained vocab pipeline = TextSequentialTransforms(tokenizer, VectorTransform(vector)) - jit_pipeline = torch.jit.script(pipeline) + jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit fasttext pipeline success!') - return pipeline, jit_pipeline + return pipeline, pipeline.to_ivalue(), jit_pipeline def run_benchmark_lookup(text_classification_dataset, pipeline): @@ -137,29 +138,37 @@ def generate_dataset(args): args = parser.parse_args() if args.pipeline == 'sentencepiece': - pipeline, jit_pipeline = build_sp_pipeline(args.spm_filename) + pipeline, torchbind_pipeline, jit_pipeline = build_sp_pipeline(args.spm_filename) elif args.pipeline == 'text_vocab': - pipeline, jit_pipeline = build_text_vocab_pipeline(args.vocab_filename) + pipeline, torchbind_pipeline, jit_pipeline = build_text_vocab_pipeline(args.vocab_filename) elif args.pipeline == 'pytext': - pipeline, jit_pipeline = build_pytext_vocab_pipeline(args.vocab_filename) + pipeline, torchbind_pipeline, jit_pipeline = build_pytext_vocab_pipeline(args.vocab_filename) elif args.pipeline == 'fasttext': - pipeline, jit_pipeline = build_fasttext_vector_pipeline() + pipeline, torchbind_pipeline, jit_pipeline = build_fasttext_vector_pipeline() elif args.pipeline == 'torchtext': - pipeline, jit_pipeline = build_torchtext_vocab(args.vocab_filename) + pipeline, torchbind_pipeline, jit_pipeline = build_torchtext_vocab(args.vocab_filename) elif args.pipeline == 'batch_torchtext': - pipeline, jit_pipeline = build_batch_torchtext_vocab(args.vocab_filename) + pipeline, torchbind_pipeline, jit_pipeline = build_batch_torchtext_vocab(args.vocab_filename) else: print("pipeline is not supported. Current pipelines include sentencepiece, text_vocab, " + "fasttext, pytext, fasttext, torchtext, batch_torchtext") if pipeline is not None: - print("Test eager mode for pipeline", args.pipeline) + print("Test eager mode for pipeline with pybind", args.pipeline) train, test = generate_dataset(args) if args.pipeline == 'batch_torchtext': run_batch_benchmark_lookup(train, pipeline) else: run_benchmark_lookup(train, pipeline) + if torchbind_pipeline is not None: + print("Test eager mode for pipeline with torchbind", args.pipeline) + train, test = generate_dataset(args) + if args.pipeline == 'batch_torchtext': + run_batch_benchmark_lookup(train, torchbind_pipeline) + else: + run_benchmark_lookup(train, torchbind_pipeline) + if jit_pipeline is not None: print("Test jit mode for pipeline", args.pipeline) train, test = generate_dataset(args) diff --git a/examples/data_pipeline/transforms.py b/examples/data_pipeline/transforms.py index 8a88c22479..fa02c027af 100644 --- a/examples/data_pipeline/transforms.py +++ b/examples/data_pipeline/transforms.py @@ -1,6 +1,5 @@ import torch.nn as nn -from torchtext.data.functional import load_sp_model -from torchtext.experimental.vocab import Vocab +from torchtext.experimental.vocab import vocab from typing import List from collections import OrderedDict import torch @@ -24,13 +23,12 @@ class PretrainedSPTokenizer(nn.Module): r"""Tokenizer based on a pretained sentencepiece model """ - def __init__(self, spm_file): + def __init__(self, sp_model): super(PretrainedSPTokenizer, self).__init__() - self.sp_model = load_sp_model(spm_file) + self.sp_model = sp_model def forward(self, line: str) -> List[str]: r""" - """ return self.sp_model.EncodeAsPieces(line) @@ -40,13 +38,13 @@ class PretrainedSPVocab(nn.Module): r"""Vocab based on a pretained sentencepiece model """ - def __init__(self, spm_file): + def __init__(self, sp_model): super(PretrainedSPVocab, self).__init__() - self.sp_model = load_sp_model(spm_file) + self.sp_model = sp_model unk_id = self.sp_model.unk_id() unk_token = self.sp_model.IdToPiece(unk_id) vocab_list = [self.sp_model.IdToPiece(i) for i in range(self.sp_model.GetPieceSize())] - self.vocab = Vocab(OrderedDict([(token, 1) for token in vocab_list]), unk_token=unk_token) + self.vocab = vocab(OrderedDict([(token, 1) for token in vocab_list]), unk_token=unk_token) def forward(self, tokens: List[str]) -> List[int]: return self.vocab.lookup_indices(tokens) @@ -54,6 +52,14 @@ def forward(self, tokens: List[str]) -> List[int]: def insert_token(self, token: str, index: int) -> None: self.vocab.insert_token(token, index) + def to_ivalue(self): + if hasattr(self.vocab, 'to_ivalue'): + sp_model = self.sp_model + new_module = PretrainedSPVocab(sp_model) + new_module.vocab = self.vocab.to_ivalue() + return new_module + return self + class VocabTransform(nn.Module): r"""Vocab transform @@ -66,6 +72,12 @@ def __init__(self, vocab): def forward(self, tokens: List[str]) -> List[int]: return self.vocab.lookup_indices(tokens) + def to_ivalue(self): + if hasattr(self.vocab, 'to_ivalue'): + vocab = self.vocab.to_ivalue() + return VocabTransform(vocab) + return self + class PyTextVocabTransform(nn.Module): r"""Vocab transform @@ -78,6 +90,12 @@ def __init__(self, vocab): def forward(self, tokens: List[str]) -> List[int]: return self.vocab.lookup_indices_1d(tokens) + def to_ivalue(self): + if hasattr(self.vocab, 'to_ivalue'): + vocab = self.vocab.to_ivalue() + return PyTextVocabTransform(vocab) + return self + class VectorTransform(nn.Module): r"""Vector transform @@ -90,6 +108,12 @@ def __init__(self, vector): def forward(self, tokens: List[str]) -> Tensor: return self.vector.lookup_vectors(tokens) + def to_ivalue(self): + if hasattr(self.vector, 'to_ivalue'): + vector = self.vector.to_ivalue() + return VectorTransform(vector) + return self + class ToLongTensor(nn.Module): r"""Convert a list of integers to long tensor diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py new file mode 100644 index 0000000000..608efd2ad9 --- /dev/null +++ b/test/experimental/test_transforms.py @@ -0,0 +1,38 @@ +import torch +from test.common.torchtext_test_case import TorchtextTestCase +from test.common.assets import get_asset_path +from torchtext.experimental.transforms import ( + VectorTransform, + VocabTransform, +) +from torchtext.experimental.vocab import vocab_from_file +from torchtext.experimental.vectors import FastText +import shutil +import tempfile +import os + + +class TestTransforms(TorchtextTestCase): + def test_vocab_transform(self): + asset_name = 'vocab_test2.txt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'r') as f: + vocab_transform = VocabTransform(vocab_from_file(f)) + self.assertEqual(vocab_transform(['of', 'that', 'new']), [7, 18, 24]) + jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) + self.assertEqual(jit_vocab_transform(['of', 'that', 'new']), [7, 18, 24]) + + def test_vector_transform(self): + asset_name = 'wiki.en.vec' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + vector_transform = VectorTransform(FastText(root=dir_name, validate_file=False)) + jit_vector_transform = torch.jit.script(vector_transform.to_ivalue()) + # The first 3 entries in each vector. + expected_fasttext_simple_en = torch.tensor([[-0.065334, -0.093031, -0.017571], + [-0.32423, -0.098845, -0.0073467]]) + self.assertEqual(vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) + self.assertEqual(jit_vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 61f428329c..45a86fef23 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -71,6 +71,24 @@ def test_vectors_jit(self): self.assertEqual(vectors_obj['b'], jit_vectors_obj['b']) self.assertEqual(vectors_obj['not_in_it'], jit_vectors_obj['not_in_it']) + def test_vectors_forward(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1], dtype=torch.float) + + unk_tensor = torch.tensor([0, 0], dtype=torch.float) + tokens = ['a', 'b'] + vecs = torch.stack((tensorA, tensorB), 0) + vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) + jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + + tokens_to_lookup = ['a', 'b', 'c'] + expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) + vectors_by_tokens = vectors_obj(tokens_to_lookup) + jit_vectors_by_tokens = jit_vectors_obj(tokens_to_lookup) + + self.assertEqual(expected_vectors, vectors_by_tokens) + self.assertEqual(expected_vectors, jit_vectors_by_tokens) + def test_vectors_lookup_vectors(self): tensorA = torch.tensor([1, 0], dtype=torch.float) tensorB = torch.tensor([0, 1], dtype=torch.float) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index fcc0056754..3cbac81e3c 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -7,9 +7,11 @@ from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase +from torchtext.experimental.transforms import basic_english_normalize from torchtext.experimental.vocab import ( vocab, - vocab_from_file_object + vocab_from_file, + vocab_from_raw_text_file ) @@ -117,6 +119,20 @@ def test_vocab_jit(self): self.assertEqual(jit_v.get_itos(), expected_itos) self.assertEqual(dict(jit_v.get_stoi()), expected_stoi) + def test_vocab_forward(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c) + jit_v = torch.jit.script(v.to_ivalue()) + + tokens = ['b', 'a', 'c'] + expected_indices = [2, 1, 3] + + self.assertEqual(v(tokens), expected_indices) + self.assertEqual(jit_v(tokens), expected_indices) + def test_vocab_lookup_token(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) @@ -208,11 +224,29 @@ def test_vocab_load_and_save(self): def test_vocab_from_file(self): asset_name = 'vocab_test.txt' asset_path = get_asset_path(asset_name) - f = open(asset_path, 'r') - v = vocab_from_file_object(f, unk_token='') + with open(asset_path, 'r') as f: + v = vocab_from_file(f, unk_token='') - expected_itos = ['', 'a', 'b', 'c'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} + expected_itos = ['', 'a', 'b', 'c'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + def test_vocab_from_raw_text_file(self): + asset_name = 'vocab_raw_text_test.txt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'r') as f: + + tokenizer = basic_english_normalize() + jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') + + expected_itos = ['', 'fears', 'for', 't', 'n', 'pension', 'after', + 'talks', 'unions', 'representing', 'workers', 'at', 'turner', + 'newall', 'say', 'they', 'are', "'", 'disappointed', 'with', + 'stricken', 'parent', 'firm', 'federal', 'mogul', '.'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/csrc/regex_tokenizer.cpp b/torchtext/csrc/regex_tokenizer.cpp index 3ab73e587c..c31ca36226 100644 --- a/torchtext/csrc/regex_tokenizer.cpp +++ b/torchtext/csrc/regex_tokenizer.cpp @@ -1,4 +1,4 @@ -#include "regex_tokenizer.h" +#include // @manual #include namespace torchtext { diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 28bb239cd5..293c620850 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -1,12 +1,12 @@ #include #include #include -#include "regex_tokenizer.h" -#include "sentencepiece.h" +#include // @manual +#include // @manual #include // @manual #include -#include "vectors.h" -#include "vocab.h" +#include // @manual +#include // @manual namespace torchtext { @@ -63,6 +63,7 @@ PYBIND11_MODULE(_torchtext, m) { m.def("_load_token_and_vectors_from_file", &_load_token_and_vectors_from_file); m.def("_load_vocab_from_file", &_load_vocab_from_file); + m.def("_load_vocab_from_raw_text_file", _load_vocab_from_raw_text_file); } // Registers our custom classes with torch. diff --git a/torchtext/csrc/sentencepiece.cpp b/torchtext/csrc/sentencepiece.cpp index 5d2f28eb7d..2294b689ed 100644 --- a/torchtext/csrc/sentencepiece.cpp +++ b/torchtext/csrc/sentencepiece.cpp @@ -1,4 +1,4 @@ -#include "sentencepiece.h" +#include // @manual namespace torchtext { diff --git a/torchtext/csrc/vectors.cpp b/torchtext/csrc/vectors.cpp index f115c7b9b9..029b3abb0d 100644 --- a/torchtext/csrc/vectors.cpp +++ b/torchtext/csrc/vectors.cpp @@ -11,7 +11,7 @@ #include #include #include -#include "vectors.h" +#include // @manual namespace torchtext { diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 78fcf3e1e9..db10993662 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -2,7 +2,9 @@ #include #include #include -#include "vocab.h" +#include // @manual +#include // @manual +#include // @manual namespace torchtext { @@ -146,9 +148,9 @@ int64_t _infer_lines(const std::string &file_path) { return num_lines; } -void parse_vocab_chunk(const std::string &file_path, size_t offset, - const int64_t start_line, const int64_t end_line, - std::shared_ptr tokens) { +void parse_vocab_file_chunk(const std::string &file_path, size_t offset, + const int64_t start_line, const int64_t end_line, + std::shared_ptr tokens) { std::ifstream fin; fin.open(file_path, std::ios::in); fin.seekg(offset); @@ -162,6 +164,28 @@ void parse_vocab_chunk(const std::string &file_path, size_t offset, } } +void parse_raw_text_file_chunk(const std::string &file_path, size_t offset, + const int64_t start_line, const int64_t end_line, + std::shared_ptr tokens, + torch::jit::script::Module &module) { + std::ifstream fin; + fin.open(file_path, std::ios::in); + fin.seekg(offset); + + std::string line; + for (int64_t i = start_line; i < end_line; i++) { + std::getline(fin, line); + auto token_list = + module.forward(std::vector({c10::IValue(line)})).toList(); + + for (size_t i = 0; i < token_list.size(); i++) { + c10::IValue token_ref = token_list.get(i); + std::string token = token_ref.toStringRef(); + tokens->push_back(token); + } + } +} + std::tuple _concat_tokens(std::vector> chunk_tokens, const std::string &unk_token, const int64_t min_freq, @@ -198,6 +222,7 @@ _concat_tokens(std::vector> chunk_tokens, tokens.emplace_back(unk_token); stoi[unk_token] = index; + index++; } // create tokens list and stoi map @@ -219,7 +244,6 @@ constexpr int64_t GRAIN_SIZE = 13107; Vocab _load_vocab_from_file(const std::string &file_path, const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus) { - std::cerr << "[INFO] Reading file " << file_path << std::endl; int64_t num_lines = _infer_lines(file_path); @@ -244,8 +268,61 @@ Vocab _load_vocab_from_file(const std::string &file_path, counter++; at::launch([&, file_path, num_lines, chunk_size, j, i, tokens_ptr]() { - parse_vocab_chunk(file_path, offsets[j], i, - std::min(num_lines, i + chunk_size), tokens_ptr); + parse_vocab_file_chunk(file_path, offsets[j], i, + std::min(num_lines, i + chunk_size), tokens_ptr); + std::lock_guard lk(m); + counter--; + cv.notify_all(); + }); + chunk_tokens.push_back(tokens_ptr); + j++; + } + + // block until all threads finish execution + std::unique_lock lock(m); + cv.wait(lock, [&counter] { return counter == 0; }); + + IndexDict stoi; + StringList tokens; + std::tie(stoi, tokens) = + _concat_tokens(chunk_tokens, unk_token, min_freq, num_lines); + + int64_t unk_index = stoi.find(unk_token)->second; + + return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); +} + +Vocab _load_vocab_from_raw_text_file(const std::string &file_path, + const std::string &unk_token, + const int64_t min_freq, + const int64_t num_cpus, py::object fn) { + std::cerr << "[INFO] Reading file " << file_path << std::endl; + + torch::jit::script::Module module(*torch::jit::as_module(fn)); + int64_t num_lines = _infer_lines(file_path); + int64_t chunk_size = impl::divup(num_lines, num_cpus); + // Launching a thread on less lines than this likely has too much overhead. + chunk_size = std::max(chunk_size, GRAIN_SIZE); + + std::vector offsets; + impl::infer_offsets(file_path, num_lines, chunk_size, offsets); + + std::vector> chunk_tokens; + + std::mutex m; + std::condition_variable cv; + std::atomic counter(0); + + // create threads + int64_t j = 0; + for (int64_t i = 0; i < num_lines; i += chunk_size) { + auto tokens_ptr = std::make_shared(); + + counter++; + at::launch([&, file_path, num_lines, chunk_size, j, i, tokens_ptr]() { + parse_raw_text_file_chunk(file_path, offsets[j], i, + std::min(num_lines, i + chunk_size), tokens_ptr, + module); std::lock_guard lk(m); counter--; cv.notify_all(); diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h index 0d3738aa54..005f833c02 100644 --- a/torchtext/csrc/vocab.h +++ b/torchtext/csrc/vocab.h @@ -1,3 +1,4 @@ +#include #include namespace torchtext { @@ -40,5 +41,10 @@ VocabStates _set_vocab_states(const c10::intrusive_ptr &self); Vocab _load_vocab_from_file(const std::string &file_path, const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus); +Vocab _load_vocab_from_raw_text_file(const std::string &file_path, + const std::string &unk_token, + const int64_t min_freq, + const int64_t num_cpus, + py::object tokenizer); } // namespace torchtext diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index a600bfe340..6554a677bf 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -57,7 +57,7 @@ def get_labels(self): labels = [] for item in self.data: label = item[0] - labels.apppend(self.transforms[0](label)) + labels.append(self.transforms[0](label)) return set(labels) def get_vocab(self): diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 5b22871220..0e60ad4214 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -1,8 +1,9 @@ import torch import torch.nn as nn from typing import List - from torchtext._torchtext import RegexTokenizer as RegexTokenizerPybind +from collections import OrderedDict +from torch import Tensor __all__ = [ 'BasicEnglishNormalize', @@ -153,3 +154,86 @@ def forward(self, input: str): for module in self: input = module(input) return input + + def to_ivalue(self): + r"""Return a JITable TextSequentialTransforms. + """ + module_list = [] + for _idx, _module in enumerate(self): + if hasattr(_module, 'to_ivalue'): + _module = _module.to_ivalue() + module_list.append((str(_idx), _module)) + return TextSequentialTransforms(OrderedDict(module_list)) + + +class VocabTransform(nn.Module): + r"""Vocab transform + + Args: + vocab: an instance of torchtext.experimental.vocab.Vocab class. + + Example: + >>> import torch + >>> from torchtext.experimental.vocab import vocab_from_file_object + >>> f = open('vocab.txt', 'r') + >>> vocab_transform = VocabTransform(vocab_from_file_object(f)) + >>> jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) + """ + + def __init__(self, vocab): + super(VocabTransform, self).__init__() + self.vocab = vocab + + def forward(self, tokens: List[str]) -> List[int]: + r""" + + Args: + tokens: a list of string tokens + + Example: + >>> vocab_transform(['here', 'is', 'an', 'example']) + + """ + return self.vocab.lookup_indices(tokens) + + def to_ivalue(self): + if hasattr(self.vocab, 'to_ivalue'): + vocab = self.vocab.to_ivalue() + return VocabTransform(vocab) + return self + + +class VectorTransform(nn.Module): + r"""Vector transform + + Args: + vector: an instance of torchtext.experimental.vectors.Vectors class. + + Example: + >>> import torch + >>> from torchtext.experimental.vectors import FastText + >>> vector_transform = VectorTransform(FastText()) + >>> jit_vector_transform = torch.jit.script(vector_transform.to_ivalue()) + """ + + def __init__(self, vector): + super(VectorTransform, self).__init__() + self.vector = vector + + def forward(self, tokens: List[str]) -> Tensor: + r""" + + Args: + tokens: a list of string tokens + + Example: + >>> vector_transform(['here', 'is', 'an', 'example']) + + """ + return self.vector.lookup_vectors(tokens) + + def to_ivalue(self): + if hasattr(self.vector, 'to_ivalue'): + vector = self.vector.to_ivalue() + return VectorTransform(vector) + return self diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index 45f1adc312..7fc3f120df 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -203,7 +203,7 @@ def is_jitable(self): return not isinstance(self.vectors, VectorsPybind) @torch.jit.export - def __call__(self, tokens: List[str]) -> Tensor: + def forward(self, tokens: List[str]) -> Tensor: r"""Calls the `lookup_vectors` method Args: tokens: a list of tokens diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index b0fa2ce46e..e4c5364575 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -6,15 +6,47 @@ import torch.nn as nn from torchtext._torchtext import ( Vocab as VocabPybind, - _load_vocab_from_file + _load_vocab_from_file, + _load_vocab_from_raw_text_file ) logger = logging.getLogger(__name__) -def vocab_from_file_object(file_like_object, min_freq=1, unk_token='', num_cpus=1): - r"""Create a `Vocab` object from a file like object. - The `file_like_object` should contain tokens seperated by new lines. Note that the vocab +def vocab_from_raw_text_file(file_object, jited_tokenizer, min_freq=1, unk_token='', num_cpus=4): + r"""Create a `Vocab` object from a raw text file. + + The `file_object` can contain any raw text. This function applies a generic JITed tokenizer in + parallel to the text. Note that the vocab will be created in the order that the tokens first appear + in the file (and not by the frequency of tokens). + + Args: + file_object (FileObject): a file object to read data from. + jited_tokenizer (ScriptModule): a tokenizer that has been JITed using `torch.jit.script` + min_freq: The minimum frequency needed to include a token in the vocabulary. + Values less than 1 will be set to 1. Default: 1. + unk_token: The default unknown token to use. Default: ''. + num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. + + Returns: + Vocab: a `Vocab` object. + + Examples: + >>> from torchtext.experimental.vocab import vocab_from_raw_text_file + >>> from torchtext.experimental.transforms import basic_english_normalize + >>> f = open('vocab.txt', 'r') + >>> tokenizer = basic_english_normalize() + >>> tokenizer = basic_english_normalize() + >>> jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + >>> v = vocab_from_raw_text_file(f, jit_tokenizer) + """ + vocab_obj = _load_vocab_from_raw_text_file(file_object.name, unk_token, min_freq, num_cpus, jited_tokenizer) + return Vocab(vocab_obj) + + +def vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4): + r"""Create a `Vocab` object from a text file. + The `file_object` should contain tokens separated by new lines. Note that the vocab will be created in the order that the tokens first appear in the file (and not by the frequency of tokens). Format for txt file: token1 @@ -22,20 +54,20 @@ def vocab_from_file_object(file_like_object, min_freq=1, unk_token='', num_ ... token_n Args: - file_like_object (FileObject): a file like object to read data from. + file_object (FileObject): a file like object to read data from. min_freq: The minimum frequency needed to include a token in the vocabulary. Values less than 1 will be set to 1. Default: 1. unk_token: The default unknown token to use. Default: ''. - num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. + num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. Returns: Vocab: a `Vocab` object. Examples: - >>> from torchtext.experimental.vocab import vocab_from_file_object + >>> from torchtext.experimental.vocab import vocab_from_file >>> f = open('vocab.txt', 'r') - >>> v = vocab_from_file_object(f) + >>> v = vocab_from_file(f) """ - vocab_obj = _load_vocab_from_file(file_like_object.name, unk_token, min_freq, num_cpus) + vocab_obj = _load_vocab_from_file(file_object.name, unk_token, min_freq, num_cpus) return Vocab(vocab_obj) @@ -96,7 +128,7 @@ def is_jitable(self): return not isinstance(self.vocab, VocabPybind) @torch.jit.export - def __call__(self, tokens: List[str]) -> List[int]: + def forward(self, tokens: List[str]) -> List[int]: r"""Calls the `lookup_indices` method Args: tokens (List[str]): the tokens used to lookup their corresponding `indices`. From f668e3c8f409a169fe8a260b6807c845572ef243 Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Fri, 4 Sep 2020 09:08:53 -0700 Subject: [PATCH 23/68] Import torchtext 9/4/2020 Reviewed By: Nayef211 Differential Revision: D23539397 fbshipit-source-id: 88dce59418a3071cbc9e944cf0a4cf2117d7d9f7 --- benchmark/benchmark_experimental_vocab.py | 72 ++++++++-- examples/data_pipeline/pipelines.py | 23 ++-- examples/data_pipeline/transforms.py | 90 +++++-------- test/data/test_functional.py | 16 +-- test/experimental/test_transforms.py | 10 +- test/experimental/test_vectors.py | 19 +-- test/experimental/test_vocab.py | 48 +++---- torchtext/csrc/register_bindings.cpp | 13 +- torchtext/csrc/sentencepiece.cpp | 5 + torchtext/csrc/sentencepiece.h | 2 + torchtext/csrc/vocab.cpp | 155 +++++++++++++--------- torchtext/data/functional.py | 14 +- torchtext/experimental/transforms.py | 48 ++++--- torchtext/experimental/vectors.py | 12 +- torchtext/experimental/vocab.py | 11 +- 15 files changed, 306 insertions(+), 232 deletions(-) diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 78c25070ca..9afaa52f3b 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -6,8 +6,8 @@ from torchtext.experimental.datasets import AG_NEWS from torchtext.experimental.vocab import ( vocab as VocabExperimental, - vocab_from_file_object, - vocab_from_raw_text_file_object + vocab_from_file, + vocab_from_raw_text_file ) from torchtext.vocab import ( Vocab, @@ -16,19 +16,63 @@ from torchtext.experimental.transforms import basic_english_normalize -def benchmark_experimental_vocab_construction(vocab_file_path, is_raw_text=True, num_iters=1): +def legacy_vocab_from_file_object(file_like_object, **kwargs): + r"""Create a `Vocab` object from a file like object. + + The `file_like_object` should contain tokens separated by new lines. Note that the vocab + will be created in the order that the tokens first appear in the file (and not by the frequency of tokens). + + Format for txt file: + token1 + token2 + ... + token_n + + Args: + file_like_object (FileObject): a file like object to read data from. + Remaining keyword arguments: Passed to the constructor of Vocab class. + + Returns: + Vocab: a `Vocab` object. + + Examples: + >>> from torchtext.experimental.vocab import vocab_from_file_object + >>> f = open('vocab.txt', 'r') + >>> v = vocab_from_file_object(f, specials=('', '', ''), specials_first=False) + """ + tokenizer = basic_english_normalize() + + def tokenize(line): + return tokenizer(line) + + def token_iterator(lines): + for line in lines: + for token in tokenize(line): + yield token + + return build_vocab_from_iterator(token_iterator(file_like_object)) + + +def benchmark_experimental_vocab_construction(vocab_file_path, is_raw_text=True, is_legacy=True, num_iters=1): f = open(vocab_file_path, 'r') t0 = time.monotonic() if is_raw_text: - print("Loading from raw text file with basic_english_normalize tokenizer") - for _ in range(num_iters): - tokenizer = basic_english_normalize() - jited_tokenizer = torch.jit.script(tokenizer.to_ivalue()) - vocab_from_raw_text_file_object(f, jited_tokenizer) - print("Construction time:", time.monotonic() - t0) + if is_legacy: + print("Loading from raw text file with legacy python function") + for _ in range(num_iters): + legacy_vocab_from_file_object(f) + + print("Construction time:", time.monotonic() - t0) + else: + print("Loading from raw text file with basic_english_normalize tokenizer") + for _ in range(num_iters): + tokenizer = basic_english_normalize() + jited_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + vocab_from_raw_text_file(f, jited_tokenizer, num_cpus=1) + print("Construction time:", time.monotonic() - t0) else: for _ in range(num_iters): - vocab_from_file_object(f) + vocab_from_file(f) print("Construction time:", time.monotonic() - t0) @@ -77,7 +121,7 @@ def token_iterator(file_path): print("Vocab Experimental") t0 = time.monotonic() f = open(vocab_file_path, 'r') - v_experimental = vocab_from_file_object(f) + v_experimental = vocab_from_file(f) print("Construction time:", time.monotonic() - t0) else: print("Loading Vocab from AG News") @@ -124,6 +168,8 @@ def token_iterator(file_path): help='run benchmark for constructing a vocab (default=False)') parser.add_argument('--is-raw-text', type=bool, default=True, help='construct vocab from raw text file (default=True)') + parser.add_argument('--is-legacy', type=bool, default=False, + help='construct vocab using legacy implementation (default=False)') parser.add_argument('--vocab-filename-construction', type=str, default='vocab.txt', help='The name of vocab file used for construction') parser.add_argument('--vocab-filename-lookup', type=str, default=None, @@ -131,6 +177,8 @@ def token_iterator(file_path): args = parser.parse_args() if args.run_construction_benchmark: - benchmark_experimental_vocab_construction(args.vocab_filename_construction, is_raw_text=args.is_raw_text) + print("is_legacy", args.is_legacy) + benchmark_experimental_vocab_construction(args.vocab_filename_construction, + is_raw_text=args.is_raw_text, is_legacy=args.is_legacy) else: benchmark_experimental_vocab_lookup(args.vocab_filename_lookup) diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index b3954ff295..7b003d2fba 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -3,15 +3,13 @@ PretrainedSPTokenizer, PretrainedSPVocab, PyTextVocabTransform, - ToLongTensor, + iterate_batch, ) from torchtext.experimental.transforms import ( basic_english_normalize, TextSequentialTransforms, - VocabTransform, - VectorTransform, ) -from torchtext.experimental.vocab import vocab_from_file_object +from torchtext.experimental.vocab import vocab_from_file from torchtext.experimental.vectors import FastText import argparse from torchtext.experimental.datasets.raw import text_classification as raw @@ -26,7 +24,7 @@ def build_sp_pipeline(spm_file): # Insert token in vocab to match a pretrained vocab vocab.insert_token('', 1) - pipeline = TextSequentialTransforms(tokenizer, vocab, ToLongTensor()) + pipeline = TextSequentialTransforms(tokenizer, vocab) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit sentencepiece pipeline success!') return pipeline, pipeline.to_ivalue(), jit_pipeline @@ -44,7 +42,7 @@ def token_iterator(vocab_file): yield token vocab = build_vocab_from_iterator(token_iterator(vocab_file)) pipeline = sequential_transforms(tokenizer, vocab_func(vocab), totensor(dtype=torch.long)) - return pipeline, None, None + return iterate_batch(pipeline), None, None def build_batch_torchtext_vocab(vocab_file): @@ -67,10 +65,10 @@ def token_iterator(vocab_file): def build_text_vocab_pipeline(hf_vocab_file): tokenizer = basic_english_normalize() f = open(hf_vocab_file, 'r') - vocab = vocab_from_file_object(f) + vocab = vocab_from_file(f) # Insert token in vocab to match a pretrained vocab - pipeline = TextSequentialTransforms(tokenizer, VocabTransform(vocab), ToLongTensor()) + pipeline = TextSequentialTransforms(tokenizer, vocab) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit text vocab pipeline success!') return pipeline, pipeline.to_ivalue(), jit_pipeline @@ -84,8 +82,7 @@ def build_pytext_vocab_pipeline(vocab_file): # Insert token in vocab to match a pretrained vocab pipeline = TextSequentialTransforms(tokenizer, - PyTextVocabTransform(ScriptVocabulary(vocab_list)), - ToLongTensor()) + PyTextVocabTransform(ScriptVocabulary(vocab_list))) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit PyText pipeline success!') return pipeline, pipeline.to_ivalue(), jit_pipeline @@ -96,7 +93,7 @@ def build_fasttext_vector_pipeline(): vector = FastText() # Insert token in vocab to match a pretrained vocab - pipeline = TextSequentialTransforms(tokenizer, VectorTransform(vector)) + pipeline = TextSequentialTransforms(tokenizer, vector) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit fasttext pipeline success!') return pipeline, pipeline.to_ivalue(), jit_pipeline @@ -104,8 +101,8 @@ def build_fasttext_vector_pipeline(): def run_benchmark_lookup(text_classification_dataset, pipeline): t0 = time.monotonic() - for (label, text) in text_classification_dataset: - text = pipeline(text) + lines = [text for (label, text) in text_classification_dataset] + lines = pipeline(lines) print("Lookup time:", time.monotonic() - t0) diff --git a/examples/data_pipeline/transforms.py b/examples/data_pipeline/transforms.py index fa02c027af..50a0225342 100644 --- a/examples/data_pipeline/transforms.py +++ b/examples/data_pipeline/transforms.py @@ -6,19 +6,6 @@ from torch import Tensor -class TextClassificationPipeline(nn.Module): - r"""Text classification pipeline template - """ - - def __init__(self, label_transform, text_transform): - super(TextClassificationPipeline, self).__init__() - self.label_transform = label_transform - self.text_transform = text_transform - - def forward(self, label_text_tuple): - return self.label_transform(label_text_tuple[0]), self.text_transform(label_text_tuple[1]) - - class PretrainedSPTokenizer(nn.Module): r"""Tokenizer based on a pretained sentencepiece model """ @@ -27,11 +14,13 @@ def __init__(self, sp_model): super(PretrainedSPTokenizer, self).__init__() self.sp_model = sp_model - def forward(self, line: str) -> List[str]: + def forward(self, lines: List[str]) -> List[List[str]]: r""" """ - - return self.sp_model.EncodeAsPieces(line) + tokens: List[List[str]] = [] + for line in lines: + tokens.append(self.sp_model.EncodeAsPieces(line)) + return tokens class PretrainedSPVocab(nn.Module): @@ -46,8 +35,11 @@ def __init__(self, sp_model): vocab_list = [self.sp_model.IdToPiece(i) for i in range(self.sp_model.GetPieceSize())] self.vocab = vocab(OrderedDict([(token, 1) for token in vocab_list]), unk_token=unk_token) - def forward(self, tokens: List[str]) -> List[int]: - return self.vocab.lookup_indices(tokens) + def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: + ids: List[List[int]] = [] + for tokens in tokens_list: + ids.append(self.vocab.lookup_indices(tokens)) + return ids def insert_token(self, token: str, index: int) -> None: self.vocab.insert_token(token, index) @@ -61,24 +53,6 @@ def to_ivalue(self): return self -class VocabTransform(nn.Module): - r"""Vocab transform - """ - - def __init__(self, vocab): - super(VocabTransform, self).__init__() - self.vocab = vocab - - def forward(self, tokens: List[str]) -> List[int]: - return self.vocab.lookup_indices(tokens) - - def to_ivalue(self): - if hasattr(self.vocab, 'to_ivalue'): - vocab = self.vocab.to_ivalue() - return VocabTransform(vocab) - return self - - class PyTextVocabTransform(nn.Module): r"""Vocab transform """ @@ -87,8 +61,11 @@ def __init__(self, vocab): super(PyTextVocabTransform, self).__init__() self.vocab = vocab - def forward(self, tokens: List[str]) -> List[int]: - return self.vocab.lookup_indices_1d(tokens) + def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: + ids: List[List[int]] = [] + for tokens in tokens_list: + ids.append(self.vocab.lookup_indices_1d(tokens)) + return ids def to_ivalue(self): if hasattr(self.vocab, 'to_ivalue'): @@ -97,30 +74,31 @@ def to_ivalue(self): return self -class VectorTransform(nn.Module): - r"""Vector transform +class ToLongTensor(nn.Module): + r"""Convert a list of integers to long tensor """ - def __init__(self, vector): - super(VectorTransform, self).__init__() - self.vector = vector + def __init__(self): + super(ToLongTensor, self).__init__() - def forward(self, tokens: List[str]) -> Tensor: - return self.vector.lookup_vectors(tokens) + def forward(self, tokens: List[List[int]]) -> Tensor: + return torch.tensor(tokens).to(torch.long) - def to_ivalue(self): - if hasattr(self.vector, 'to_ivalue'): - vector = self.vector.to_ivalue() - return VectorTransform(vector) - return self +def iterate_batch(pipeline): + def func(data_batch): + return [pipeline(data) for data in data_batch] + return func -class ToLongTensor(nn.Module): - r"""Convert a list of integers to long tensor + +class TextClassificationPipeline(nn.Module): + r"""Text classification pipeline template """ - def __init__(self): - super(ToLongTensor, self).__init__() + def __init__(self, label_transform, text_transform): + super(TextClassificationPipeline, self).__init__() + self.label_transform = label_transform + self.text_transform = text_transform - def forward(self, tokens: List[int]) -> Tensor: - return torch.tensor(tokens).to(torch.long) + def forward(self, label_text_tuple): + return self.label_transform(label_text_tuple[0]), self.text_transform(label_text_tuple[1]) diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 6057c02769..174f641733 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -68,7 +68,7 @@ def test_sentencepiece_numericalizer(self): def test_sentencepiece_tokenizer(self): test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' model_path = get_asset_path('spm_example.model') - sp_model = load_sp_model(model_path) + sp_model = load_sp_model(open(model_path, 'rb')) self.assertEqual(sp_model.GetPieceSize(), 20000) spm_generator = sentencepiece_tokenizer(sp_model) @@ -83,9 +83,9 @@ def test_sentencepiece_tokenizer(self): # TODO(Nayef211): remove decorator once https://github.com/pytorch/pytorch/issues/38207 is closed @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_BasicEnglishNormalize(self): - test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' - ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', - 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] + test_sample = ['\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:'] + ref_results = [["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', + 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?']] basic_eng_norm = basic_english_normalize() experimental_eager_tokens = basic_eng_norm(test_sample) @@ -94,7 +94,7 @@ def test_BasicEnglishNormalize(self): experimental_jit_tokens = jit_basic_eng_norm(test_sample) basic_english_tokenizer = data.get_tokenizer("basic_english") - eager_tokens = basic_english_tokenizer(test_sample) + eager_tokens = [basic_english_tokenizer(test_sample[0])] assert not basic_eng_norm.is_jitable assert basic_eng_norm.to_ivalue().is_jitable @@ -114,9 +114,9 @@ def test_BasicEnglishNormalize(self): # TODO(Nayef211): remove decorator once https://github.com/pytorch/pytorch/issues/38207 is closed @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_RegexTokenizer(self): - test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' - ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', - 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] + test_sample = ['\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:'] + ref_results = [["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', + 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?']] patterns_list = [ (r'\'', ' \' '), (r'\"', ''), diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py index 608efd2ad9..7e8b29c8b6 100644 --- a/test/experimental/test_transforms.py +++ b/test/experimental/test_transforms.py @@ -18,9 +18,11 @@ def test_vocab_transform(self): asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: vocab_transform = VocabTransform(vocab_from_file(f)) - self.assertEqual(vocab_transform(['of', 'that', 'new']), [7, 18, 24]) + self.assertEqual(vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), + [[21, 26, 20], [21, 26, 20, 26]]) jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) - self.assertEqual(jit_vocab_transform(['of', 'that', 'new']), [7, 18, 24]) + self.assertEqual(jit_vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), + [[21, 26, 20], [21, 26, 20, 26]]) def test_vector_transform(self): asset_name = 'wiki.en.vec' @@ -34,5 +36,5 @@ def test_vector_transform(self): # The first 3 entries in each vector. expected_fasttext_simple_en = torch.tensor([[-0.065334, -0.093031, -0.017571], [-0.32423, -0.098845, -0.0073467]]) - self.assertEqual(vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) - self.assertEqual(jit_vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) + self.assertEqual(vector_transform([['the', 'world']])[0][:, 0:3], expected_fasttext_simple_en) + self.assertEqual(jit_vector_transform([['the', 'world']])[0][:, 0:3], expected_fasttext_simple_en) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 45a86fef23..26c858cb12 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -81,8 +81,8 @@ def test_vectors_forward(self): vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) - tokens_to_lookup = ['a', 'b', 'c'] - expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) + tokens_to_lookup = [['a', 'b', 'c']] + expected_vectors = [torch.stack((tensorA, tensorB, unk_tensor), 0)] vectors_by_tokens = vectors_obj(tokens_to_lookup) jit_vectors_by_tokens = jit_vectors_obj(tokens_to_lookup) @@ -104,21 +104,6 @@ def test_vectors_lookup_vectors(self): self.assertEqual(expected_vectors, vectors_by_tokens) - def test_vectors_call_method(self): - tensorA = torch.tensor([1, 0], dtype=torch.float) - tensorB = torch.tensor([0, 1], dtype=torch.float) - - unk_tensor = torch.tensor([0, 0], dtype=torch.float) - tokens = ['a', 'b'] - vecs = torch.stack((tensorA, tensorB), 0) - vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) - - tokens_to_lookup = ['a', 'b', 'c'] - expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) - vectors_by_tokens = vectors_obj(tokens_to_lookup) - - self.assertEqual(expected_vectors, vectors_by_tokens) - def test_vectors_add_item(self): tensorA = torch.tensor([1, 0], dtype=torch.float) unk_tensor = torch.tensor([0, 0], dtype=torch.float) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 3cbac81e3c..1201587aeb 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -7,11 +7,11 @@ from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase -from torchtext.experimental.transforms import basic_english_normalize +# from torchtext.experimental.transforms import basic_english_normalize from torchtext.experimental.vocab import ( vocab, vocab_from_file, - vocab_from_raw_text_file + # vocab_from_raw_text_file ) @@ -127,8 +127,8 @@ def test_vocab_forward(self): v = vocab(c) jit_v = torch.jit.script(v.to_ivalue()) - tokens = ['b', 'a', 'c'] - expected_indices = [2, 1, 3] + tokens = [['b', 'a', 'c']] + expected_indices = [[2, 1, 3]] self.assertEqual(v(tokens), expected_indices) self.assertEqual(jit_v(tokens), expected_indices) @@ -163,17 +163,6 @@ def test_vocab_lookup_indices(self): self.assertEqual(v.lookup_indices(tokens), expected_indices) - def test_vocab_call_method(self): - token_to_freq = {'a': 2, 'b': 2, 'c': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c) - - tokens = ['b', 'a', 'c'] - expected_indices = [2, 1, 3] - - self.assertEqual(v(tokens), expected_indices) - # we separate out these errors because Windows runs into seg faults when propagating # exceptions from C++ using pybind11 @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") @@ -233,20 +222,21 @@ def test_vocab_from_file(self): self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) - def test_vocab_from_raw_text_file(self): - asset_name = 'vocab_raw_text_test.txt' - asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: + # TODO: Update cpp function to use a list of strings from the JITed tokenizer + # def test_vocab_from_raw_text_file(self): + # asset_name = 'vocab_raw_text_test.txt' + # asset_path = get_asset_path(asset_name) + # f = open(asset_path, 'r') - tokenizer = basic_english_normalize() - jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) - v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') + # tokenizer = basic_english_normalize() + # jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + # v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') - expected_itos = ['', 'fears', 'for', 't', 'n', 'pension', 'after', - 'talks', 'unions', 'representing', 'workers', 'at', 'turner', - 'newall', 'say', 'they', 'are', "'", 'disappointed', 'with', - 'stricken', 'parent', 'firm', 'federal', 'mogul', '.'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} + # expected_itos = ['', 'after', 'talks', "'", 'newall', '.', 'mogul', 'federal', + # 'firm', 'parent', 'stricken', 'with', 'disappointed', 'are', 'they', + # 'say', 'fears', 'turner', 'at', 'workers', 'representing', 'unions', + # 'pension', 'n', 't', 'for'] + # expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) + # self.assertEqual(v.get_itos(), expected_itos) + # self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 293c620850..4f817b3720 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -1,12 +1,12 @@ #include #include #include -#include // @manual -#include // @manual +#include // @manual +#include // @manual #include // @manual #include #include // @manual -#include // @manual +#include // @manual namespace torchtext { @@ -172,5 +172,10 @@ static auto registry = .op(torch::RegisterOperators::options() .schema("torchtext::load_sp_model(str path) -> " "__torch__.torch.classes.torchtext.SentencePiece model") - .catchAllKernel()); + .catchAllKernel()) + .op(torch::RegisterOperators::options() + .schema("torchtext::load_sp_model_string(str content) -> " + "__torch__.torch.classes.torchtext.SentencePiece model") + .catchAllKernel()); } // namespace torchtext diff --git a/torchtext/csrc/sentencepiece.cpp b/torchtext/csrc/sentencepiece.cpp index 2294b689ed..7e89a544eb 100644 --- a/torchtext/csrc/sentencepiece.cpp +++ b/torchtext/csrc/sentencepiece.cpp @@ -64,4 +64,9 @@ c10::intrusive_ptr load_sp_model(const std::string &path) { return c10::make_intrusive(std::move(content)); } +c10::intrusive_ptr +load_sp_model_string(const std::string &content) { + return c10::make_intrusive(std::move(content)); +} + } // namespace torchtext diff --git a/torchtext/csrc/sentencepiece.h b/torchtext/csrc/sentencepiece.h index b6786eab29..e1079b102f 100644 --- a/torchtext/csrc/sentencepiece.h +++ b/torchtext/csrc/sentencepiece.h @@ -30,5 +30,7 @@ void generate_sp_model(const std::string &filename, const int64_t &vocab_size, const std::string &model_type, const std::string &model_prefix); c10::intrusive_ptr load_sp_model(const std::string &path); +c10::intrusive_ptr +load_sp_model_string(const std::string &content); } // namespace torchtext diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index db10993662..200c217e5c 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -3,8 +3,8 @@ #include #include #include // @manual -#include // @manual -#include // @manual +#include // @manual +#include // @manual namespace torchtext { @@ -150,7 +150,7 @@ int64_t _infer_lines(const std::string &file_path) { void parse_vocab_file_chunk(const std::string &file_path, size_t offset, const int64_t start_line, const int64_t end_line, - std::shared_ptr tokens) { + std::shared_ptr counter) { std::ifstream fin; fin.open(file_path, std::ios::in); fin.seekg(offset); @@ -160,13 +160,17 @@ void parse_vocab_file_chunk(const std::string &file_path, size_t offset, fin >> token; fin >> std::ws; - tokens->push_back(token); + if ((*counter).find(token) == (*counter).end()) { + (*counter)[token] = 1; + } else { + (*counter)[token] += 1; + } } } void parse_raw_text_file_chunk(const std::string &file_path, size_t offset, const int64_t start_line, const int64_t end_line, - std::shared_ptr tokens, + std::shared_ptr counter, torch::jit::script::Module &module) { std::ifstream fin; fin.open(file_path, std::ios::in); @@ -181,38 +185,74 @@ void parse_raw_text_file_chunk(const std::string &file_path, size_t offset, for (size_t i = 0; i < token_list.size(); i++) { c10::IValue token_ref = token_list.get(i); std::string token = token_ref.toStringRef(); - tokens->push_back(token); + + if ((*counter).find(token) == (*counter).end()) { + (*counter)[token] = 1; + } else { + (*counter)[token] += 1; + } } } } +// sorting using a custom object +struct CompareTokens { + bool operator()(const std::pair &a, + const std::pair &b) { + if (a.second == b.second) { + return a.first < b.first; + } + return a.second > b.second; + } +}; + std::tuple -_concat_tokens(std::vector> chunk_tokens, +_concat_tokens(std::vector> chunk_counters, const std::string &unk_token, const int64_t min_freq, const int64_t num_lines) { - TORCH_CHECK(chunk_tokens.size() > 0, + TORCH_CHECK(chunk_counters.size() > 0, "There must be at least 1 chunk to concatenate!"); - std::unordered_map tokens_freq; - IndexDict stoi; - StringList tokens; - stoi.reserve(num_lines); - tokens.reserve(num_lines); - - // create tokens frequency map - for (size_t i = 0; i < chunk_tokens.size(); i++) { - auto &subset_tokens = *chunk_tokens[i]; - for (size_t j = 0; j < subset_tokens.size(); j++) { - // const auto &item = tokens_freq.find(subset_tokens[j]); - if (tokens_freq.find(subset_tokens[j]) != tokens_freq.end()) { - tokens_freq[subset_tokens[j]]++; + IndexDict tokens_freq; + StringList unique_tokens; + unique_tokens.reserve(num_lines); + + // concatenate all counters + for (size_t i = 0; i < chunk_counters.size(); i++) { + auto &cur_counter = *chunk_counters[i]; + for (const auto &item : cur_counter) { + int64_t cur_token_freq = item.second; + if (tokens_freq.find(item.first) != tokens_freq.end()) { + tokens_freq[item.first] += cur_token_freq; } else { - tokens_freq[subset_tokens[j]] = 1; + tokens_freq[item.first] = cur_token_freq; + } + + // add to tokens list only if we exceed min_freq for the first time + if (tokens_freq[item.first] - cur_token_freq < min_freq && + tokens_freq[item.first] >= min_freq) { + unique_tokens.push_back(item.first); } } } - int64_t index = 0; + // create token freq pairs + std::vector> token_freq_pairs; + + for (std::string token : unique_tokens) { + token_freq_pairs.push_back(std::make_pair(token, tokens_freq[token])); + } + + // sort tokens by freq + CompareTokens compare_tokens; + std::sort(token_freq_pairs.begin(), token_freq_pairs.end(), compare_tokens); + + // update unique tokens with correct order + unique_tokens.clear(); + for (const auto &token_freq_pair : token_freq_pairs) { + unique_tokens.push_back(token_freq_pair.first); + } + // insert unk_token if not present if (tokens_freq.find(unk_token) == tokens_freq.end()) { std::cerr << "The `unk_token` " << unk_token @@ -220,24 +260,20 @@ _concat_tokens(std::vector> chunk_tokens, "to the beginning of the Vocab." << std::endl; - tokens.emplace_back(unk_token); - stoi[unk_token] = index; - index++; + unique_tokens.insert(unique_tokens.begin(), unk_token); } - // create tokens list and stoi map - for (size_t i = 0; i < chunk_tokens.size(); i++) { - auto &subset_tokens = *chunk_tokens[i]; - for (size_t j = 0; j < subset_tokens.size(); j++) { - if (tokens_freq[subset_tokens[j]] >= min_freq && - stoi.find(subset_tokens[j]) == stoi.end()) { - tokens.emplace_back(subset_tokens[j]); - stoi[subset_tokens[j]] = index; - index++; - } - } + // create stoi + IndexDict stoi; + stoi.reserve(num_lines); + int64_t index = 0; + + for (const auto &token : unique_tokens) { + stoi[token] = index; + index++; } - return std::make_tuple(std::move(stoi), std::move(tokens)); + + return std::make_tuple(std::move(stoi), std::move(unique_tokens)); } constexpr int64_t GRAIN_SIZE = 13107; @@ -255,37 +291,37 @@ Vocab _load_vocab_from_file(const std::string &file_path, std::vector offsets; impl::infer_offsets(file_path, num_lines, chunk_size, offsets); - std::vector> chunk_tokens; + std::vector> chunk_counters; std::mutex m; std::condition_variable cv; - std::atomic counter(0); + std::atomic thread_count(0); // create threads int64_t j = 0; for (int64_t i = 0; i < num_lines; i += chunk_size) { - auto tokens_ptr = std::make_shared(); + auto counter_ptr = std::make_shared(); - counter++; - at::launch([&, file_path, num_lines, chunk_size, j, i, tokens_ptr]() { + thread_count++; + at::launch([&, file_path, num_lines, chunk_size, j, i, counter_ptr]() { parse_vocab_file_chunk(file_path, offsets[j], i, - std::min(num_lines, i + chunk_size), tokens_ptr); + std::min(num_lines, i + chunk_size), counter_ptr); std::lock_guard lk(m); - counter--; + thread_count--; cv.notify_all(); }); - chunk_tokens.push_back(tokens_ptr); + chunk_counters.push_back(counter_ptr); j++; } // block until all threads finish execution std::unique_lock lock(m); - cv.wait(lock, [&counter] { return counter == 0; }); + cv.wait(lock, [&thread_count] { return thread_count == 0; }); IndexDict stoi; StringList tokens; std::tie(stoi, tokens) = - _concat_tokens(chunk_tokens, unk_token, min_freq, num_lines); + _concat_tokens(chunk_counters, unk_token, min_freq, num_lines); int64_t unk_index = stoi.find(unk_token)->second; @@ -307,38 +343,37 @@ Vocab _load_vocab_from_raw_text_file(const std::string &file_path, std::vector offsets; impl::infer_offsets(file_path, num_lines, chunk_size, offsets); - std::vector> chunk_tokens; + std::vector> chunk_counters; std::mutex m; std::condition_variable cv; - std::atomic counter(0); + std::atomic thread_count(0); // create threads int64_t j = 0; for (int64_t i = 0; i < num_lines; i += chunk_size) { - auto tokens_ptr = std::make_shared(); - - counter++; - at::launch([&, file_path, num_lines, chunk_size, j, i, tokens_ptr]() { + auto counter_ptr = std::make_shared(); + thread_count++; + at::launch([&, file_path, num_lines, chunk_size, j, i, counter_ptr]() { parse_raw_text_file_chunk(file_path, offsets[j], i, - std::min(num_lines, i + chunk_size), tokens_ptr, - module); + std::min(num_lines, i + chunk_size), + counter_ptr, module); std::lock_guard lk(m); - counter--; + thread_count--; cv.notify_all(); }); - chunk_tokens.push_back(tokens_ptr); + chunk_counters.push_back(counter_ptr); j++; } // block until all threads finish execution std::unique_lock lock(m); - cv.wait(lock, [&counter] { return counter == 0; }); + cv.wait(lock, [&thread_count] { return thread_count == 0; }); IndexDict stoi; StringList tokens; std::tie(stoi, tokens) = - _concat_tokens(chunk_tokens, unk_token, min_freq, num_lines); + _concat_tokens(chunk_counters, unk_token, min_freq, num_lines); int64_t unk_index = stoi.find(unk_token)->second; return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); diff --git a/torchtext/data/functional.py b/torchtext/data/functional.py index a1d7a3b41e..3333c2dc63 100644 --- a/torchtext/data/functional.py +++ b/torchtext/data/functional.py @@ -1,5 +1,5 @@ import re - +import io import torch @@ -39,11 +39,11 @@ def generate_sp_model(filename, vocab_size=20000, torch.ops.torchtext.generate_sp_model(filename, vocab_size, model_type, model_prefix) -def load_sp_model(spm_path): +def load_sp_model(spm): r"""Load a sentencepiece model for file. Arguments: - spm_path: the file path saving the sentencepiece model. + spm: the file path or a file object saving the sentencepiece model. Outputs: output: a SentencePiece model. @@ -51,8 +51,14 @@ def load_sp_model(spm_path): Examples: >>> from torchtext.data.functional import load_sp_model >>> sp_model = load_sp_model("m_user.model") + >>> sp_model = load_sp_model(open("m_user.model", 'rb')) """ - return torch.ops.torchtext.load_sp_model(spm_path) + if isinstance(spm, str): + return torch.ops.torchtext.load_sp_model(spm) + elif isinstance(spm, io.BufferedReader): + return torch.ops.torchtext.load_sp_model_string(spm.read()) + else: + raise RuntimeError('the input of the load_sp_model func is not supported.') def sentencepiece_numericalizer(sp_model): diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 0e60ad4214..5b60f362b5 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -94,14 +94,18 @@ def __init__(self, regex_tokenizer): def is_jitable(self): return not isinstance(self.regex_tokenizer, RegexTokenizerPybind) - def forward(self, line: str) -> List[str]: + def forward(self, lines: List[str]) -> List[List[str]]: r""" Args: - line (str): a line of text to tokenize. + lines (List[str]): a list of text to tokenize. + Returns: - List[str]: a list of tokens after normalizing and splitting on whitespace. + List[List[str]]: a list of token list after normalizing and splitting on whitespace. """ - return self.regex_tokenizer.forward(line) + tokens: List[List[str]] = [] + for line in lines: + tokens.append(self.regex_tokenizer.forward(line)) + return tokens def to_ivalue(self): r"""Return a JITable BasicEnglishNormalize. @@ -124,14 +128,18 @@ def __init__(self, regex_tokenzier): def is_jitable(self): return not isinstance(self.regex_tokenizer, RegexTokenizerPybind) - def forward(self, line: str) -> List[str]: + def forward(self, lines: List[str]) -> List[List[str]]: r""" Args: - line (str): a line of text to tokenize. + lines (List[str]): a list of text to tokenize. + Returns: - List[str]: a list of tokens after normalizing and splitting on whitespace. + List[List[str]]: a list of token list after normalizing and splitting on whitespace. """ - return self.regex_tokenizer.forward(line) + tokens: List[List[str]] = [] + for line in lines: + tokens.append(self.regex_tokenizer.forward(line)) + return tokens def to_ivalue(self): r"""Return a JITable RegexTokenizer. @@ -150,7 +158,7 @@ class TextSequentialTransforms(nn.Sequential): >>> txt_pipeline = TextSequentialTransforms(tokenizer) >>> jit_txt_pipeline = torch.jit.script(txt_pipeline) """ - def forward(self, input: str): + def forward(self, input: List[str]): for module in self: input = module(input) return input @@ -184,17 +192,20 @@ def __init__(self, vocab): super(VocabTransform, self).__init__() self.vocab = vocab - def forward(self, tokens: List[str]) -> List[int]: + def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: r""" Args: - tokens: a list of string tokens + tokens: a list of string token list Example: - >>> vocab_transform(['here', 'is', 'an', 'example']) + >>> vocab_transform([['here', 'is', 'an', 'example']]) """ - return self.vocab.lookup_indices(tokens) + ids: List[List[int]] = [] + for tokens in tokens_list: + ids.append(self.vocab.lookup_indices(tokens)) + return ids def to_ivalue(self): if hasattr(self.vocab, 'to_ivalue'): @@ -220,17 +231,20 @@ def __init__(self, vector): super(VectorTransform, self).__init__() self.vector = vector - def forward(self, tokens: List[str]) -> Tensor: + def forward(self, tokens_list: List[List[str]]) -> List[Tensor]: r""" Args: - tokens: a list of string tokens + tokens: a list of string token list Example: - >>> vector_transform(['here', 'is', 'an', 'example']) + >>> vector_transform([['here', 'is', 'an', 'example']]) """ - return self.vector.lookup_vectors(tokens) + vectors: List[Tensor] = [] + for tokens in tokens_list: + vectors.append(self.vector.lookup_vectors(tokens)) + return vectors def to_ivalue(self): if hasattr(self.vector, 'to_ivalue'): diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index 7fc3f120df..5954b3721c 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -203,15 +203,19 @@ def is_jitable(self): return not isinstance(self.vectors, VectorsPybind) @torch.jit.export - def forward(self, tokens: List[str]) -> Tensor: + def forward(self, tokens_list: List[List[str]]) -> List[Tensor]: r"""Calls the `lookup_vectors` method Args: - tokens: a list of tokens + tokens: a list of string token list Returns: - vectors (Tensor): returns a 2-D tensor of shape=(len(tokens), vector_dim) or an empty tensor if `tokens` is empty + vectors (List[Tensor]): returns a list of a 2-D tensor of shape=(len(tokens), vector_dim) or + an empty tensor if `tokens` is empty """ - return self.lookup_vectors(tokens) + vectors: List[Tensor] = [] + for tokens in tokens_list: + vectors.append(self.vectors.lookup_vectors(tokens)) + return vectors @torch.jit.export def __getitem__(self, token: str) -> Tensor: diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index e4c5364575..a3e97778dd 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -128,15 +128,18 @@ def is_jitable(self): return not isinstance(self.vocab, VocabPybind) @torch.jit.export - def forward(self, tokens: List[str]) -> List[int]: + def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: r"""Calls the `lookup_indices` method Args: - tokens (List[str]): the tokens used to lookup their corresponding `indices`. + tokens (List[List[str]]): a list of tokens used to lookup their corresponding `indices`. Returns: - indices (List[int]): the 'indices` associated with `tokens`. + indices (List[List[int]]): the 'indices` associated with a list of tokens`. """ - return self.lookup_indices(tokens) + ids: List[List[int]] = [] + for tokens in tokens_list: + ids.append(self.vocab.lookup_indices(tokens)) + return ids @torch.jit.export def __len__(self) -> int: From d2e1af467351e709a95122ea00e2b9a03cf17200 Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Sun, 13 Sep 2020 10:11:12 -0700 Subject: [PATCH 24/68] Import github torchtext on 9/9/2020 Reviewed By: cpuhrsch Differential Revision: D23616189 fbshipit-source-id: 365debc987326145eead7456ed48517fe55cac96 --- benchmark/benchmark_experimental_vocab.py | 2 +- benchmark/benchmark_pytext_vocab.py | 2 +- examples/data_pipeline/README.md | 57 ++++++-- examples/data_pipeline/pipelines.py | 150 +++++++++++++++------- examples/data_pipeline/transforms.py | 41 +++++- examples/vocab/pytext_vocab.py | 31 ++++- test/experimental/test_transforms.py | 4 +- test/experimental/test_vocab.py | 40 +++--- torchtext/csrc/vocab.cpp | 19 ++- torchtext/experimental/vectors.py | 4 +- 10 files changed, 249 insertions(+), 101 deletions(-) diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 9afaa52f3b..29f1c18e80 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -19,7 +19,7 @@ def legacy_vocab_from_file_object(file_like_object, **kwargs): r"""Create a `Vocab` object from a file like object. - The `file_like_object` should contain tokens separated by new lines. Note that the vocab + The `file_like_object` should contain tokens seperated by new lines. Note that the vocab will be created in the order that the tokens first appear in the file (and not by the frequency of tokens). Format for txt file: diff --git a/benchmark/benchmark_pytext_vocab.py b/benchmark/benchmark_pytext_vocab.py index 6dbe200fd4..2e686dd5dc 100644 --- a/benchmark/benchmark_pytext_vocab.py +++ b/benchmark/benchmark_pytext_vocab.py @@ -150,7 +150,7 @@ def benchmark_experimental_vocab(): t0 = time.monotonic() experimental_script_vocab = ExperimentalScriptVocabulary(ordered_dict, unk_token="") print("Construction time:", time.monotonic() - t0) - jit_experimental_script_vocab = torch.jit.script(experimental_script_vocab) + jit_experimental_script_vocab = torch.jit.script(experimental_script_vocab.to_ivalue()) # pytext Vocab eager lookup print("Pytext Vocabulary - Eager Mode") diff --git a/examples/data_pipeline/README.md b/examples/data_pipeline/README.md index 6a6f45e586..34418be5d4 100644 --- a/examples/data_pipeline/README.md +++ b/examples/data_pipeline/README.md @@ -20,7 +20,22 @@ The lookup time: 34.36592311505228 (eager mode with torchbind) The lookup time: 23.43273439211771 (jit mode) -## Vocab from a text file +## Legacy Torchtext + +This pipeline example shows the application with the existing `Vocab` in torchtext library. The `Vocab` instance is built from a text file where a column of vocab tokens are read in sequence. + +* `basic_english` func from `torchtext.data.utils.get_tokenizer` +* `torchtext.vocab.Vocab` +* `torchtext.experimental.functional.totensor` to convert a list of integers to `torch.tensor` + +The command to run the pipeline: + + python pipelines.py --pipeline torchtext + +The lookup time: 8.690132656134665 (eager mode) + + +## Experimental Torchtext This pipeline example shows the application with the vocab text file from Hugging Face ([link](https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-uncased-vocab.txt)). The experimental vocab in torchtext library is used here: @@ -37,7 +52,7 @@ The lookup time: 17.28485624492168 (eager mode with torchbind) The lookup time: 10.25370063772425 (jit mode) -## PyText +## Legacy PyText This pipeline example shows the application with the existing `ScriptVocab` in pytext library. The `ScriptVocab` instance is built from a text file where a column of vocab tokens are read in sequence. @@ -54,22 +69,24 @@ The lookup time: 22.16066740499809 (eager mode with torchbind) The lookup time: 13.41519635310396 (jit mode) -## Torchtext +## Experimental PyText -This pipeline example shows the application with the existing `Vocab` in torchtext library. The `Vocab` instance is built from a text file where a column of vocab tokens are read in sequence. +This pipeline example shows the application with a `ScriptVocab` based on the torchtext vocab. The `ScriptVocab` instance is built from a text file where a column of vocab tokens are read in sequence. -* `basic_english` func from `torchtext.data.utils.get_tokenizer` -* `torchtext.vocab.Vocab` -* `torchtext.experimental.functional.totensor` to convert a list of integers to `torch.tensor` +* `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library +* `from pytext.torchscript.vocab.ScriptVocabulary` +* `ToLongTensor` to convert a list of integers to `torch.tensor` -The command to run the pipeline: +With the dependency of `pytext` library, the command to run the pipeline: - python pipelines.py --pipeline torchtext + python pipelines.py --pipeline pytext -The lookup time: 8.690132656134665 (eager mode) +The lookup time: 11.004039663821459 (eager mode with pybind) +The lookup time: 17.025434703100473 (eager mode with torchbind) +The lookup time: 10.078087331261486 (jit mode) -## Torchtext with a batch of data +## Legacy Torchtext with a batch of data This pipeline example shows the application with the data batch as input. For the real-world text classification task, two separate pipelines are created for text and label. @@ -92,9 +109,23 @@ The command to run the pipeline: The lookup time: 10.05315054487437 (eager mode) -## FastText pretrained word vectors +## Legacy FastText pretrained word vectors + +This pipeline example shows the application with the pretained word vector from legacy FastText: + +* `basic_english` func from `torchtext.data.utils.get_tokenizer` +* `torchtext.vocab.FastText` + +The command to run the pipeline: + + python pipelines.py --pipeline fasttext + +The lookup time: 34.08170719863847 (eager mode) + + +## Experimental FastText pretrained word vectors -This pipeline example shows the application with the pretained word vector from FastText: +This pipeline example shows the application with the pretained word vector using our experimental FastText: * `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library * `torchtext.experimental.vectors.FastText` diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index 7b003d2fba..466137eada 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -1,16 +1,27 @@ +from collections import Counter, OrderedDict import torch from transforms import ( PretrainedSPTokenizer, PretrainedSPVocab, PyTextVocabTransform, + PyTextScriptVocabTransform, iterate_batch, + tokenizer_func, + totensor, + vocab_func, ) from torchtext.experimental.transforms import ( basic_english_normalize, TextSequentialTransforms, ) +from torchtext.data.utils import get_tokenizer +from torchtext.experimental.functional import ( + sequential_transforms, +) +from torchtext.experimental.vectors import FastText as FastTextExperimental from torchtext.experimental.vocab import vocab_from_file -from torchtext.experimental.vectors import FastText +from torchtext.vocab import FastText + import argparse from torchtext.experimental.datasets.raw import text_classification as raw import time @@ -30,72 +41,115 @@ def build_sp_pipeline(spm_file): return pipeline, pipeline.to_ivalue(), jit_pipeline -def build_torchtext_vocab(vocab_file): - from torchtext.data.utils import get_tokenizer +def build_legacy_torchtext_vocab_pipeline(vocab_file): tokenizer = get_tokenizer("basic_english") from torchtext.vocab import build_vocab_from_iterator - from torchtext.experimental.functional import totensor, vocab_func, sequential_transforms def token_iterator(vocab_file): f = open(vocab_file, 'r') - for token in f: - yield token + for line in f: + for token in line: + yield token + vocab = build_vocab_from_iterator(token_iterator(vocab_file)) - pipeline = sequential_transforms(tokenizer, vocab_func(vocab), totensor(dtype=torch.long)) + pipeline = sequential_transforms(tokenizer_func(tokenizer), vocab_func(vocab)) return iterate_batch(pipeline), None, None -def build_batch_torchtext_vocab(vocab_file): - from torchtext.data.utils import get_tokenizer +def build_experimental_torchtext_pipeline(hf_vocab_file): + tokenizer = basic_english_normalize() + with open(hf_vocab_file, 'r') as f: + vocab = vocab_from_file(f) + pipeline = TextSequentialTransforms(tokenizer, vocab) + jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + print('jit experimental torchtext pipeline success!') + return pipeline, pipeline.to_ivalue(), jit_pipeline + + +def build_legacy_batch_torchtext_vocab_pipeline(vocab_file): tokenizer = get_tokenizer("basic_english") from torchtext.vocab import build_vocab_from_iterator from transforms import TextClassificationPipeline - from torchtext.experimental.functional import totensor, vocab_func, sequential_transforms def token_iterator(vocab_file): f = open(vocab_file, 'r') - for token in f: - yield token + for line in f: + for token in line: + yield token + vocab = build_vocab_from_iterator(token_iterator(vocab_file)) - text_pipeline = sequential_transforms(tokenizer, vocab_func(vocab), totensor(dtype=torch.long)) + text_pipeline = sequential_transforms(tokenizer, vocab_func(vocab)) label_pipeline = totensor(dtype=torch.long) return TextClassificationPipeline(label_pipeline, text_pipeline), None, None -def build_text_vocab_pipeline(hf_vocab_file): - tokenizer = basic_english_normalize() - f = open(hf_vocab_file, 'r') - vocab = vocab_from_file(f) +def build_legacy_pytext_vocab_pipeline(vocab_file): + from pytext.data.utils import Vocabulary - # Insert token in vocab to match a pretrained vocab - pipeline = TextSequentialTransforms(tokenizer, vocab) - jit_pipeline = torch.jit.script(pipeline.to_ivalue()) - print('jit text vocab pipeline success!') - return pipeline, pipeline.to_ivalue(), jit_pipeline + tokenizer = get_tokenizer("basic_english") + with open(vocab_file, 'r') as f: + vocab_counter = Counter([token for line in f for token in line.rstrip()]) + sorted_by_freq_tuples = sorted(vocab_counter.items(), key=lambda x: x[1], reverse=True) + vocab_list = [pair[0] for pair in sorted_by_freq_tuples] + vocab_list.insert(0, "") + pipeline = sequential_transforms(tokenizer_func(tokenizer), + PyTextVocabTransform(Vocabulary(vocab_list, unk_token=""))) + return pipeline, None, None -def build_pytext_vocab_pipeline(vocab_file): +def build_legacy_pytext_script_vocab_pipeline(vocab_file): from pytext.torchscript.vocab import ScriptVocabulary + + tokenizer = basic_english_normalize() + with open(vocab_file, 'r') as f: + vocab_counter = Counter([token for line in f for token in line.rstrip()]) + sorted_by_freq_tuples = sorted(vocab_counter.items(), key=lambda x: x[1], reverse=True) + vocab_list = [pair[0] for pair in sorted_by_freq_tuples] + vocab_list.insert(0, "") + pipeline = TextSequentialTransforms(tokenizer_func(tokenizer), + PyTextScriptVocabTransform(ScriptVocabulary(vocab_list))) + jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + print('jit legacy PyText pipeline success!') + return pipeline, pipeline.to_ivalue(), jit_pipeline + + +def build_experimental_pytext_script_pipeline(vocab_file): + import os + import sys + # this is needed because we want to add 'torchtext/examples/vocab' directory to the + # `sys.path` variable in order to import the pytext_vocab (since its not a module) + sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "vocab")) + from pytext_vocab import script_vocab + tokenizer = basic_english_normalize() f = open(vocab_file, 'r') - vocab_list = [line.rstrip() for line in f] + vocab_counter = Counter([token for line in f for token in line.rstrip()]) + ordered_dict = OrderedDict(sorted(vocab_counter.items(), key=lambda x: x[1], reverse=True)) # Insert token in vocab to match a pretrained vocab pipeline = TextSequentialTransforms(tokenizer, - PyTextVocabTransform(ScriptVocabulary(vocab_list))) + PyTextScriptVocabTransform(script_vocab(ordered_dict))) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) - print('jit PyText pipeline success!') + print('jit legacy PyText pipeline success!') return pipeline, pipeline.to_ivalue(), jit_pipeline -def build_fasttext_vector_pipeline(): - tokenizer = basic_english_normalize() +def build_legacy_fasttext_vector_pipeline(): + tokenizer = get_tokenizer("basic_english") vector = FastText() - # Insert token in vocab to match a pretrained vocab + pipeline = sequential_transforms(tokenizer_func(tokenizer), vector_func(vector)) + return pipeline, None, None + + +def build_experimental_fasttext_vector_pipeline(): + tokenizer = basic_english_normalize() + vector = FastTextExperimental() + pipeline = TextSequentialTransforms(tokenizer, vector) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) - print('jit fasttext pipeline success!') + + print('jit legacy fasttext pipeline success!') return pipeline, pipeline.to_ivalue(), jit_pipeline @@ -114,7 +168,7 @@ def run_batch_benchmark_lookup(text_classification_dataset, pipeline): def generate_dataset(args): - if args.pipeline == 'batch_torchtext': + if args.pipeline == 'legacy_batch_torchtext': train = BatchTextClassificationData(args.dataset) test = None else: @@ -136,24 +190,30 @@ def generate_dataset(args): if args.pipeline == 'sentencepiece': pipeline, torchbind_pipeline, jit_pipeline = build_sp_pipeline(args.spm_filename) - elif args.pipeline == 'text_vocab': - pipeline, torchbind_pipeline, jit_pipeline = build_text_vocab_pipeline(args.vocab_filename) - elif args.pipeline == 'pytext': - pipeline, torchbind_pipeline, jit_pipeline = build_pytext_vocab_pipeline(args.vocab_filename) - elif args.pipeline == 'fasttext': - pipeline, torchbind_pipeline, jit_pipeline = build_fasttext_vector_pipeline() - elif args.pipeline == 'torchtext': - pipeline, torchbind_pipeline, jit_pipeline = build_torchtext_vocab(args.vocab_filename) - elif args.pipeline == 'batch_torchtext': - pipeline, torchbind_pipeline, jit_pipeline = build_batch_torchtext_vocab(args.vocab_filename) + elif args.pipeline == 'experimental_torchtext': + pipeline, torchbind_pipeline, jit_pipeline = build_experimental_torchtext_pipeline(args.vocab_filename) + elif args.pipeline == 'experimental_pytext_script_vocab': + pipeline, torchbind_pipeline, jit_pipeline = build_experimental_pytext_script_pipeline(args.vocab_filename) + elif args.pipeline == 'experimental_fasttext': + pipeline, torchbind_pipeline, jit_pipeline = build_experimental_fasttext_vector_pipeline() + elif args.pipeline == 'legacy_torchtext': + pipeline, torchbind_pipeline, jit_pipeline = build_legacy_torchtext_vocab_pipeline(args.vocab_filename) + elif args.pipeline == 'legacy_pytext_vocab': + pipeline, torchbind_pipeline, jit_pipeline = build_legacy_pytext_vocab_pipeline(args.vocab_filename) + elif args.pipeline == 'legacy_pytext_script_vocab': + pipeline, torchbind_pipeline, jit_pipeline = build_legacy_pytext_script_vocab_pipeline(args.vocab_filename) + elif args.pipeline == 'legacy_fasttext': + pipeline, torchbind_pipeline, jit_pipeline = build_legacy_fasttext_vector_pipeline() + elif args.pipeline == 'legacy_batch_torchtext': + pipeline, torchbind_pipeline, jit_pipeline = build_legacy_batch_torchtext_vocab_pipeline(args.vocab_filename) else: - print("pipeline is not supported. Current pipelines include sentencepiece, text_vocab, " + - "fasttext, pytext, fasttext, torchtext, batch_torchtext") + print("pipeline is not supported. Current pipelines include sentencepiece, experimental_torchtext, " + + "experimental_fasttext, legacy_pytext, experimental_fasttext, legacy_torchtext, legacy_batch_torchtext") if pipeline is not None: print("Test eager mode for pipeline with pybind", args.pipeline) train, test = generate_dataset(args) - if args.pipeline == 'batch_torchtext': + if args.pipeline == 'legacy_batch_torchtext': run_batch_benchmark_lookup(train, pipeline) else: run_benchmark_lookup(train, pipeline) @@ -161,7 +221,7 @@ def generate_dataset(args): if torchbind_pipeline is not None: print("Test eager mode for pipeline with torchbind", args.pipeline) train, test = generate_dataset(args) - if args.pipeline == 'batch_torchtext': + if args.pipeline == 'legacy_batch_torchtext': run_batch_benchmark_lookup(train, torchbind_pipeline) else: run_benchmark_lookup(train, torchbind_pipeline) diff --git a/examples/data_pipeline/transforms.py b/examples/data_pipeline/transforms.py index 50a0225342..867153353d 100644 --- a/examples/data_pipeline/transforms.py +++ b/examples/data_pipeline/transforms.py @@ -54,7 +54,7 @@ def to_ivalue(self): class PyTextVocabTransform(nn.Module): - r"""Vocab transform + r"""PyTextVocabTransform transform """ def __init__(self, vocab): @@ -62,15 +62,25 @@ def __init__(self, vocab): self.vocab = vocab def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: - ids: List[List[int]] = [] - for tokens in tokens_list: - ids.append(self.vocab.lookup_indices_1d(tokens)) + ids: List[List[int]] = self.vocab.lookup_all(tokens_list) return ids + +class PyTextScriptVocabTransform(nn.Module): + r"""PyTextScriptVocabTransform transform + """ + + def __init__(self, vocab): + super(PyTextScriptVocabTransform, self).__init__() + self.vocab = vocab + + def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: + return self.vocab.lookup_indices_2d(tokens_list) + def to_ivalue(self): if hasattr(self.vocab, 'to_ivalue'): vocab = self.vocab.to_ivalue() - return PyTextVocabTransform(vocab) + return PyTextScriptVocabTransform(vocab) return self @@ -91,6 +101,27 @@ def func(data_batch): return func +def vocab_func(vocab): + def func(tokens_list_iter): + return [vocab[tok] for tokens_list in tokens_list_iter for tok in tokens_list] + + return func + + +def vector_func(vector): + def func(tokens_list_iter): + return [vector.get_vecs_by_tokens(tokens_list) for tokens_list in tokens_list_iter] + + return func + + +def tokenizer_func(tokenizer): + def func(lines): + return [tokenizer(line) for line in lines] + + return func + + class TextClassificationPipeline(nn.Module): r"""Text classification pipeline template """ diff --git a/examples/vocab/pytext_vocab.py b/examples/vocab/pytext_vocab.py index 9050696dc9..d20d652b74 100644 --- a/examples/vocab/pytext_vocab.py +++ b/examples/vocab/pytext_vocab.py @@ -2,7 +2,7 @@ from fairseq.data.dictionary import Dictionary import torch -from torchtext.experimental.vocab import Vocab +from torchtext.experimental.vocab import vocab, Vocab from typing import Dict, List, Optional @@ -63,6 +63,17 @@ def build_fairseq_vocab( return Vocab(dictionary_items, unk_token=unk_replacement) +def script_vocab(ordered_dict, + pad_token=None, + bos_token=None, + eos_token=None, + mask_token=None, + **kwargs): + + v = vocab(ordered_dict, **kwargs) + return ScriptVocab(v.vocab, pad_token, bos_token, eos_token, mask_token, **kwargs) + + class ScriptVocab(Vocab): r"""Creates a script vocab object which maps tokens to indices. @@ -82,14 +93,21 @@ class ScriptVocab(Vocab): >>> print(v.unk_idx, v.pad_idx, v.bos_idx, v.eos_idx, v.mask_idx) """ def __init__(self, - ordered_dict, + cpp_vocab, pad_token=None, bos_token=None, eos_token=None, mask_token=None, **kwargs): - super(ScriptVocab, self).__init__(ordered_dict, **kwargs) + + super(ScriptVocab, self).__init__(cpp_vocab) + + # store all tokens self.unk_token: str = kwargs.get('unk_token', '') + self.pad_token: str = pad_token + self.bos_token: str = bos_token + self.eos_token: str = eos_token + self.mask_token: str = mask_token # init all special token indices self.unk_idx: int = self.vocab[self.unk_token] @@ -180,3 +198,10 @@ def lookup_words_1d_cycle_heuristic( result.append(unk_value) unk_idx += 1 return result + + def to_ivalue(self): + r"""Return a JITable ScriptVocab. + """ + cpp_vocab = torch.classes.torchtext.Vocab(self.vocab.itos_, self.vocab.unk_token_) + return ScriptVocab(cpp_vocab, self.pad_token, self.bos_token, self.eos_token, + self.mask_token, unk_token=self.unk_token) diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py index 7e8b29c8b6..84c22f269f 100644 --- a/test/experimental/test_transforms.py +++ b/test/experimental/test_transforms.py @@ -19,10 +19,10 @@ def test_vocab_transform(self): with open(asset_path, 'r') as f: vocab_transform = VocabTransform(vocab_from_file(f)) self.assertEqual(vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), - [[21, 26, 20], [21, 26, 20, 26]]) + [[7, 18, 24], [7, 18, 24, 18]]) jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) self.assertEqual(jit_vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), - [[21, 26, 20], [21, 26, 20, 26]]) + [[7, 18, 24], [7, 18, 24, 18]]) def test_vector_transform(self): asset_name = 'wiki.en.vec' diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 1201587aeb..826807947b 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -7,11 +7,11 @@ from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase -# from torchtext.experimental.transforms import basic_english_normalize +from torchtext.experimental.transforms import basic_english_normalize from torchtext.experimental.vocab import ( vocab, vocab_from_file, - # vocab_from_raw_text_file + vocab_from_raw_text_file ) @@ -215,28 +215,22 @@ def test_vocab_from_file(self): asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: v = vocab_from_file(f, unk_token='') - - expected_itos = ['', 'a', 'b', 'c'] + expected_itos = ['', 'b', 'a', 'c'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) - # TODO: Update cpp function to use a list of strings from the JITed tokenizer - # def test_vocab_from_raw_text_file(self): - # asset_name = 'vocab_raw_text_test.txt' - # asset_path = get_asset_path(asset_name) - # f = open(asset_path, 'r') - - # tokenizer = basic_english_normalize() - # jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) - # v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') - - # expected_itos = ['', 'after', 'talks', "'", 'newall', '.', 'mogul', 'federal', - # 'firm', 'parent', 'stricken', 'with', 'disappointed', 'are', 'they', - # 'say', 'fears', 'turner', 'at', 'workers', 'representing', 'unions', - # 'pension', 'n', 't', 'for'] - # expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - # self.assertEqual(v.get_itos(), expected_itos) - # self.assertEqual(dict(v.get_stoi()), expected_stoi) + def test_vocab_from_raw_text_file(self): + asset_name = 'vocab_raw_text_test.txt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'r') as f: + tokenizer = basic_english_normalize() + jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') + expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', + 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', + 'pension', 'representing', 'say', 'stricken', 't', 'they', 'turner', + 'unions', 'with', 'workers'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 200c217e5c..49b1c6c3f4 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -179,8 +179,13 @@ void parse_raw_text_file_chunk(const std::string &file_path, size_t offset, std::string line; for (int64_t i = start_line; i < end_line; i++) { std::getline(fin, line); + + auto line_list_ivalue = c10::IValue(std::vector({line})); auto token_list = - module.forward(std::vector({c10::IValue(line)})).toList(); + module.forward(std::vector({line_list_ivalue})) + .toList() + .get(0) + .toList(); for (size_t i = 0; i < token_list.size(); i++) { c10::IValue token_ref = token_list.get(i); @@ -209,7 +214,7 @@ struct CompareTokens { std::tuple _concat_tokens(std::vector> chunk_counters, const std::string &unk_token, const int64_t min_freq, - const int64_t num_lines) { + const int64_t num_lines, const bool sort_tokens) { TORCH_CHECK(chunk_counters.size() > 0, "There must be at least 1 chunk to concatenate!"); @@ -244,8 +249,10 @@ _concat_tokens(std::vector> chunk_counters, } // sort tokens by freq - CompareTokens compare_tokens; - std::sort(token_freq_pairs.begin(), token_freq_pairs.end(), compare_tokens); + if (sort_tokens) { + CompareTokens compare_tokens; + std::sort(token_freq_pairs.begin(), token_freq_pairs.end(), compare_tokens); + } // update unique tokens with correct order unique_tokens.clear(); @@ -321,7 +328,7 @@ Vocab _load_vocab_from_file(const std::string &file_path, IndexDict stoi; StringList tokens; std::tie(stoi, tokens) = - _concat_tokens(chunk_counters, unk_token, min_freq, num_lines); + _concat_tokens(chunk_counters, unk_token, min_freq, num_lines, false); int64_t unk_index = stoi.find(unk_token)->second; @@ -373,7 +380,7 @@ Vocab _load_vocab_from_raw_text_file(const std::string &file_path, IndexDict stoi; StringList tokens; std::tie(stoi, tokens) = - _concat_tokens(chunk_counters, unk_token, min_freq, num_lines); + _concat_tokens(chunk_counters, unk_token, min_freq, num_lines, true); int64_t unk_index = stoi.find(unk_token)->second; return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index 5954b3721c..d7261bd27d 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -209,8 +209,8 @@ def forward(self, tokens_list: List[List[str]]) -> List[Tensor]: tokens: a list of string token list Returns: - vectors (List[Tensor]): returns a list of a 2-D tensor of shape=(len(tokens), vector_dim) or - an empty tensor if `tokens` is empty + vectors (List[Tensor]): returns a list of a 2-D tensor of shape=(len(tokens), vector_dim) or an + empty tensor if `tokens` is empty """ vectors: List[Tensor] = [] for tokens in tokens_list: From 8c374dd5228dfc95f827b1add13e51245a384392 Mon Sep 17 00:00:00 2001 From: Meghan Lele Date: Mon, 14 Sep 2020 18:41:17 -0700 Subject: [PATCH 25/68] Add property support for ScriptModules (#42390) Summary: Pull Request resolved: https://github.com/pytorch/pytorch/pull/42390 **Summary** This commit extends support for properties to include ScriptModules. **Test Plan** This commit adds a unit test that has a ScriptModule with a user-defined property. `python test/test_jit_py3.py TestScriptPy3.test_module_properties` Test Plan: Imported from OSS Reviewed By: eellison, mannatsingh Differential Revision: D22880298 Pulled By: SplitInfinity fbshipit-source-id: 74f6cb80f716084339e2151ca25092b6341a1560 --- torchtext/experimental/transforms.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 5b60f362b5..59704f3ac4 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -81,6 +81,8 @@ def regex_tokenizer(patterns_list): class BasicEnglishNormalize(nn.Module): + __ignored_properties__ = ['is_jitable'] + r"""Basic normalization for a string sentence. Args: @@ -115,6 +117,8 @@ def to_ivalue(self): class RegexTokenizer(nn.Module): + __ignored_properties__ = ['is_jitable'] + r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. Args: From 2ac6d798f717a027bfe70f077a016470e5b32e9b Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Fri, 25 Sep 2020 12:41:39 -0700 Subject: [PATCH 26/68] sync with OSS torchtext 9/15/20 Reviewed By: cpuhrsch Differential Revision: D23721167 fbshipit-source-id: 13b32091c422a3ed0ae299595d69a7afa7136638 --- examples/BERT/qa_task.py | 24 +-- packaging/pkg_helpers.bash | 2 +- test/data/test_builtin_datasets.py | 26 ++-- test/experimental/__init__.py | 0 test/experimental/test_transforms.py | 15 +- .../test_transforms_with_asset.py | 145 ++++++++++++++++++ test/experimental/test_vectors.py | 94 +----------- test/experimental/test_vocab.py | 27 ---- .../experimental/datasets/question_answer.py | 35 ++--- .../datasets/raw/question_answer.py | 15 +- torchtext/experimental/transforms.py | 6 +- torchtext/experimental/vectors.py | 1 + torchtext/experimental/vocab.py | 1 + 13 files changed, 201 insertions(+), 190 deletions(-) create mode 100644 test/experimental/__init__.py create mode 100644 test/experimental/test_transforms_with_asset.py diff --git a/examples/BERT/qa_task.py b/examples/BERT/qa_task.py index a92f67be05..c9d4dd77a4 100644 --- a/examples/BERT/qa_task.py +++ b/examples/BERT/qa_task.py @@ -14,13 +14,13 @@ def process_raw_data(data): _data = [] - for item in data: + for (_context, _question, _answers, _ans_pos) in data: right_length = True - for _idx in range(len(item['ans_pos'])): - if item['ans_pos'][_idx][1] + item['question'].size(0) + 2 >= args.bptt: + for _idx in range(len(_ans_pos)): + if _ans_pos[_idx][1] + _question.size(0) + 2 >= args.bptt: right_length = False if right_length: - _data.append(item) + _data.append((_context, _question, _answers, _ans_pos)) return _data @@ -28,9 +28,9 @@ def collate_batch(batch): seq_list = [] ans_pos_list = [] tok_type = [] - for item in batch: - qa_item = torch.cat((torch.tensor([cls_id]), item['question'], torch.tensor([sep_id]), - item['context'], torch.tensor([sep_id]))) + for (_context, _question, _answers, _ans_pos) in batch: + qa_item = torch.cat((torch.tensor([cls_id]), _question, torch.tensor([sep_id]), + _context, torch.tensor([sep_id]))) if qa_item.size(0) > args.bptt: qa_item = qa_item[:args.bptt] elif qa_item.size(0) < args.bptt: @@ -38,11 +38,11 @@ def collate_batch(batch): torch.tensor([pad_id] * (args.bptt - qa_item.size(0))))) seq_list.append(qa_item) - pos_list = [pos + item['question'].size(0) + 2 for pos in item['ans_pos']] # 1 for sep and 1 for cls + pos_list = [pos + _question.size(0) + 2 for pos in _ans_pos] # 1 for sep and 1 for cls ans_pos_list.append(pos_list) - tok_type.append(torch.cat((torch.zeros((item['question'].size(0) + 2)), + tok_type.append(torch.cat((torch.zeros((_question.size(0) + 2)), torch.ones((args.bptt - - item['question'].size(0) - 2))))) + _question.size(0) - 2))))) _ans_pos_list = [] for pos in zip(*ans_pos_list): _ans_pos_list.append(torch.stack(list(pos))) @@ -97,10 +97,10 @@ def train(): dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, collate_fn=collate_batch) train_loss_log.append(0.0) - for idx, (seq_input, ans_pos, tok_type) in enumerate(dataloader): + for idx, (seq_input, _ans_pos, tok_type) in enumerate(dataloader): optimizer.zero_grad() start_pos, end_pos = model(seq_input, token_type_input=tok_type) - target_start_pos, target_end_pos = ans_pos[0].to(device).split(1, dim=-1) + target_start_pos, target_end_pos = _ans_pos[0].to(device).split(1, dim=-1) target_start_pos = target_start_pos.squeeze(-1) target_end_pos = target_end_pos.squeeze(-1) loss = (criterion(start_pos, target_start_pos) + criterion(end_pos, target_end_pos)) / 2 diff --git a/packaging/pkg_helpers.bash b/packaging/pkg_helpers.bash index 6f43f8e025..b7254c19c3 100644 --- a/packaging/pkg_helpers.bash +++ b/packaging/pkg_helpers.bash @@ -34,7 +34,7 @@ setup_cuda() { # First, compute version suffixes. By default, assume no version suffixes export VERSION_SUFFIX="" export PYTORCH_VERSION_SUFFIX="" - export WHEEL_DIR="" + export WHEEL_DIR="cpu/" # Wheel builds need suffixes (but not if they're on OS X, which never has suffix) if [[ "$BUILD_TYPE" == "wheel" ]] && [[ "$(uname)" != Darwin ]]; then # The default CUDA has no suffix diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 1c120da16c..126680fb3b 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -265,14 +265,13 @@ def test_squad1(self): train_dataset, dev_dataset = SQuAD1() self.assertEqual(len(train_dataset), 87599) self.assertEqual(len(dev_dataset), 10570) - self.assertEqual(train_dataset[100]['question'], + context, question, answers, ans_pos = train_dataset[100] + self.assertEqual(question, torch.tensor([7, 24, 86, 52, 2, 373, 887, 18, 12797, 11090, 1356, 2, 1788, 3273, 16]).long()) - self.assertEqual(train_dataset[100]['ans_pos'][0], - torch.tensor([72, 72]).long()) - self.assertEqual(dev_dataset[100]['question'], - torch.tensor([42, 27, 669, 7438, 17, 2, 1950, 3273, 17252, 389, 16]).long()) - self.assertEqual(dev_dataset[100]['ans_pos'][0], - torch.tensor([45, 48]).long()) + self.assertEqual(ans_pos[0], torch.tensor([72, 72]).long()) + context, question, answers, ans_pos = dev_dataset[100] + self.assertEqual(question, torch.tensor([42, 27, 669, 7438, 17, 2, 1950, 3273, 17252, 389, 16]).long()) + self.assertEqual(ans_pos[0], torch.tensor([45, 48]).long()) # Test API with a vocab input object old_vocab = train_dataset.get_vocab() @@ -286,14 +285,13 @@ def test_squad2(self): train_dataset, dev_dataset = SQuAD2() self.assertEqual(len(train_dataset), 130319) self.assertEqual(len(dev_dataset), 11873) - self.assertEqual(train_dataset[200]['question'], + context, question, answers, ans_pos = train_dataset[200] + self.assertEqual(question, torch.tensor([84, 50, 1421, 12, 5439, 4569, 17, 30, 2, 15202, 4754, 1421, 16]).long()) - self.assertEqual(train_dataset[200]['ans_pos'][0], - torch.tensor([9, 9]).long()) - self.assertEqual(dev_dataset[200]['question'], - torch.tensor([41, 29, 2, 66, 17016, 30, 0, 1955, 16]).long()) - self.assertEqual(dev_dataset[200]['ans_pos'][0], - torch.tensor([40, 46]).long()) + self.assertEqual(ans_pos[0], torch.tensor([9, 9]).long()) + context, question, answers, ans_pos = dev_dataset[200] + self.assertEqual(question, torch.tensor([41, 29, 2, 66, 17016, 30, 0, 1955, 16]).long()) + self.assertEqual(ans_pos[0], torch.tensor([40, 46]).long()) # Test API with a vocab input object old_vocab = train_dataset.get_vocab() diff --git a/test/experimental/__init__.py b/test/experimental/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py index 84c22f269f..87b17038d4 100644 --- a/test/experimental/test_transforms.py +++ b/test/experimental/test_transforms.py @@ -1,11 +1,9 @@ import torch from test.common.torchtext_test_case import TorchtextTestCase -from test.common.assets import get_asset_path +from ..common.assets import get_asset_path from torchtext.experimental.transforms import ( VectorTransform, - VocabTransform, ) -from torchtext.experimental.vocab import vocab_from_file from torchtext.experimental.vectors import FastText import shutil import tempfile @@ -13,17 +11,6 @@ class TestTransforms(TorchtextTestCase): - def test_vocab_transform(self): - asset_name = 'vocab_test2.txt' - asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: - vocab_transform = VocabTransform(vocab_from_file(f)) - self.assertEqual(vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), - [[7, 18, 24], [7, 18, 24, 18]]) - jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) - self.assertEqual(jit_vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), - [[7, 18, 24], [7, 18, 24, 18]]) - def test_vector_transform(self): asset_name = 'wiki.en.vec' asset_path = get_asset_path(asset_name) diff --git a/test/experimental/test_transforms_with_asset.py b/test/experimental/test_transforms_with_asset.py new file mode 100644 index 0000000000..b22d031a58 --- /dev/null +++ b/test/experimental/test_transforms_with_asset.py @@ -0,0 +1,145 @@ +import torch +from test.common.torchtext_test_case import TorchtextTestCase +from ..common.assets import get_asset_path +from torchtext.experimental.transforms import ( + VocabTransform, +) +from torchtext.experimental.vocab import ( + vocab_from_file, + vocab_from_raw_text_file, +) +import shutil +import tempfile +import os +from torchtext.experimental.vectors import ( + GloVe, + vectors, +) + + +class TestTransformsWithAsset(TorchtextTestCase): + def test_vocab_transform(self): + asset_name = 'vocab_test2.txt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'r') as f: + vocab_transform = VocabTransform(vocab_from_file(f)) + self.assertEqual(vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), + [[7, 18, 24], [7, 18, 24, 18]]) + jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) + self.assertEqual(jit_vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), + [[7, 18, 24], [7, 18, 24, 18]]) + + def test_errors_vectors_python(self): + tokens = [] + vecs = torch.empty(0, dtype=torch.float) + + with self.assertRaises(ValueError): + # Test proper error raised when passing in empty tokens and vectors and + # not passing in a user defined unk_tensor + vectors(tokens, vecs) + + tensorA = torch.tensor([1, 0, 0], dtype=torch.int8) + tokens = ['a'] + vecs = tensorA.unsqueeze(0) + + with self.assertRaises(TypeError): + # Test proper error raised when vector is not of type torch.float + vectors(tokens, vecs) + + with tempfile.TemporaryDirectory() as dir_name: + # Test proper error raised when incorrect filename or dim passed into GloVe + asset_name = 'glove.6B.zip' + asset_path = get_asset_path(asset_name) + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + + with self.assertRaises(ValueError): + # incorrect name + GloVe(name='UNK', dim=50, root=dir_name, validate_file=False) + + with self.assertRaises(ValueError): + # incorrect dim + GloVe(name='6B', dim=500, root=dir_name, validate_file=False) + + def test_glove(self): + # copy the asset file into the expected download location + # note that this is just a zip file with the first 100 entries of the GloVe 840B dataset + asset_name = 'glove.840B.300d.zip' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + vectors_obj = GloVe(root=dir_name, validate_file=False) + jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + + # The first 3 entries in each vector. + expected_glove = { + 'the': [0.27204, -0.06203, -0.1884], + 'people': [-0.19686, 0.11579, -0.41091], + } + + for word in expected_glove.keys(): + self.assertEqual(vectors_obj[word][:3], expected_glove[word]) + self.assertEqual(jit_vectors_obj[word][:3], expected_glove[word]) + + def test_glove_different_dims(self): + # copy the asset file into the expected download location + # note that this is just a zip file with 1 line txt files used to test that the + # correct files are being loaded + asset_name = 'glove.6B.zip' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + + glove_50d = GloVe(name='6B', dim=50, root=dir_name, validate_file=False) + glove_100d = GloVe(name='6B', dim=100, root=dir_name, validate_file=False) + glove_200d = GloVe(name='6B', dim=200, root=dir_name, validate_file=False) + glove_300d = GloVe(name='6B', dim=300, root=dir_name, validate_file=False) + vectors_objects = [glove_50d, glove_100d, glove_200d, glove_300d] + + # The first 3 entries in each vector. + expected_glove_50d = { + 'the': [0.418, 0.24968, -0.41242], + } + expected_glove_100d = { + 'the': [-0.038194, -0.24487, 0.72812], + } + expected_glove_200d = { + 'the': [-0.071549, 0.093459, 0.023738], + } + expected_glove_300d = { + 'the': [0.04656, 0.21318, -0.0074364], + } + expected_gloves = [expected_glove_50d, expected_glove_100d, expected_glove_200d, expected_glove_300d] + + for vectors_obj, expected_glove in zip(vectors_objects, expected_gloves): + for word in expected_glove.keys(): + self.assertEqual(vectors_obj[word][:3], expected_glove[word]) + + def test_vocab_from_file(self): + asset_name = 'vocab_test.txt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'r') as f: + v = vocab_from_file(f, unk_token='') + expected_itos = ['', 'b', 'a', 'c'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + def test_vocab_from_raw_text_file(self): + asset_name = 'vocab_raw_text_test.txt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'r') as f: + tokenizer = basic_english_normalize() + jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') + expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', + 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', + 'pension', 'representing', 'say', 'stricken', 't', 'they', 'turner', + 'unions', 'with', 'workers'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 26c858cb12..69b33de094 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -5,9 +5,7 @@ import tempfile import torch import unittest - - -from test.common.assets import get_asset_path +from ..common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vectors import ( FastText, @@ -155,38 +153,6 @@ def test_errors_vectors_cpp(self): # the key of the duplicate token in the error message vectors(tokens, vecs) - def test_errors_vectors_python(self): - tokens = [] - vecs = torch.empty(0, dtype=torch.float) - - with self.assertRaises(ValueError): - # Test proper error raised when passing in empty tokens and vectors and - # not passing in a user defined unk_tensor - vectors(tokens, vecs) - - tensorA = torch.tensor([1, 0, 0], dtype=torch.int8) - tokens = ['a'] - vecs = tensorA.unsqueeze(0) - - with self.assertRaises(TypeError): - # Test proper error raised when vector is not of type torch.float - vectors(tokens, vecs) - - with tempfile.TemporaryDirectory() as dir_name: - # Test proper error raised when incorrect filename or dim passed into GloVe - asset_name = 'glove.6B.zip' - asset_path = get_asset_path(asset_name) - data_path = os.path.join(dir_name, asset_name) - shutil.copy(asset_path, data_path) - - with self.assertRaises(ValueError): - # incorrect name - GloVe(name='UNK', dim=50, root=dir_name, validate_file=False) - - with self.assertRaises(ValueError): - # incorrect dim - GloVe(name='6B', dim=500, root=dir_name, validate_file=False) - def test_vectors_from_file(self): asset_name = 'vectors_test.csv' asset_path = get_asset_path(asset_name) @@ -222,61 +188,3 @@ def test_fast_text(self): for word in expected_fasttext_simple_en.keys(): self.assertEqual(vectors_obj[word][:3], expected_fasttext_simple_en[word]) self.assertEqual(jit_vectors_obj[word][:3], expected_fasttext_simple_en[word]) - - def test_glove(self): - # copy the asset file into the expected download location - # note that this is just a zip file with the first 100 entries of the GloVe 840B dataset - asset_name = 'glove.840B.300d.zip' - asset_path = get_asset_path(asset_name) - - with tempfile.TemporaryDirectory() as dir_name: - data_path = os.path.join(dir_name, asset_name) - shutil.copy(asset_path, data_path) - vectors_obj = GloVe(root=dir_name, validate_file=False) - jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) - - # The first 3 entries in each vector. - expected_glove = { - 'the': [0.27204, -0.06203, -0.1884], - 'people': [-0.19686, 0.11579, -0.41091], - } - - for word in expected_glove.keys(): - self.assertEqual(vectors_obj[word][:3], expected_glove[word]) - self.assertEqual(jit_vectors_obj[word][:3], expected_glove[word]) - - def test_glove_different_dims(self): - # copy the asset file into the expected download location - # note that this is just a zip file with 1 line txt files used to test that the - # correct files are being loaded - asset_name = 'glove.6B.zip' - asset_path = get_asset_path(asset_name) - - with tempfile.TemporaryDirectory() as dir_name: - data_path = os.path.join(dir_name, asset_name) - shutil.copy(asset_path, data_path) - - glove_50d = GloVe(name='6B', dim=50, root=dir_name, validate_file=False) - glove_100d = GloVe(name='6B', dim=100, root=dir_name, validate_file=False) - glove_200d = GloVe(name='6B', dim=200, root=dir_name, validate_file=False) - glove_300d = GloVe(name='6B', dim=300, root=dir_name, validate_file=False) - vectors_objects = [glove_50d, glove_100d, glove_200d, glove_300d] - - # The first 3 entries in each vector. - expected_glove_50d = { - 'the': [0.418, 0.24968, -0.41242], - } - expected_glove_100d = { - 'the': [-0.038194, -0.24487, 0.72812], - } - expected_glove_200d = { - 'the': [-0.071549, 0.093459, 0.023738], - } - expected_glove_300d = { - 'the': [0.04656, 0.21318, -0.0074364], - } - expected_gloves = [expected_glove_50d, expected_glove_100d, expected_glove_200d, expected_glove_300d] - - for vectors_obj, expected_glove in zip(vectors_objects, expected_gloves): - for word in expected_glove.keys(): - self.assertEqual(vectors_obj[word][:3], expected_glove[word]) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 826807947b..977b5f5293 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -4,8 +4,6 @@ import platform import torch import unittest - -from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.transforms import basic_english_normalize from torchtext.experimental.vocab import ( @@ -209,28 +207,3 @@ def test_vocab_load_and_save(self): self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) - - def test_vocab_from_file(self): - asset_name = 'vocab_test.txt' - asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: - v = vocab_from_file(f, unk_token='') - expected_itos = ['', 'b', 'a', 'c'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) - - def test_vocab_from_raw_text_file(self): - asset_name = 'vocab_raw_text_test.txt' - asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: - tokenizer = basic_english_normalize() - jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) - v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') - expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', - 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', - 'pension', 'representing', 'say', 'stricken', 't', 'they', 'turner', - 'unions', 'with', 'workers'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index 094a252bfc..aef81d0112 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -20,9 +20,7 @@ def __init__(self, data, vocab, transforms): """Initiate question answer dataset. Arguments: - data: a dictionary of data. - For example {'context': context_data, 'answers': answers_data, - 'question': question_data, 'ans_pos': ans_pos_data} + data: a tuple of (context, question, answers, ans_pos). vocab: Vocabulary object used for dataset. transforms: a dictionary of transforms. For example {'context': context_transform, 'answers': answers_transform, @@ -35,20 +33,21 @@ def __init__(self, data, vocab, transforms): self.transforms = transforms def __getitem__(self, i): - _data = {'context': self.transforms['context'](self.data[i]['context']), - 'question': self.transforms['question'](self.data[i]['question']), - 'answers': [], 'ans_pos': []} - for idx in range(len(self.data[i]['answer_start'])): - _data['answers'].append(self.transforms['answers'](self.data[i]['answers'][idx])) - ans_start_idx = self.data[i]['answer_start'][idx] + raw_context, raw_question, raw_answers, raw_answer_start = self.data[i] + _context = self.transforms['context'](raw_context) + _question = self.transforms['question'](raw_question) + _answers, _ans_pos = [], [] + for idx in range(len(raw_answer_start)): + _answers.append(self.transforms['answers'](raw_answers[idx])) + ans_start_idx = raw_answer_start[idx] if ans_start_idx == -1: # No answer for this sample - _data['ans_pos'].append(self.transforms['ans_pos']([-1, -1])) + _ans_pos.append(self.transforms['ans_pos']([-1, -1])) else: - ans_start_token_idx = len(self.transforms['context'](self.data[i]['context'][:ans_start_idx])) + ans_start_token_idx = len(self.transforms['context'](raw_context[:ans_start_idx])) ans_end_token_idx = ans_start_token_idx + \ - len(self.transforms['answers'](self.data[i]['answers'][idx])) - 1 - _data['ans_pos'].append(self.transforms['ans_pos']([ans_start_token_idx, ans_end_token_idx])) - return _data + len(self.transforms['answers'](raw_answers[idx])) - 1 + _ans_pos.append(self.transforms['ans_pos']([ans_start_token_idx, ans_end_token_idx])) + return (_context, _question, _answers, _ans_pos) def __len__(self): return len(self.data) @@ -77,12 +76,12 @@ def _setup_datasets(dataset_name, if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") tok_list = [] - for raw_dict in raw_data['train']: + for (_context, _question, _answers, _ans_pos) in raw_data['train']: tok_ans = [] - for item in raw_dict['answers']: + for item in _answers: tok_ans += text_transform(item) - tok_list.append(text_transform(raw_dict['context']) + - text_transform(raw_dict['question']) + tok_ans) + tok_list.append(text_transform(_context) + + text_transform(_question) + tok_ans) vocab = build_vocab_from_iterator(tok_list) text_transform = sequential_transforms(text_transform, vocab_func(vocab), totensor(dtype=torch.long)) transforms = {'context': text_transform, 'question': text_transform, diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py index 528e3e9930..e0b488eff1 100644 --- a/torchtext/experimental/datasets/raw/question_answer.py +++ b/torchtext/experimental/datasets/raw/question_answer.py @@ -18,13 +18,14 @@ def _create_data_from_json(data_path): for layer1 in raw_json_data: for layer2 in layer1['paragraphs']: for layer3 in layer2['qas']: - processed = {'context': layer2['context'], 'question': layer3['question'], - 'answers': [item['text'] for item in layer3['answers']], - 'answer_start': [item['answer_start'] for item in layer3['answers']]} - if len(processed['answers']) == 0: - processed['answers'] = [""] - processed['answer_start'] = [-1] - yield processed + _context, _question = layer2['context'], layer3['question'] + _answers = [item['text'] for item in layer3['answers']] + _answer_start = [item['answer_start'] for item in layer3['answers']] + if len(_answers) == 0: + _answers = [""] + _answer_start = [-1] + # yield the raw data in the order of context, question, answers, answer_start + yield (_context, _question, _answers, _answer_start) class RawQuestionAnswerDataset(torch.utils.data.IterableDataset): diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 59704f3ac4..367a0b3bcb 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -81,8 +81,7 @@ def regex_tokenizer(patterns_list): class BasicEnglishNormalize(nn.Module): - __ignored_properties__ = ['is_jitable'] - + __ignored_properties__ = ["is_jitable"] r"""Basic normalization for a string sentence. Args: @@ -117,8 +116,7 @@ def to_ivalue(self): class RegexTokenizer(nn.Module): - __ignored_properties__ = ['is_jitable'] - + __ignored_properties__ = ["is_jitable"] r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. Args: diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index d7261bd27d..88edb31ca8 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -189,6 +189,7 @@ def vectors(tokens, vectors, unk_tensor=None): class Vectors(nn.Module): + __ignored_properties__ = ["is_jitable"] r"""Creates a vectors object which maps tokens to vectors. Args: vectors (torch.classes.torchtext.Vectors or torchtext._torchtext.Vectors): a cpp vectors object. diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index a3e97778dd..3d0b58f292 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -113,6 +113,7 @@ def vocab(ordered_dict, min_freq=1, unk_token=''): class Vocab(nn.Module): + __ignored_properties__ = ["is_jitable"] r"""Creates a vocab object which maps tokens to indices. Arguments: From 84174db59d4931bd4c5c0dfe45a2dc44119df21f Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Mon, 28 Sep 2020 13:23:21 -0700 Subject: [PATCH 27/68] Import Github torchtext on 9/28/2020 Reviewed By: cpuhrsch Differential Revision: D23962265 fbshipit-source-id: 0d042878fe9119aa725e982ab7d5e96e7c885a59 --- benchmark/benchmark_sentencepiece.py | 49 ++++ benchmark/data_construction.py | 17 ++ docs/source/experimental_transforms.rst | 40 ++- docs/source/index.rst | 1 + examples/BERT/qa_task.py | 24 +- examples/data_pipeline/README.md | 45 ++-- examples/data_pipeline/pipelines.py | 43 ++-- examples/data_pipeline/transforms.py | 28 +-- examples/text_classification/run_script.sh | 2 + examples/text_classification/spm_dataset.py | 28 +-- test/data/test_builtin_datasets.py | 4 +- test/data/test_functional.py | 22 +- test/experimental/test_transforms.py | 38 ++- .../test_transforms_with_asset.py | 93 ++++++- test/experimental/test_vectors.py | 64 +---- test/experimental/test_vocab.py | 4 +- torchtext/csrc/register_bindings.cpp | 8 + torchtext/csrc/sentencepiece.cpp | 10 + torchtext/csrc/sentencepiece.h | 4 +- torchtext/csrc/vocab.cpp | 7 +- torchtext/data/functional.py | 7 +- torchtext/experimental/__init__.py | 3 +- torchtext/experimental/datasets/__init__.py | 42 ++-- .../datasets/language_modeling.py | 49 ++-- .../experimental/datasets/question_answer.py | 16 +- .../experimental/datasets/raw/__init__.py | 41 +-- .../experimental/datasets/sequence_tagging.py | 10 +- .../datasets/text_classification.py | 12 +- .../experimental/datasets/translation.py | 22 +- torchtext/experimental/functional.py | 7 + torchtext/experimental/transforms.py | 237 +++++++++++++++--- torchtext/experimental/vectors.py | 19 +- torchtext/experimental/vocab.py | 17 +- 33 files changed, 667 insertions(+), 346 deletions(-) create mode 100644 benchmark/benchmark_sentencepiece.py create mode 100644 benchmark/data_construction.py diff --git a/benchmark/benchmark_sentencepiece.py b/benchmark/benchmark_sentencepiece.py new file mode 100644 index 0000000000..bbf1f47c81 --- /dev/null +++ b/benchmark/benchmark_sentencepiece.py @@ -0,0 +1,49 @@ +import time +import argparse +from torchtext.experimental.transforms import load_sp_model as load_pybind_sp_model +from torchtext.data.functional import load_sp_model as load_torchbind_sp_model +from torchtext.utils import download_from_url +from torchtext.experimental.datasets.raw import text_classification as raw + + +def benchmark_sentencepiece(args): + def _run_benchmark(train, spm_processor): + t0 = time.monotonic() + for (_, text) in train: + spm_processor(text) + print("Sentencepiece processor time:", time.monotonic() - t0) + + # Download a pretrained sentencepiece model + sp_model_path = download_from_url('https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_15000.model') + + # existing sentencepiece model with torchbind + train, _ = raw.DATASETS[args.dataset]() + sp_model = load_torchbind_sp_model(sp_model_path) + print("SentencePiece EncodeAsIds - torchbind") + _run_benchmark(train, sp_model.EncodeAsIds) + + # experimental sentencepiece model with pybind + train, _ = raw.DATASETS[args.dataset]() + sp_model = load_pybind_sp_model(sp_model_path) + print("SentencePiece EncodeAsIds - pybind") + _run_benchmark(train, sp_model.EncodeAsIds) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='SentencePiece benchmark') + parser.add_argument('--dataset', type=str, default='AG_NEWS', + help='Dataset for performance benchmark') + args = parser.parse_args() + benchmark_sentencepiece(args) + +# Running with AG_NEWS +# SentencePiece EncodeAsIds - torchbind +# Sentencepiece processor time: 11.536989663727582 +# SentencePiece EncodeAsIds - pybind +# Sentencepiece processor time: 11.38821320142597 + +# Running with YelpReviewFull +# SentencePiece EncodeAsIds - torchbind +# Sentencepiece processor time: 224.23954573180526 +# SentencePiece EncodeAsIds - pybind +# Sentencepiece processor time: 217.134037473239 diff --git a/benchmark/data_construction.py b/benchmark/data_construction.py new file mode 100644 index 0000000000..46e3462805 --- /dev/null +++ b/benchmark/data_construction.py @@ -0,0 +1,17 @@ +import torch +from torchtext.experimental import datasets +import torch.utils._benchmark as benchmark_utils +import time + + +def benchmark_construction(name, Dataset): + t0 = time.perf_counter() + print(name, end='') + d, = Dataset(data_select=('train',)) + print(" construction time {0:.2f}s".format(time.perf_counter() - t0)) + del d + + +if __name__ == "__main__": + for name, Dataset in datasets.DATASETS.items(): + benchmark_construction(name, Dataset) diff --git a/docs/source/experimental_transforms.rst b/docs/source/experimental_transforms.rst index b8fce62dd0..f134a29048 100644 --- a/docs/source/experimental_transforms.rst +++ b/docs/source/experimental_transforms.rst @@ -21,7 +21,6 @@ torchtext.experimental.transforms :members: :special-members: __init__ - :hidden:`TextSequentialTransforms` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -29,15 +28,50 @@ torchtext.experimental.transforms :members: :special-members: __init__ -:hidden:`VocabTransform` +:hidden:`load_sp_model` +~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: load_sp_model + :members: + :special-members: __init__ + +:hidden: `sentencepiece_tokenizer` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. autoclass:: sentencepiece_tokenizer + :members: + :special-members: __init__ + +:hidden:`SentencePieceTokenizer` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: SentencePieceTokenizer + :members: + :special-members: __init__ + +:hidden: `sentencepiece_processor` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: sentencepiece_processor + :members: + :special-members: __init__ + +:hidden:`SentencePieceProcessor` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: SentencePieceProcessor + :members: + :special-members: __init__ + +:hidden:`VocabTransform` +~~~~~~~~~~~~~~~~~~~~~~~ + .. autoclass:: VocabTransform :members: :special-members: __init__ :hidden:`VectorTransform` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: VectorTransform :members: diff --git a/docs/source/index.rst b/docs/source/index.rst index e1ce8cfd27..a75692252e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,6 +10,7 @@ popular datasets for natural language. self torchtext.data + modules data_utils data_functional data_metrics diff --git a/examples/BERT/qa_task.py b/examples/BERT/qa_task.py index c9d4dd77a4..72595c101d 100644 --- a/examples/BERT/qa_task.py +++ b/examples/BERT/qa_task.py @@ -14,13 +14,13 @@ def process_raw_data(data): _data = [] - for (_context, _question, _answers, _ans_pos) in data: + for (context, question, answers, ans_pos) in data: right_length = True - for _idx in range(len(_ans_pos)): - if _ans_pos[_idx][1] + _question.size(0) + 2 >= args.bptt: + for _idx in range(len(ans_pos)): + if ans_pos[_idx][1] + question.size(0) + 2 >= args.bptt: right_length = False if right_length: - _data.append((_context, _question, _answers, _ans_pos)) + _data.append((context, question, answers, ans_pos)) return _data @@ -28,9 +28,9 @@ def collate_batch(batch): seq_list = [] ans_pos_list = [] tok_type = [] - for (_context, _question, _answers, _ans_pos) in batch: - qa_item = torch.cat((torch.tensor([cls_id]), _question, torch.tensor([sep_id]), - _context, torch.tensor([sep_id]))) + for (context, question, answers, ans_pos) in batch: + qa_item = torch.cat((torch.tensor([cls_id]), question, torch.tensor([sep_id]), + context, torch.tensor([sep_id]))) if qa_item.size(0) > args.bptt: qa_item = qa_item[:args.bptt] elif qa_item.size(0) < args.bptt: @@ -38,11 +38,11 @@ def collate_batch(batch): torch.tensor([pad_id] * (args.bptt - qa_item.size(0))))) seq_list.append(qa_item) - pos_list = [pos + _question.size(0) + 2 for pos in _ans_pos] # 1 for sep and 1 for cls + pos_list = [pos + question.size(0) + 2 for pos in ans_pos] # 1 for sep and 1 for cls ans_pos_list.append(pos_list) - tok_type.append(torch.cat((torch.zeros((_question.size(0) + 2)), + tok_type.append(torch.cat((torch.zeros((question.size(0) + 2)), torch.ones((args.bptt - - _question.size(0) - 2))))) + question.size(0) - 2))))) _ans_pos_list = [] for pos in zip(*ans_pos_list): _ans_pos_list.append(torch.stack(list(pos))) @@ -97,10 +97,10 @@ def train(): dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, collate_fn=collate_batch) train_loss_log.append(0.0) - for idx, (seq_input, _ans_pos, tok_type) in enumerate(dataloader): + for idx, (seq_input, ans_pos, tok_type) in enumerate(dataloader): optimizer.zero_grad() start_pos, end_pos = model(seq_input, token_type_input=tok_type) - target_start_pos, target_end_pos = _ans_pos[0].to(device).split(1, dim=-1) + target_start_pos, target_end_pos = ans_pos[0].to(device).split(1, dim=-1) target_start_pos = target_start_pos.squeeze(-1) target_end_pos = target_end_pos.squeeze(-1) loss = (criterion(start_pos, target_start_pos) + criterion(end_pos, target_end_pos)) / 2 diff --git a/examples/data_pipeline/README.md b/examples/data_pipeline/README.md index 34418be5d4..8ebbccc752 100644 --- a/examples/data_pipeline/README.md +++ b/examples/data_pipeline/README.md @@ -9,16 +9,11 @@ This pipeline example shows the application with a pretrained sentencepiece mode * `PretrainedSPTokenizer` * `PretrainedSPVocab` backed by `torchtext.experimental.vocab.Vocab` -* `ToLongTensor` to convert a list of integers to `torch.tensor` The command to run the pipeline: python pipelines.py --pipeline sentencepiece -The lookup time: 30.770548372063786 (eager mode with pybind) -The lookup time: 34.36592311505228 (eager mode with torchbind) -The lookup time: 23.43273439211771 (jit mode) - ## Legacy Torchtext @@ -26,14 +21,11 @@ This pipeline example shows the application with the existing `Vocab` in torchte * `basic_english` func from `torchtext.data.utils.get_tokenizer` * `torchtext.vocab.Vocab` -* `torchtext.experimental.functional.totensor` to convert a list of integers to `torch.tensor` The command to run the pipeline: python pipelines.py --pipeline torchtext -The lookup time: 8.690132656134665 (eager mode) - ## Experimental Torchtext @@ -41,16 +33,11 @@ This pipeline example shows the application with the vocab text file from Huggin * `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library * `torchtext.experimental.vocab.Vocab` -* `ToLongTensor` to convert a list of integers to `torch.tensor` The command to run the pipeline: python pipelines.py --pipeline text_vocab -The lookup time: 10.21763815311715 (eager mode with pybind) -The lookup time: 17.28485624492168 (eager mode with torchbind) -The lookup time: 10.25370063772425 (jit mode) - ## Legacy PyText @@ -58,16 +45,11 @@ This pipeline example shows the application with the existing `ScriptVocab` in p * `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library * `from pytext.torchscript.vocab.ScriptVocabulary` -* `ToLongTensor` to convert a list of integers to `torch.tensor` With the dependency of `pytext` library, the command to run the pipeline: python pipelines.py --pipeline pytext -The lookup time: 18.07144843228161 (eager mode with pybind) -The lookup time: 22.16066740499809 (eager mode with torchbind) -The lookup time: 13.41519635310396 (jit mode) - ## Experimental PyText @@ -75,16 +57,11 @@ This pipeline example shows the application with a `ScriptVocab` based on the to * `torchtext.experimental.transforms.BasicEnglishNormalize` backed by `re2` regular expression library * `from pytext.torchscript.vocab.ScriptVocabulary` -* `ToLongTensor` to convert a list of integers to `torch.tensor` With the dependency of `pytext` library, the command to run the pipeline: python pipelines.py --pipeline pytext -The lookup time: 11.004039663821459 (eager mode with pybind) -The lookup time: 17.025434703100473 (eager mode with torchbind) -The lookup time: 10.078087331261486 (jit mode) - ## Legacy Torchtext with a batch of data @@ -94,7 +71,6 @@ For the text pipeline: * `basic_english` func from `torchtext.data.utils.get_tokenizer` * `torchtext.vocab.Vocab` -* `torchtext.experimental.functional.totensor` to convert a list of integers to `torch.tensor` For the label pipeline: @@ -106,8 +82,6 @@ The command to run the pipeline: python pipelines.py --pipeline batch_torchtext -The lookup time: 10.05315054487437 (eager mode) - ## Legacy FastText pretrained word vectors @@ -120,8 +94,6 @@ The command to run the pipeline: python pipelines.py --pipeline fasttext -The lookup time: 34.08170719863847 (eager mode) - ## Experimental FastText pretrained word vectors @@ -134,6 +106,17 @@ The command to run the pipeline: python pipelines.py --pipeline fasttext -The lookup time: 16.45024944096803 (eager mode with pybind) -The lookup time: 23.96459424262866 (eager mode with torchbind) -The lookup time: 19.34995342604816 (jit mode) +Here are the time in seconds for the pipelines above: + +Pipelines | Eager Mode with Pybind | Eager Mode with Torchbind | JIT Mode +------------ | ------------- | ------------- | ------------- +SentencePiece | 19.555 | 22.798 | 17.579 +Legacy Torchtext | 11.677 | N/A | N/A +Experimental Torchtext | 4.793 | 9.745 | 6.459 +Legacy PyText | 10.168 | 12.636 | 8.425 +Experimental PyText | 5.192 | 10.555 | 6.272 +Legacy Torchtext with a batch of data | 5.192 | N/A | N/A +Legacy FastText pretrained word vectors | 22.947 | N/A | N/A +Experimental FastText pretrained word vectors | 11.949 | 18.100 | 14.058 + +Please note that these numbers are for our development reference only. diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index 466137eada..10818da8b2 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -1,18 +1,17 @@ from collections import Counter, OrderedDict import torch from transforms import ( - PretrainedSPTokenizer, PretrainedSPVocab, PyTextVocabTransform, PyTextScriptVocabTransform, - iterate_batch, tokenizer_func, - totensor, vocab_func, ) from torchtext.experimental.transforms import ( basic_english_normalize, TextSequentialTransforms, + sentencepiece_tokenizer, + load_sp_model, ) from torchtext.data.utils import get_tokenizer from torchtext.experimental.functional import ( @@ -25,12 +24,11 @@ import argparse from torchtext.experimental.datasets.raw import text_classification as raw import time -from dataset import BatchTextClassificationData -from torchtext.data.functional import load_sp_model +from torch.utils.data import DataLoader def build_sp_pipeline(spm_file): - tokenizer = PretrainedSPTokenizer(load_sp_model(spm_file)) + tokenizer = sentencepiece_tokenizer(spm_file) vocab = PretrainedSPVocab(load_sp_model(spm_file)) # Insert token in vocab to match a pretrained vocab @@ -52,8 +50,8 @@ def token_iterator(vocab_file): yield token vocab = build_vocab_from_iterator(token_iterator(vocab_file)) - pipeline = sequential_transforms(tokenizer_func(tokenizer), vocab_func(vocab)) - return iterate_batch(pipeline), None, None + pipeline = sequential_transforms(tokenizer, vocab_func(vocab)) + return pipeline, None, None def build_experimental_torchtext_pipeline(hf_vocab_file): @@ -69,7 +67,6 @@ def build_experimental_torchtext_pipeline(hf_vocab_file): def build_legacy_batch_torchtext_vocab_pipeline(vocab_file): tokenizer = get_tokenizer("basic_english") from torchtext.vocab import build_vocab_from_iterator - from transforms import TextClassificationPipeline def token_iterator(vocab_file): f = open(vocab_file, 'r') @@ -78,9 +75,8 @@ def token_iterator(vocab_file): yield token vocab = build_vocab_from_iterator(token_iterator(vocab_file)) - text_pipeline = sequential_transforms(tokenizer, vocab_func(vocab)) - label_pipeline = totensor(dtype=torch.long) - return TextClassificationPipeline(label_pipeline, text_pipeline), None, None + text_pipeline = sequential_transforms(tokenizer_func(tokenizer), vocab_func(vocab)) + return text_pipeline, None, None def build_legacy_pytext_vocab_pipeline(vocab_file): @@ -106,7 +102,7 @@ def build_legacy_pytext_script_vocab_pipeline(vocab_file): sorted_by_freq_tuples = sorted(vocab_counter.items(), key=lambda x: x[1], reverse=True) vocab_list = [pair[0] for pair in sorted_by_freq_tuples] vocab_list.insert(0, "") - pipeline = TextSequentialTransforms(tokenizer_func(tokenizer), + pipeline = TextSequentialTransforms(tokenizer, PyTextScriptVocabTransform(ScriptVocabulary(vocab_list))) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit legacy PyText pipeline success!') @@ -138,7 +134,7 @@ def build_legacy_fasttext_vector_pipeline(): tokenizer = get_tokenizer("basic_english") vector = FastText() - pipeline = sequential_transforms(tokenizer_func(tokenizer), vector_func(vector)) + pipeline = sequential_transforms(tokenizer, vector.get_vecs_by_tokens) return pipeline, None, None @@ -155,25 +151,24 @@ def build_experimental_fasttext_vector_pipeline(): def run_benchmark_lookup(text_classification_dataset, pipeline): t0 = time.monotonic() - lines = [text for (label, text) in text_classification_dataset] - lines = pipeline(lines) + for (label, text) in text_classification_dataset: + text = pipeline(text) print("Lookup time:", time.monotonic() - t0) def run_batch_benchmark_lookup(text_classification_dataset, pipeline): + def collate_fn(data_batch): + return [text for (label, text) in data_batch] + dataloader = DataLoader(text_classification_dataset, batch_size=16, shuffle=True, collate_fn=collate_fn) t0 = time.monotonic() - for items in text_classification_dataset: - items = list(map(pipeline, items)) + for lines in dataloader: + lines = pipeline(lines) print("Lookup time:", time.monotonic() - t0) def generate_dataset(args): - if args.pipeline == 'legacy_batch_torchtext': - train = BatchTextClassificationData(args.dataset) - test = None - else: - train, test = raw.DATASETS[args.dataset]() - return train, test + train, test = raw.DATASETS[args.dataset]() + return [_data for _data in train], [_data for _data in test] if __name__ == "__main__": diff --git a/examples/data_pipeline/transforms.py b/examples/data_pipeline/transforms.py index 867153353d..7a6d9214e5 100644 --- a/examples/data_pipeline/transforms.py +++ b/examples/data_pipeline/transforms.py @@ -6,23 +6,6 @@ from torch import Tensor -class PretrainedSPTokenizer(nn.Module): - r"""Tokenizer based on a pretained sentencepiece model - """ - - def __init__(self, sp_model): - super(PretrainedSPTokenizer, self).__init__() - self.sp_model = sp_model - - def forward(self, lines: List[str]) -> List[List[str]]: - r""" - """ - tokens: List[List[str]] = [] - for line in lines: - tokens.append(self.sp_model.EncodeAsPieces(line)) - return tokens - - class PretrainedSPVocab(nn.Module): r"""Vocab based on a pretained sentencepiece model """ @@ -35,11 +18,8 @@ def __init__(self, sp_model): vocab_list = [self.sp_model.IdToPiece(i) for i in range(self.sp_model.GetPieceSize())] self.vocab = vocab(OrderedDict([(token, 1) for token in vocab_list]), unk_token=unk_token) - def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: - ids: List[List[int]] = [] - for tokens in tokens_list: - ids.append(self.vocab.lookup_indices(tokens)) - return ids + def forward(self, tokens: List[str]) -> List[int]: + return self.vocab.lookup_indices(tokens) def insert_token(self, token: str, index: int) -> None: self.vocab.insert_token(token, index) @@ -74,8 +54,8 @@ def __init__(self, vocab): super(PyTextScriptVocabTransform, self).__init__() self.vocab = vocab - def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: - return self.vocab.lookup_indices_2d(tokens_list) + def forward(self, tokens: List[str]) -> List[int]: + return self.vocab.lookup_indices_1d(tokens) def to_ivalue(self): if hasattr(self.vocab, 'to_ivalue'): diff --git a/examples/text_classification/run_script.sh b/examples/text_classification/run_script.sh index d38359e0e9..534c9975ca 100755 --- a/examples/text_classification/run_script.sh +++ b/examples/text_classification/run_script.sh @@ -3,4 +3,6 @@ if [ ! -d ".data" ]; then fi python train.py AG_NEWS --device cuda --save-model-path model.i --dictionary vocab.i +# To run spm with YelpReviewFull +# python train.py YelpReviewFull --device cuda --save-model-path model.i --dictionary vocab.i --use-sp-tokenizer True cut -f 2- -d "," .data/ag_news_csv/test.csv | python predict.py model.i vocab.i > predict_script.o diff --git a/examples/text_classification/spm_dataset.py b/examples/text_classification/spm_dataset.py index 4a67e309be..627c67163e 100644 --- a/examples/text_classification/spm_dataset.py +++ b/examples/text_classification/spm_dataset.py @@ -1,23 +1,25 @@ -import logging import torch import io from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from os import path from torchtext.datasets.text_classification import URLS -from torchtext.data.functional import generate_sp_model, \ - load_sp_model, sentencepiece_numericalizer from torchtext.datasets import text_classification +from torchtext.experimental.transforms import ( + sentencepiece_processor, + pretrained_sp_model, +) -def _create_data_with_sp_transform(sp_generator, data_path): +def _create_data_with_sp_transform(data_path): data = [] labels = [] + spm_path = pretrained_sp_model['text_unigram_15000'] + text_pipeline = sentencepiece_processor(download_from_url(spm_path)) with io.open(data_path, encoding="utf8") as f: reader = unicode_csv_reader(f) for row in reader: corpus = ' '.join(row[1:]) - token_ids = list(sp_generator([corpus]))[0] + token_ids = text_pipeline(corpus) label = int(row[0]) - 1 data.append((label, torch.tensor(token_ids))) labels.append(label) @@ -33,18 +35,8 @@ def setup_datasets(dataset_name, root='.data', vocab_size=20000, include_unk=Fal train_csv_path = fname if fname.endswith('test.csv'): test_csv_path = fname - - # generate sentencepiece pretrained tokenizer - if not path.exists('m_user.model'): - logging.info('Generate SentencePiece pretrained tokenizer...') - generate_sp_model(train_csv_path, vocab_size) - - sp_model = load_sp_model("m_user.model") - sp_generator = sentencepiece_numericalizer(sp_model) - train_data, train_labels = _create_data_with_sp_transform(sp_generator, - train_csv_path) - test_data, test_labels = _create_data_with_sp_transform(sp_generator, - test_csv_path) + train_data, train_labels = _create_data_with_sp_transform(train_csv_path) + test_data, test_labels = _create_data_with_sp_transform(test_csv_path) if len(train_labels ^ test_labels) > 0: raise ValueError("Training and test labels don't match") diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 126680fb3b..85ed3024ac 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -129,8 +129,8 @@ def test_multi30k(self): # smoke test to ensure multi30k works properly train_dataset, valid_dataset, test_dataset = Multi30k() self.assertEqual(len(train_dataset), 29000) - self.assertEqual(len(valid_dataset), 1000) - self.assertEqual(len(test_dataset), 1014) + self.assertEqual(len(valid_dataset), 1014) + self.assertEqual(len(test_dataset), 1000) de_vocab, en_vocab = train_dataset.get_vocab() de_tokens_ids = [ diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 174f641733..80648d0983 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -80,12 +80,20 @@ def test_sentencepiece_tokenizer(self): self.assertEqual(list(spm_generator([test_sample]))[0], ref_results) + def test_sentencepiece_unsupported_input_type(self): + with self.assertRaisesRegex( + TypeError, + 'Unsupported type for spm argument: dict. ' + 'Supported types are: str, io.BufferedReader' + ): + load_sp_model(dict()) + # TODO(Nayef211): remove decorator once https://github.com/pytorch/pytorch/issues/38207 is closed @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_BasicEnglishNormalize(self): - test_sample = ['\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:'] - ref_results = [["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', - 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?']] + test_sample = '\'".
,()!?;: Basic English Normalization for a Line of Text \'".
,()!?;:' + ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', + 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] basic_eng_norm = basic_english_normalize() experimental_eager_tokens = basic_eng_norm(test_sample) @@ -94,7 +102,7 @@ def test_BasicEnglishNormalize(self): experimental_jit_tokens = jit_basic_eng_norm(test_sample) basic_english_tokenizer = data.get_tokenizer("basic_english") - eager_tokens = [basic_english_tokenizer(test_sample[0])] + eager_tokens = basic_english_tokenizer(test_sample) assert not basic_eng_norm.is_jitable assert basic_eng_norm.to_ivalue().is_jitable @@ -114,9 +122,9 @@ def test_BasicEnglishNormalize(self): # TODO(Nayef211): remove decorator once https://github.com/pytorch/pytorch/issues/38207 is closed @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") def test_RegexTokenizer(self): - test_sample = ['\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:'] - ref_results = [["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', - 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?']] + test_sample = '\'".
,()!?;: Basic Regex Tokenization for a Line of Text \'".
,()!?;:' + ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', + 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] patterns_list = [ (r'\'', ' \' '), (r'\"', ''), diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py index 87b17038d4..234ab1072d 100644 --- a/test/experimental/test_transforms.py +++ b/test/experimental/test_transforms.py @@ -1,9 +1,14 @@ import torch +from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase -from ..common.assets import get_asset_path from torchtext.experimental.transforms import ( + basic_english_normalize, VectorTransform, + VocabTransform, + sentencepiece_processor, + sentencepiece_tokenizer, ) +from torchtext.experimental.vocab import vocab_from_file from torchtext.experimental.vectors import FastText import shutil import tempfile @@ -11,6 +16,33 @@ class TestTransforms(TorchtextTestCase): + def test_sentencepiece_processor(self): + model_path = get_asset_path('spm_example.model') + spm_transform = sentencepiece_processor(model_path) + jit_spm_transform = torch.jit.script(spm_transform.to_ivalue()) + test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' + ref_results = [15340, 4286, 981, 1207, 1681, 17, 84, 684, 8896, 5366, + 144, 3689, 9, 5602, 12114, 6, 560, 649, 5602, 12114] + self.assertEqual(spm_transform(test_sample), ref_results) + self.assertEqual(jit_spm_transform(test_sample), ref_results) + self.assertEqual(spm_transform.decode(ref_results), test_sample) + self.assertEqual(jit_spm_transform.decode(ref_results), test_sample) + + def test_sentencepiece_tokenizer(self): + model_path = get_asset_path('spm_example.model') + spm_tokenizer = sentencepiece_tokenizer(model_path) + jit_spm_tokenizer = torch.jit.script(spm_tokenizer.to_ivalue()) + test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' + ref_results = ['\u2581Sent', 'ence', 'P', 'ie', 'ce', '\u2581is', + '\u2581an', '\u2581un', 'super', 'vis', 'ed', '\u2581text', + '\u2581to', 'ken', 'izer', '\u2581and', + '\u2581de', 'to', 'ken', 'izer'] + + self.assertEqual(spm_tokenizer(test_sample), ref_results) + self.assertEqual(spm_tokenizer.decode(ref_results), test_sample) + self.assertEqual(jit_spm_tokenizer(test_sample), ref_results) + self.assertEqual(jit_spm_tokenizer.decode(ref_results), test_sample) + def test_vector_transform(self): asset_name = 'wiki.en.vec' asset_path = get_asset_path(asset_name) @@ -23,5 +55,5 @@ def test_vector_transform(self): # The first 3 entries in each vector. expected_fasttext_simple_en = torch.tensor([[-0.065334, -0.093031, -0.017571], [-0.32423, -0.098845, -0.0073467]]) - self.assertEqual(vector_transform([['the', 'world']])[0][:, 0:3], expected_fasttext_simple_en) - self.assertEqual(jit_vector_transform([['the', 'world']])[0][:, 0:3], expected_fasttext_simple_en) + self.assertEqual(vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) + self.assertEqual(jit_vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) diff --git a/test/experimental/test_transforms_with_asset.py b/test/experimental/test_transforms_with_asset.py index b22d031a58..f9ec6d5d0c 100644 --- a/test/experimental/test_transforms_with_asset.py +++ b/test/experimental/test_transforms_with_asset.py @@ -3,6 +3,8 @@ from ..common.assets import get_asset_path from torchtext.experimental.transforms import ( VocabTransform, + pretrained_sp_model, + TextSequentialTransforms, ) from torchtext.experimental.vocab import ( vocab_from_file, @@ -11,10 +13,14 @@ import shutil import tempfile import os +import platform from torchtext.experimental.vectors import ( GloVe, vectors, + FastText, + vectors_from_file_object, ) +from torchtext.utils import download_from_url class TestTransformsWithAsset(TorchtextTestCase): @@ -23,11 +29,11 @@ def test_vocab_transform(self): asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: vocab_transform = VocabTransform(vocab_from_file(f)) - self.assertEqual(vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), - [[7, 18, 24], [7, 18, 24, 18]]) + self.assertEqual(vocab_transform(['of', 'that', 'new']), + [7, 18, 24]) jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) - self.assertEqual(jit_vocab_transform([['of', 'that', 'new'], ['of', 'that', 'new', 'that']]), - [[7, 18, 24], [7, 18, 24, 18]]) + self.assertEqual(jit_vocab_transform(['of', 'that', 'new', 'that']), + [7, 18, 24, 18]) def test_errors_vectors_python(self): tokens = [] @@ -143,3 +149,82 @@ def test_vocab_from_raw_text_file(self): expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) + + def test_builtin_pretrained_sentencepiece_processor(self): + sp_model_path = download_from_url(pretrained_sp_model['text_unigram_25000']) + spm_tokenizer = sentencepiece_tokenizer(sp_model_path) + _path = os.path.join(self.project_root, '.data', 'text_unigram_25000.model') + os.remove(_path) + test_sample = 'the pretrained spm model names' + ref_results = ['\u2581the', '\u2581pre', 'trained', '\u2581sp', 'm', '\u2581model', '\u2581names'] + self.assertEqual(spm_tokenizer(test_sample), ref_results) + + sp_model_path = download_from_url(pretrained_sp_model['text_bpe_25000']) + spm_transform = sentencepiece_processor(sp_model_path) + _path = os.path.join(self.project_root, '.data', 'text_bpe_25000.model') + os.remove(_path) + test_sample = 'the pretrained spm model names' + ref_results = [13, 1465, 12824, 304, 24935, 5771, 3776] + self.assertEqual(spm_transform(test_sample), ref_results) + + def test_text_sequential_transform(self): + asset_name = 'vocab_test2.txt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'r') as f: + pipeline = TextSequentialTransforms(basic_english_normalize(), vocab_from_file(f)) + jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + self.assertEqual(pipeline('of that new'), [7, 18, 24]) + self.assertEqual(jit_pipeline('of that new'), [7, 18, 24]) + + + # we separate out these errors because Windows runs into seg faults when propagating + # exceptions from C++ using pybind11 + @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") + def test_errors_vectors_cpp(self): + tensorA = torch.tensor([1, 0, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1, 0], dtype=torch.float) + tensorC = torch.tensor([0, 0, 1], dtype=torch.float) + tokens = ['a', 'a', 'c'] + vecs = torch.stack((tensorA, tensorB, tensorC), 0) + + with self.assertRaises(RuntimeError): + # Test proper error raised when tokens have duplicates + # TODO: use self.assertRaisesRegex() to check + # the key of the duplicate token in the error message + vectors(tokens, vecs) + + def test_vectors_from_file(self): + asset_name = 'vectors_test.csv' + asset_path = get_asset_path(asset_name) + f = open(asset_path, 'r') + vectors_obj = vectors_from_file_object(f) + + expected_tensorA = torch.tensor([1, 0, 0], dtype=torch.float) + expected_tensorB = torch.tensor([0, 1, 0], dtype=torch.float) + expected_unk_tensor = torch.tensor([0, 0, 0], dtype=torch.float) + + self.assertEqual(vectors_obj['a'], expected_tensorA) + self.assertEqual(vectors_obj['b'], expected_tensorB) + self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) + + def test_fast_text(self): + # copy the asset file into the expected download location + # note that this is just a file with the first 100 entries of the FastText english dataset + asset_name = 'wiki.en.vec' + asset_path = get_asset_path(asset_name) + + with tempfile.TemporaryDirectory() as dir_name: + data_path = os.path.join(dir_name, asset_name) + shutil.copy(asset_path, data_path) + vectors_obj = FastText(root=dir_name, validate_file=False) + jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + + # The first 3 entries in each vector. + expected_fasttext_simple_en = { + 'the': [-0.065334, -0.093031, -0.017571], + 'world': [-0.32423, -0.098845, -0.0073467], + } + + for word in expected_fasttext_simple_en.keys(): + self.assertEqual(vectors_obj[word][:3], expected_fasttext_simple_en[word]) + self.assertEqual(jit_vectors_obj[word][:3], expected_fasttext_simple_en[word]) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 69b33de094..c39dae8708 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -1,17 +1,9 @@ # -*- coding: utf-8 -*- import os -import platform -import shutil -import tempfile import torch -import unittest -from ..common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vectors import ( - FastText, - GloVe, vectors, - vectors_from_file_object ) @@ -79,8 +71,8 @@ def test_vectors_forward(self): vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) - tokens_to_lookup = [['a', 'b', 'c']] - expected_vectors = [torch.stack((tensorA, tensorB, unk_tensor), 0)] + tokens_to_lookup = ['a', 'b', 'c'] + expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) vectors_by_tokens = vectors_obj(tokens_to_lookup) jit_vectors_by_tokens = jit_vectors_obj(tokens_to_lookup) @@ -136,55 +128,3 @@ def test_vectors_load_and_save(self): self.assertEqual(loaded_vectors_obj['a'], tensorA) self.assertEqual(loaded_vectors_obj['b'], tensorC) self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) - - # we separate out these errors because Windows runs into seg faults when propagating - # exceptions from C++ using pybind11 - @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") - def test_errors_vectors_cpp(self): - tensorA = torch.tensor([1, 0, 0], dtype=torch.float) - tensorB = torch.tensor([0, 1, 0], dtype=torch.float) - tensorC = torch.tensor([0, 0, 1], dtype=torch.float) - tokens = ['a', 'a', 'c'] - vecs = torch.stack((tensorA, tensorB, tensorC), 0) - - with self.assertRaises(RuntimeError): - # Test proper error raised when tokens have duplicates - # TODO: use self.assertRaisesRegex() to check - # the key of the duplicate token in the error message - vectors(tokens, vecs) - - def test_vectors_from_file(self): - asset_name = 'vectors_test.csv' - asset_path = get_asset_path(asset_name) - f = open(asset_path, 'r') - vectors_obj = vectors_from_file_object(f) - - expected_tensorA = torch.tensor([1, 0, 0], dtype=torch.float) - expected_tensorB = torch.tensor([0, 1, 0], dtype=torch.float) - expected_unk_tensor = torch.tensor([0, 0, 0], dtype=torch.float) - - self.assertEqual(vectors_obj['a'], expected_tensorA) - self.assertEqual(vectors_obj['b'], expected_tensorB) - self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) - - def test_fast_text(self): - # copy the asset file into the expected download location - # note that this is just a file with the first 100 entries of the FastText english dataset - asset_name = 'wiki.en.vec' - asset_path = get_asset_path(asset_name) - - with tempfile.TemporaryDirectory() as dir_name: - data_path = os.path.join(dir_name, asset_name) - shutil.copy(asset_path, data_path) - vectors_obj = FastText(root=dir_name, validate_file=False) - jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) - - # The first 3 entries in each vector. - expected_fasttext_simple_en = { - 'the': [-0.065334, -0.093031, -0.017571], - 'world': [-0.32423, -0.098845, -0.0073467], - } - - for word in expected_fasttext_simple_en.keys(): - self.assertEqual(vectors_obj[word][:3], expected_fasttext_simple_en[word]) - self.assertEqual(jit_vectors_obj[word][:3], expected_fasttext_simple_en[word]) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 977b5f5293..0813ab16e4 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -125,8 +125,8 @@ def test_vocab_forward(self): v = vocab(c) jit_v = torch.jit.script(v.to_ivalue()) - tokens = [['b', 'a', 'c']] - expected_indices = [[2, 1, 3]] + tokens = ['b', 'a', 'c'] + expected_indices = [2, 1, 3] self.assertEqual(v(tokens), expected_indices) self.assertEqual(jit_v(tokens), expected_indices) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 4f817b3720..920167af5a 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -26,9 +26,14 @@ PYBIND11_MODULE(_torchtext, m) { .def("forward", &RegexTokenizer::forward); py::class_(m, "SentencePiece") + .def(py::init()) + .def("_return_content", + [](const SentencePiece &self) { return py::bytes(self.content_); }) .def("Encode", &SentencePiece::Encode) .def("EncodeAsIds", &SentencePiece::EncodeAsIds) + .def("DecodeIds", &SentencePiece::DecodeIds) .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) + .def("DecodePieces", &SentencePiece::DecodePieces) .def("GetPieceSize", &SentencePiece::GetPieceSize) .def("unk_id", &SentencePiece::unk_id) .def("PieceToId", &SentencePiece::PieceToId) @@ -108,9 +113,12 @@ static auto regex_tokenizer = static auto sentencepiece = torch::class_("torchtext", "SentencePiece") + .def(torch::init()) .def("Encode", &SentencePiece::Encode) .def("EncodeAsIds", &SentencePiece::EncodeAsIds) + .def("DecodeIds", &SentencePiece::DecodeIds) .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) + .def("DecodePieces", &SentencePiece::DecodePieces) .def("GetPieceSize", &SentencePiece::GetPieceSize) .def("unk_id", &SentencePiece::unk_id) .def("PieceToId", &SentencePiece::PieceToId) diff --git a/torchtext/csrc/sentencepiece.cpp b/torchtext/csrc/sentencepiece.cpp index 7e89a544eb..1fc5e370b2 100644 --- a/torchtext/csrc/sentencepiece.cpp +++ b/torchtext/csrc/sentencepiece.cpp @@ -22,11 +22,21 @@ SentencePiece::EncodeAsIds(const std::string &input) const { return std::vector(val.begin(), val.end()); } +std::string SentencePiece::DecodeIds(const std::vector &ids) const { + const std::vector val(ids.begin(), ids.end()); + return processor_.DecodeIds(val); +} + std::vector SentencePiece::EncodeAsPieces(const std::string &input) const { return processor_.EncodeAsPieces(input); } +std::string +SentencePiece::DecodePieces(const std::vector &pieces) const { + return processor_.DecodePieces(pieces); +} + int64_t SentencePiece::GetPieceSize() const { return processor_.GetPieceSize(); } diff --git a/torchtext/csrc/sentencepiece.h b/torchtext/csrc/sentencepiece.h index e1079b102f..3b26d90ffa 100644 --- a/torchtext/csrc/sentencepiece.h +++ b/torchtext/csrc/sentencepiece.h @@ -14,12 +14,14 @@ struct SentencePiece : torch::CustomClassHolder { // provide serialization mechanism, yet we still need to be able to serialize // the model so that we can save the scripted object. pickle will get the // serialized model from this content_ member, thus it needs to be public. - const std::string content_; + std::string content_; explicit SentencePiece(const std::string &content); std::vector Encode(const std::string &input) const; std::vector EncodeAsIds(const std::string &input) const; + std::string DecodeIds(const std::vector &ids) const; std::vector EncodeAsPieces(const std::string &input) const; + std::string DecodePieces(const std::vector &pieces) const; int64_t GetPieceSize() const; int64_t unk_id() const; int64_t PieceToId(const std::string &piece) const; diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 49b1c6c3f4..1b462a8967 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -179,13 +179,8 @@ void parse_raw_text_file_chunk(const std::string &file_path, size_t offset, std::string line; for (int64_t i = start_line; i < end_line; i++) { std::getline(fin, line); - - auto line_list_ivalue = c10::IValue(std::vector({line})); auto token_list = - module.forward(std::vector({line_list_ivalue})) - .toList() - .get(0) - .toList(); + module.forward(std::vector({c10::IValue(line)})).toList(); for (size_t i = 0; i < token_list.size(); i++) { c10::IValue token_ref = token_list.get(i); diff --git a/torchtext/data/functional.py b/torchtext/data/functional.py index 3333c2dc63..6e20c8e667 100644 --- a/torchtext/data/functional.py +++ b/torchtext/data/functional.py @@ -58,7 +58,12 @@ def load_sp_model(spm): elif isinstance(spm, io.BufferedReader): return torch.ops.torchtext.load_sp_model_string(spm.read()) else: - raise RuntimeError('the input of the load_sp_model func is not supported.') + raise TypeError( + f'Unsupported type for spm argument: {type(spm).__name__}. ' + + 'Supported types are: ' + + ', '.join([ + 'str', 'io.BufferedReader' + ])) def sentencepiece_numericalizer(sp_model): diff --git a/torchtext/experimental/__init__.py b/torchtext/experimental/__init__.py index d7fa116bab..196d0dd84b 100644 --- a/torchtext/experimental/__init__.py +++ b/torchtext/experimental/__init__.py @@ -1,3 +1,4 @@ from . import datasets +from . import transforms -__all__ = ['datasets'] +__all__ = ['datasets', 'transforms'] diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index b86e9f4756..44169f77a5 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -6,23 +6,25 @@ from .translation import Multi30k, IWSLT, WMT14 from .question_answer import SQuAD1, SQuAD2 -__all__ = ['LanguageModelingDataset', - 'WikiText2', - 'WikiText103', - 'PennTreebank', - 'WMTNewsCrawl', - 'IMDB', - 'AG_NEWS', - 'SogouNews', - 'DBpedia', - 'YelpReviewPolarity', - 'YelpReviewFull', - 'YahooAnswers', - 'AmazonReviewPolarity', - 'AmazonReviewFull', - 'UDPOS', - 'CoNLL2000Chunking', - 'Multi30k', - 'IWSLT', - 'WMT14', - 'SQuAD1', 'SQuAD2'] +DATASETS = {'WikiText2': WikiText2, + 'WikiText103': WikiText103, + 'PennTreebank': PennTreebank, + 'WMTNewsCrawl': WMTNewsCrawl, + 'IMDB': IMDB, + 'AG_NEWS': AG_NEWS, + 'SogouNews': SogouNews, + 'DBpedia': DBpedia, + 'YelpReviewPolarity': YelpReviewPolarity, + 'YelpReviewFull': YelpReviewFull, + 'YahooAnswers': YahooAnswers, + 'AmazonReviewPolarity': AmazonReviewPolarity, + 'AmazonReviewFull': AmazonReviewFull, + 'UDPOS': UDPOS, + 'CoNLL2000Chunking': CoNLL2000Chunking, + 'Multi30k': Multi30k, + 'IWSLT': IWSLT, + 'WMT14': WMT14, + 'SQuAD1': SQuAD1, + 'SQuAD2': SQuAD2} + +__all__ = sorted(list(map(str, DATASETS.keys()))) diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index f44de4af88..42329a5a60 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -2,14 +2,15 @@ from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.datasets.raw import language_modeling as raw -from torchtext.experimental.functional import vocab_func, totensor, sequential_transforms def build_vocab(data, transforms): - tok_list = [] - for txt in data: - tok_list.append(transforms(txt)) - return build_vocab_from_iterator(tok_list) + def apply_transforms(data): + for line in data: + tokens = transforms(line) + if len(tokens) > 0: + yield tokens + return build_vocab_from_iterator(apply_transforms(data)) class LanguageModelingDataset(torch.utils.data.Dataset): @@ -39,10 +40,9 @@ def __init__(self, data, vocab, transforms, single_line): self.vocab = vocab self.transforms = transforms self.single_line = single_line + self.data = data if single_line: - self.data = torch.cat(tuple(transforms(row) for row in data), axis=0) - else: - self.data = data + self.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, self.data))) def __getitem__(self, i): if self.single_line: @@ -65,7 +65,6 @@ def _setup_datasets(dataset_name, tokenizer=None, root='.data', vocab=None, data_select=('train', 'test', 'valid'), single_line=True): if tokenizer is None: tokenizer = get_tokenizer('basic_english') - text_transform = sequential_transforms(tokenizer) if isinstance(data_select, str): data_select = [data_select] @@ -74,30 +73,20 @@ def _setup_datasets(dataset_name, tokenizer=None, root='.data', vocab=None, if not single_line and dataset_name != 'WikiText103': raise TypeError('single_line must be True except for WikiText103') - if dataset_name == 'WMTNewsCrawl': - train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) - if single_line: - raw_data = {'train': [" ".join([txt for txt in train]), ]} - else: - raw_data = {'train': [txt for txt in train]} - else: - train, test, valid = raw.DATASETS[dataset_name](root=root, data_select=('train', 'test', 'valid')) - # Cache raw text iterable dataset - if single_line: - raw_data = {'train': [" ".join([txt for txt in train]), ], - 'valid': [" ".join(txt for txt in valid), ], - 'test': [" ".join(txt for txt in test), ]} - else: - raw_data = {'train': [txt for txt in train], - 'valid': [txt for txt in valid], - 'test': [txt for txt in test]} - if vocab is None: if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - vocab = build_vocab(raw_data['train'], text_transform) - text_transform = sequential_transforms(text_transform, vocab_func(vocab), - totensor(dtype=torch.long)) + raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) + vocab = build_vocab(raw_train, tokenizer) + + def text_transform(line): + return torch.tensor([vocab[token] for token in tokenizer(line)], dtype=torch.long) + + raw_data = {} + for name in data_select: + raw_data[name], = raw.DATASETS[dataset_name](root=root, data_select=name) + raw_data[name] = [text_transform(txt) for txt in raw_data[name]] + return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform, single_line) for item in data_select) diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index aef81d0112..7413d2ab6a 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -75,14 +75,14 @@ def _setup_datasets(dataset_name, if vocab is None: if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - tok_list = [] - for (_context, _question, _answers, _ans_pos) in raw_data['train']: - tok_ans = [] - for item in _answers: - tok_ans += text_transform(item) - tok_list.append(text_transform(_context) + - text_transform(_question) + tok_ans) - vocab = build_vocab_from_iterator(tok_list) + + def apply_transform(data): + for (_context, _question, _answers, _ans_pos) in data: + tok_ans = [] + for item in _answers: + tok_ans += text_transform(item) + yield text_transform(_context) + text_transform(_question) + tok_ans + vocab = build_vocab_from_iterator(apply_transform(raw_data['train'])) text_transform = sequential_transforms(text_transform, vocab_func(vocab), totensor(dtype=torch.long)) transforms = {'context': text_transform, 'question': text_transform, 'answers': text_transform, 'ans_pos': totensor(dtype=torch.long)} diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py index ec3371de26..5a3eeabc6f 100644 --- a/torchtext/experimental/datasets/raw/__init__.py +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -6,22 +6,25 @@ from .language_modeling import WikiText2, WikiText103, PennTreebank, WMTNewsCrawl from .question_answer import SQuAD1, SQuAD2 -__all__ = ['IMDB', - 'AG_NEWS', - 'SogouNews', - 'DBpedia', - 'YelpReviewPolarity', - 'YelpReviewFull', - 'YahooAnswers', - 'AmazonReviewPolarity', - 'AmazonReviewFull', - 'UDPOS', - 'CoNLL2000Chunking', - 'Multi30k', - 'IWSLT', - 'WMT14', - 'WikiText2', - 'WikiText103', - 'PennTreebank', - 'WMTNewsCrawl', - 'SQuAD1', 'SQuAD2'] +DATASETS = {'IMDB': IMDB, + 'AG_NEWS': AG_NEWS, + 'SogouNews': SogouNews, + 'DBpedia': DBpedia, + 'YelpReviewPolarity': YelpReviewPolarity, + 'YelpReviewFull': YelpReviewFull, + 'YahooAnswers': YahooAnswers, + 'AmazonReviewPolarity': AmazonReviewPolarity, + 'AmazonReviewFull': AmazonReviewFull, + 'UDPOS': UDPOS, + 'CoNLL2000Chunking': CoNLL2000Chunking, + 'Multi30k': Multi30k, + 'IWSLT': IWSLT, + 'WMT14': WMT14, + 'WikiText2': WikiText2, + 'WikiText103': WikiText103, + 'PennTreebank': PennTreebank, + 'WMTNewsCrawl': WMTNewsCrawl, + 'SQuAD1': SQuAD1, + 'SQuAD2': SQuAD2} + +__all__ = sorted(list(map(str, DATASETS.keys()))) diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index 8a6a97a55e..41df4f6ba4 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -9,7 +9,7 @@ ) -def _build_vocab(data): +def build_vocab(data): total_columns = len(data[0]) data_list = [[] for _ in range(total_columns)] vocabs = [] @@ -17,7 +17,6 @@ def _build_vocab(data): for line in data: for idx, col in enumerate(line): data_list[idx].append(col) - for it in data_list: vocabs.append(build_vocab_from_iterator(it)) @@ -33,7 +32,7 @@ def _setup_datasets(dataset_name, if not set(data_select).issubset(set(("train", "valid", "test"))): raise TypeError("Given data selection {} is not supported!".format(data_select)) - train, val, test = DATASETS[dataset_name](root=root) + train, val, test = raw.DATASETS[dataset_name](root=root) raw_data = { "train": [line for line in train] if train else None, "valid": [line for line in val] if val else None, @@ -43,7 +42,7 @@ def _setup_datasets(dataset_name, if vocabs is None: if "train" not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - vocabs = _build_vocab(raw_data["train"]) + vocabs = build_vocab(raw_data["train"]) else: if not isinstance(vocabs, list): raise TypeError("vocabs must be an instance of list") @@ -80,6 +79,7 @@ class SequenceTaggingDataset(torch.utils.data.Dataset): - UDPOS - CoNLL2000Chunking """ + def __init__(self, data, vocabs, transforms): """Initiate sequence tagging dataset. Arguments: @@ -166,4 +166,4 @@ def CoNLL2000Chunking(*args, **kwargs): return _setup_datasets(*(("CoNLL2000Chunking", ) + args), **kwargs) -DATASETS = {"UDPOS": raw.UDPOS, "CoNLL2000Chunking": raw.CoNLL2000Chunking} +DATASETS = {"UDPOS": UDPOS, "CoNLL2000Chunking": CoNLL2000Chunking} diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index 6554a677bf..c54c9c4032 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -10,11 +10,11 @@ ) -def _build_vocab(data, transforms): - tok_list = [] - for _, txt in data: - tok_list.append(transforms(txt)) - return build_vocab_from_iterator(tok_list) +def build_vocab(data, transforms): + def apply_transforms(data): + for _, line in data: + yield transforms(line) + return build_vocab_from_iterator(apply_transforms(data)) class TextClassificationDataset(torch.utils.data.Dataset): @@ -91,7 +91,7 @@ def _setup_datasets( if vocab is None: if "train" not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - vocab = _build_vocab(raw_data["train"], text_transform) + vocab = build_vocab(raw_data["train"], text_transform) text_transform = sequential_transforms( text_transform, vocab_func(vocab), totensor(dtype=torch.long) ) diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index e5d29c3d1b..765d102877 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -8,10 +8,10 @@ def build_vocab(data, transforms, index): - tok_list = [] - for line in data: - tok_list.append(transforms(line[index])) - return build_vocab_from_iterator(tok_list) + def apply_transforms(data): + for line in data: + yield transforms(line[index]) + return build_vocab_from_iterator(apply_transforms(data)) def _setup_datasets(dataset_name, @@ -37,10 +37,10 @@ def _setup_datasets(dataset_name, raise ValueError( "tokenizer must be an instance of tuple with length two" "or None") - train, val, test = DATASETS[dataset_name](train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root) + train, val, test = raw.DATASETS[dataset_name](train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + root=root) raw_data = { "train": [line for line in train], "valid": [line for line in val], @@ -96,6 +96,7 @@ class TranslationDataset(torch.utils.data.Dataset): - WMT14 - IWSLT """ + def __init__(self, data, vocab, transforms): """Initiate translation dataset. @@ -235,6 +236,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), train_filenames=train_filenames, valid_filenames=valid_filenames, test_filenames=test_filenames, + data_select=data_select, tokenizer=tokenizer, root=root, vocab=vocab, @@ -431,6 +433,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), train_filenames=train_filenames, valid_filenames=valid_filenames, test_filenames=test_filenames, + data_select=data_select, tokenizer=tokenizer, root=root, vocab=vocab, @@ -542,10 +545,11 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', train_filenames=train_filenames, valid_filenames=valid_filenames, test_filenames=test_filenames, + data_select=data_select, tokenizer=tokenizer, root=root, vocab=vocab, removed_tokens=removed_tokens) -DATASETS = {'Multi30k': raw.Multi30k, 'IWSLT': raw.IWSLT, 'WMT14': raw.WMT14} +DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} diff --git a/torchtext/experimental/functional.py b/torchtext/experimental/functional.py index 26f277fd3a..0073d09e3c 100644 --- a/torchtext/experimental/functional.py +++ b/torchtext/experimental/functional.py @@ -1,6 +1,13 @@ import torch from torchtext.data.utils import ngrams_iterator +__all__ = [ + 'vocab_func', + 'totensor', + 'ngrams_func', + 'sequential_transforms' +] + def vocab_func(vocab): def func(tok_iter): diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 367a0b3bcb..b1346cbb04 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -4,10 +4,24 @@ from torchtext._torchtext import RegexTokenizer as RegexTokenizerPybind from collections import OrderedDict from torch import Tensor +from torchtext._torchtext import SentencePiece as SentencePiecePybind +import io + __all__ = [ + 'basic_english_normalize', + 'regex_tokenizer', 'BasicEnglishNormalize', - 'RegexTokenizer' + 'RegexTokenizer', + 'TextSequentialTransforms', + 'pretrained_sp_model', + 'load_sp_model', + 'sentencepiece_tokenizer', + 'SentencePieceTokenizer', + 'sentencepiece_processor', + 'SentencePieceProcessor', + 'VocabTransform', + 'VectorTransform' ] @@ -95,18 +109,15 @@ def __init__(self, regex_tokenizer): def is_jitable(self): return not isinstance(self.regex_tokenizer, RegexTokenizerPybind) - def forward(self, lines: List[str]) -> List[List[str]]: + def forward(self, line: str) -> List[str]: r""" Args: - lines (List[str]): a list of text to tokenize. + lines (str): a text string to tokenize. Returns: - List[List[str]]: a list of token list after normalizing and splitting on whitespace. + List[str]: a token list after normalizing and splitting on whitespace. """ - tokens: List[List[str]] = [] - for line in lines: - tokens.append(self.regex_tokenizer.forward(line)) - return tokens + return self.regex_tokenizer.forward(line) def to_ivalue(self): r"""Return a JITable BasicEnglishNormalize. @@ -130,18 +141,15 @@ def __init__(self, regex_tokenzier): def is_jitable(self): return not isinstance(self.regex_tokenizer, RegexTokenizerPybind) - def forward(self, lines: List[str]) -> List[List[str]]: + def forward(self, line: str) -> List[str]: r""" Args: - lines (List[str]): a list of text to tokenize. + lines (str): a text string to tokenize. Returns: - List[List[str]]: a list of token list after normalizing and splitting on whitespace. + List[str]: a token list after regex. """ - tokens: List[List[str]] = [] - for line in lines: - tokens.append(self.regex_tokenizer.forward(line)) - return tokens + return self.regex_tokenizer.forward(line) def to_ivalue(self): r"""Return a JITable RegexTokenizer. @@ -152,15 +160,16 @@ def to_ivalue(self): class TextSequentialTransforms(nn.Sequential): r"""A container to host a sequential text transforms. - Example: >>> import torch - >>> from torchtext.experimental.transforms import BasicEnglishNormalize, TextSequentialTransforms - >>> tokenizer = BasicEnglishNormalize() + >>> from torchtext.experimental.transforms import basic_english_normalize, TextSequentialTransforms + >>> tokenizer = basic_english_normalize() >>> txt_pipeline = TextSequentialTransforms(tokenizer) - >>> jit_txt_pipeline = torch.jit.script(txt_pipeline) + >>> txt_pipeline('here is an example') + ['here', 'is', 'an', 'example'] + >>> jit_txt_pipeline = torch.jit.script(txt_pipeline.to_ivalue()) """ - def forward(self, input: List[str]): + def forward(self, input: str): for module in self: input = module(input) return input @@ -176,6 +185,172 @@ def to_ivalue(self): return TextSequentialTransforms(OrderedDict(module_list)) +pretrained_sp_model = { + 'text_unigram_15000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_15000.model', + 'text_unigram_25000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_25000.model', + 'text_unigram_50000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_50000.model', + 'text_bpe_15000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_bpe_15000.model', + 'text_bpe_25000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_bpe_25000.model', + 'text_bpe_50000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_bpe_50000.model'} + + +def load_sp_model(sp_model): + r"""Load a sentencepiece model for file. + + Arguments: + sp_model: the file path or a file object saving the sentencepiece model. + + Outputs: + output: a SentencePiece model. + + Examples: + >>> from torchtext.experimental.transforms import load_sp_model + >>> sp_model = load_sp_model("m_user.model") + >>> sp_model = load_sp_model(open("m_user.model", 'rb')) + + Note: We also provide several pretrained sentencepiece models. The model was trained with torchtext.datasets.WikiText103, + torchtext.datasets.EnWik9 and BookCorpus. Both BPE and unigram methods were used to train the model (for more + details please refer to SentencePiece GitHub https://github.com/google/sentencepiece). We also provide the pretrained model + with a different size of the vocabulary (i.e. 15000, 25000, 50000). + The following pretrained sentencepiece models are provided: + - text_unigram_15000 + - text_unigram_25000 + - text_unigram_50000 + - text_bpe_15000 + - text_bpe_25000 + - text_bpe_50000 + + Examples: + >>> from torchtext.experimental.transforms import pretrained_sp_model + >>> sp_model_path = torchtext.utils.download_from_url(pretrained_sp_model['text_unigram_25000']) + >>> sp_model = load_sp_model(sp_model_path) + """ + if isinstance(sp_model, str): + with open(sp_model, 'rb') as f: + return SentencePiecePybind(f.read()) + elif isinstance(sp_model, io.BufferedReader): + return SentencePiecePybind(sp_model.read()) + else: + raise TypeError( + f'Unsupported type for sp_model argument: {type(sp_model).__name__}. ' + + 'Supported types are: ' + + ', '.join([ + 'str', 'io.BufferedReader' + ])) + + +def sentencepiece_tokenizer(sp_model): + r"""Factory function to generate SentencePieceTokenizer from a pretrained SentencePiece model + + Args: + sp_model: the file path or a file object saving the sentencepiece model. + + Examples: + >>> import torch + >>> from torchtext.experimental.transforms import sentencepiece_tokenizer + >>> spm_tokenizer = sentencepiece_tokenizer('m_user.model') + >>> jit_spm_tokenizer = torch.jit.script(spm_tokenizer.to_ivalue()) + """ + spm = load_sp_model(sp_model) + return SentencePieceTokenizer(spm) + + +class SentencePieceTokenizer(nn.Module): + r"""Tokenizer based on a pretained sentencepiece model. + + Args: + spm_model: the sentencepiece model instance + """ + + def __init__(self, spm_model): + super(SentencePieceTokenizer, self).__init__() + self.sp_model = spm_model + + def forward(self, line: str) -> List[str]: + r""" + Args: + line: the input sentence string + + Examples: + >>> spm_tokenizer('the pretrained sp model names') + >>> ['▁the', '▁pre', 'trained', '▁sp', '▁model', '▁names'] + + Note: SentencePiece treats the input text just as a sequence of Unicode characters. Whitespace is also handled as a normal symbol. To handle the whitespace as a basic token explicitly, SentencePiece first escapes the whitespace with a meta symbol "▁" (U+2581) as follows. + """ + return self.sp_model.EncodeAsPieces(line) + + @torch.jit.export + def decode(self, tokens: List[str]) -> str: + r""" + Args: + tokens: the tokens list for decoder + + Examples: + >>> spm_transform.decoder(['▁the', '▁pre', 'trained', '▁sp', '▁model', '▁names']) + >>> 'the pretrained sp model names' + """ + return self.sp_model.DecodePieces(tokens) + + def to_ivalue(self): + torchbind_spm = torch.classes.torchtext.SentencePiece(self.sp_model._return_content()) + return SentencePieceTokenizer(torchbind_spm) + + +def sentencepiece_processor(sp_model): + r"""Factory function to generate SentencePieceProcessor from a pretrained SentencePiece model + + Args: + sp_model: the file path or a file object saving the sentencepiece model. + + Examples: + >>> import torch + >>> from torchtext.experimental.transforms import sentencepiece_processor + >>> spm_processor = sentencepiece_processor('m_user.model') + >>> jit_spm_processor = torch.jit.script(spm_processor.to_ivalue()) + """ + spm = load_sp_model(sp_model) + return SentencePieceProcessor(spm) + + +class SentencePieceProcessor(nn.Module): + r"""String to ids transform based on a pretained sentencepiece model + + Args: + spm_model: the sentencepiece model instance + """ + + def __init__(self, spm_model): + super(SentencePieceProcessor, self).__init__() + self.sp_model = spm_model + + def forward(self, line: str) -> List[int]: + r""" + Args: + line: the input sentence string + + Examples: + >>> spm_processor('the pretrained sp model names') + >>> [9, 1546, 18811, 2849, 2759, 2202] + """ + return self.sp_model.EncodeAsIds(line) + + @torch.jit.export + def decode(self, ids: List[int]) -> str: + r""" + Args: + ids: the integers list for decoder + + Examples: + >>> spm_processor.decoder([9, 1546, 18811, 2849, 2759, 2202]) + >>> 'the pretrained sp model names' + """ + return self.sp_model.DecodeIds(ids) + + def to_ivalue(self): + torchbind_spm = torch.classes.torchtext.SentencePiece(self.sp_model._return_content()) + return SentencePieceProcessor(torchbind_spm) + + class VocabTransform(nn.Module): r"""Vocab transform @@ -194,20 +369,17 @@ def __init__(self, vocab): super(VocabTransform, self).__init__() self.vocab = vocab - def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: + def forward(self, tokens: List[str]) -> List[int]: r""" Args: - tokens: a list of string token list + tokens: a string token list Example: - >>> vocab_transform([['here', 'is', 'an', 'example']]) + >>> vocab_transform(['here', 'is', 'an', 'example']) """ - ids: List[List[int]] = [] - for tokens in tokens_list: - ids.append(self.vocab.lookup_indices(tokens)) - return ids + return self.vocab.lookup_indices(tokens) def to_ivalue(self): if hasattr(self.vocab, 'to_ivalue'): @@ -233,20 +405,17 @@ def __init__(self, vector): super(VectorTransform, self).__init__() self.vector = vector - def forward(self, tokens_list: List[List[str]]) -> List[Tensor]: + def forward(self, tokens: List[str]) -> Tensor: r""" Args: - tokens: a list of string token list + tokens: a string token list Example: - >>> vector_transform([['here', 'is', 'an', 'example']]) + >>> vector_transform(['here', 'is', 'an', 'example']) """ - vectors: List[Tensor] = [] - for tokens in tokens_list: - vectors.append(self.vector.lookup_vectors(tokens)) - return vectors + return self.vector.lookup_vectors(tokens) def to_ivalue(self): if hasattr(self.vector, 'to_ivalue'): diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index 88edb31ca8..2db8d9a4ad 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -14,6 +14,14 @@ _load_token_and_vectors_from_file ) +__all__ = [ + 'FastText', + 'GloVe', + 'vectors_from_file_object', + 'vectors', + 'Vectors' +] + logger = logging.getLogger(__name__) @@ -204,19 +212,16 @@ def is_jitable(self): return not isinstance(self.vectors, VectorsPybind) @torch.jit.export - def forward(self, tokens_list: List[List[str]]) -> List[Tensor]: + def forward(self, tokens: List[str]) -> Tensor: r"""Calls the `lookup_vectors` method Args: - tokens: a list of string token list + tokens: a list of string tokens Returns: - vectors (List[Tensor]): returns a list of a 2-D tensor of shape=(len(tokens), vector_dim) or an + vectors (Tensor): returns a 2-D tensor of shape=(len(tokens), vector_dim) or an empty tensor if `tokens` is empty """ - vectors: List[Tensor] = [] - for tokens in tokens_list: - vectors.append(self.vectors.lookup_vectors(tokens)) - return vectors + return self.vectors.lookup_vectors(tokens) @torch.jit.export def __getitem__(self, token: str) -> Tensor: diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 3d0b58f292..83a48d8ef8 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -10,6 +10,12 @@ _load_vocab_from_raw_text_file ) +__all__ = [ + 'vocab_from_raw_text_file', + 'vocab_from_file', + 'vocab', + 'Vocab', +] logger = logging.getLogger(__name__) @@ -129,18 +135,15 @@ def is_jitable(self): return not isinstance(self.vocab, VocabPybind) @torch.jit.export - def forward(self, tokens_list: List[List[str]]) -> List[List[int]]: + def forward(self, tokens: List[str]) -> List[int]: r"""Calls the `lookup_indices` method Args: - tokens (List[List[str]]): a list of tokens used to lookup their corresponding `indices`. + tokens (List[str]): a list of tokens used to lookup their corresponding `indices`. Returns: - indices (List[List[int]]): the 'indices` associated with a list of tokens`. + indices (List[int]): the 'indices` associated with a list of tokens`. """ - ids: List[List[int]] = [] - for tokens in tokens_list: - ids.append(self.vocab.lookup_indices(tokens)) - return ids + return self.vocab.lookup_indices(tokens) @torch.jit.export def __len__(self) -> int: From 24b304e1a3c26c38ed25714276f3efea3ed653a4 Mon Sep 17 00:00:00 2001 From: Meghan Lele Date: Tue, 29 Sep 2020 10:20:00 -0700 Subject: [PATCH 28/68] Enable @unused syntax for ignoring properties (#45261) Summary: Pull Request resolved: https://github.com/pytorch/pytorch/pull/45261 **Summary** This commit enables `unused` syntax for ignoring properties. Inoring properties is more intuitive with this feature enabled. `ignore` is not supported because class type properties cannot be executed in Python (because they exist only as TorchScript types) like an `ignored` function and module properties that cannot be scripted are not added to the `ScriptModule` wrapper so that they may execute in Python. **Test Plan** This commit updates the existing unit tests for class type and module properties to test properties ignored using `unused`. Test Plan: Imported from OSS Reviewed By: navahgar, Krovatkin, mannatsingh Differential Revision: D23971881 Pulled By: SplitInfinity fbshipit-source-id: 8d3cc1bbede7753d6b6f416619e4660c56311d33 --- torchtext/experimental/transforms.py | 4 ++-- torchtext/experimental/vectors.py | 2 +- torchtext/experimental/vocab.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index b1346cbb04..0473c57516 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -95,7 +95,7 @@ def regex_tokenizer(patterns_list): class BasicEnglishNormalize(nn.Module): - __ignored_properties__ = ["is_jitable"] + __jit_unused_properties__ = ["is_jitable"] r"""Basic normalization for a string sentence. Args: @@ -127,7 +127,7 @@ def to_ivalue(self): class RegexTokenizer(nn.Module): - __ignored_properties__ = ["is_jitable"] + __jit_unused_properties__ = ["is_jitable"] r"""Regex tokenizer for a string sentence that applies all regex replacements defined in patterns_list. Args: diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index 2db8d9a4ad..61b1e20ec4 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -197,7 +197,7 @@ def vectors(tokens, vectors, unk_tensor=None): class Vectors(nn.Module): - __ignored_properties__ = ["is_jitable"] + __jit_unused_properties__ = ["is_jitable"] r"""Creates a vectors object which maps tokens to vectors. Args: vectors (torch.classes.torchtext.Vectors or torchtext._torchtext.Vectors): a cpp vectors object. diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 83a48d8ef8..001e64405c 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -119,7 +119,7 @@ def vocab(ordered_dict, min_freq=1, unk_token=''): class Vocab(nn.Module): - __ignored_properties__ = ["is_jitable"] + __jit_unused_properties__ = ["is_jitable"] r"""Creates a vocab object which maps tokens to indices. Arguments: From 5cd2bb2e8de3eaa327fe370fbef9f72c1f7ff70f Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Mon, 12 Oct 2020 11:19:28 -0700 Subject: [PATCH 29/68] Import Github torchtext on 10/11/2020 Reviewed By: cpuhrsch Differential Revision: D24242037 fbshipit-source-id: 605d81412c320373f1158c51dbb120e7d70d624d --- benchmark/data_construction.py | 9 ++ docs/source/experimental_vocab.rst | 5 + test/data/test_builtin_datasets.py | 2 +- test/experimental/test_transforms.py | 3 - .../test_transforms_with_asset.py | 27 +--- test/experimental/test_vectors.py | 18 +++ test/experimental/test_vocab.py | 13 +- .../datasets/language_modeling.py | 59 +++---- .../experimental/datasets/question_answer.py | 22 +-- torchtext/experimental/datasets/raw/common.py | 53 +++++++ .../datasets/raw/language_modeling.py | 67 +++----- .../datasets/raw/question_answer.py | 105 +++++++------ .../datasets/raw/sequence_tagging.py | 84 ++++------ .../datasets/raw/text_classification.py | 148 +++++++++--------- .../experimental/datasets/raw/translation.py | 107 +++++-------- .../experimental/datasets/sequence_tagging.py | 48 ++---- .../datasets/text_classification.py | 59 +++---- .../experimental/datasets/translation.py | 133 ++++++---------- torchtext/experimental/transforms.py | 8 +- torchtext/experimental/vocab.py | 21 ++- torchtext/vocab.py | 8 +- 21 files changed, 483 insertions(+), 516 deletions(-) create mode 100644 torchtext/experimental/datasets/raw/common.py diff --git a/benchmark/data_construction.py b/benchmark/data_construction.py index 46e3462805..1a1621c353 100644 --- a/benchmark/data_construction.py +++ b/benchmark/data_construction.py @@ -12,6 +12,15 @@ def benchmark_construction(name, Dataset): del d +def benchmark_raw_construction(name, Dataset): + print(name, end='') + if name in "WMTNewsCrawl": + d = Dataset(data_select=('train',)) + else: + d = Dataset() + del d + + if __name__ == "__main__": for name, Dataset in datasets.DATASETS.items(): benchmark_construction(name, Dataset) diff --git a/docs/source/experimental_vocab.rst b/docs/source/experimental_vocab.rst index c2025bf631..debe7644e3 100644 --- a/docs/source/experimental_vocab.rst +++ b/docs/source/experimental_vocab.rst @@ -28,3 +28,8 @@ torchtext.experimental.vocab ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autofunction:: vocab_from_raw_text_file + +:hidden:`build_vocab_from_iterator` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: build_vocab_from_iterator diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 85ed3024ac..3d9b700238 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -4,7 +4,7 @@ import glob import shutil import torchtext.data as data -from torchtext.datasets import AG_NEWS +from torchtext.experimental.datasets import AG_NEWS import torch from ..common.torchtext_test_case import TorchtextTestCase diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py index 234ab1072d..69816dd6e7 100644 --- a/test/experimental/test_transforms.py +++ b/test/experimental/test_transforms.py @@ -2,13 +2,10 @@ from test.common.assets import get_asset_path from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.transforms import ( - basic_english_normalize, VectorTransform, - VocabTransform, sentencepiece_processor, sentencepiece_tokenizer, ) -from torchtext.experimental.vocab import vocab_from_file from torchtext.experimental.vectors import FastText import shutil import tempfile diff --git a/test/experimental/test_transforms_with_asset.py b/test/experimental/test_transforms_with_asset.py index f9ec6d5d0c..610ff6beaf 100644 --- a/test/experimental/test_transforms_with_asset.py +++ b/test/experimental/test_transforms_with_asset.py @@ -2,8 +2,11 @@ from test.common.torchtext_test_case import TorchtextTestCase from ..common.assets import get_asset_path from torchtext.experimental.transforms import ( + sentencepiece_tokenizer, + basic_english_normalize, VocabTransform, - pretrained_sp_model, + PRETRAINED_SP_MODEL, + sentencepiece_processor, TextSequentialTransforms, ) from torchtext.experimental.vocab import ( @@ -13,7 +16,6 @@ import shutil import tempfile import os -import platform from torchtext.experimental.vectors import ( GloVe, vectors, @@ -151,7 +153,7 @@ def test_vocab_from_raw_text_file(self): self.assertEqual(dict(v.get_stoi()), expected_stoi) def test_builtin_pretrained_sentencepiece_processor(self): - sp_model_path = download_from_url(pretrained_sp_model['text_unigram_25000']) + sp_model_path = download_from_url(PRETRAINED_SP_MODEL['text_unigram_25000']) spm_tokenizer = sentencepiece_tokenizer(sp_model_path) _path = os.path.join(self.project_root, '.data', 'text_unigram_25000.model') os.remove(_path) @@ -159,7 +161,7 @@ def test_builtin_pretrained_sentencepiece_processor(self): ref_results = ['\u2581the', '\u2581pre', 'trained', '\u2581sp', 'm', '\u2581model', '\u2581names'] self.assertEqual(spm_tokenizer(test_sample), ref_results) - sp_model_path = download_from_url(pretrained_sp_model['text_bpe_25000']) + sp_model_path = download_from_url(PRETRAINED_SP_MODEL['text_bpe_25000']) spm_transform = sentencepiece_processor(sp_model_path) _path = os.path.join(self.project_root, '.data', 'text_bpe_25000.model') os.remove(_path) @@ -176,23 +178,6 @@ def test_text_sequential_transform(self): self.assertEqual(pipeline('of that new'), [7, 18, 24]) self.assertEqual(jit_pipeline('of that new'), [7, 18, 24]) - - # we separate out these errors because Windows runs into seg faults when propagating - # exceptions from C++ using pybind11 - @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") - def test_errors_vectors_cpp(self): - tensorA = torch.tensor([1, 0, 0], dtype=torch.float) - tensorB = torch.tensor([0, 1, 0], dtype=torch.float) - tensorC = torch.tensor([0, 0, 1], dtype=torch.float) - tokens = ['a', 'a', 'c'] - vecs = torch.stack((tensorA, tensorB, tensorC), 0) - - with self.assertRaises(RuntimeError): - # Test proper error raised when tokens have duplicates - # TODO: use self.assertRaisesRegex() to check - # the key of the duplicate token in the error message - vectors(tokens, vecs) - def test_vectors_from_file(self): asset_name = 'vectors_test.csv' asset_path = get_asset_path(asset_name) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index c39dae8708..cae865f628 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- import os +import platform import torch +import unittest from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vectors import ( vectors, @@ -128,3 +130,19 @@ def test_vectors_load_and_save(self): self.assertEqual(loaded_vectors_obj['a'], tensorA) self.assertEqual(loaded_vectors_obj['b'], tensorC) self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) + + # we separate out these errors because Windows runs into seg faults when propagating + # exceptions from C++ using pybind11 + @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") + def test_errors_vectors_cpp(self): + tensorA = torch.tensor([1, 0, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1, 0], dtype=torch.float) + tensorC = torch.tensor([0, 0, 1], dtype=torch.float) + tokens = ['a', 'a', 'c'] + vecs = torch.stack((tensorA, tensorB, tensorC), 0) + + with self.assertRaises(RuntimeError): + # Test proper error raised when tokens have duplicates + # TODO: use self.assertRaisesRegex() to check + # the key of the duplicate token in the error message + vectors(tokens, vecs) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 0813ab16e4..626db2e726 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -5,11 +5,9 @@ import torch import unittest from test.common.torchtext_test_case import TorchtextTestCase -from torchtext.experimental.transforms import basic_english_normalize from torchtext.experimental.vocab import ( vocab, - vocab_from_file, - vocab_from_raw_text_file + build_vocab_from_iterator, ) @@ -207,3 +205,12 @@ def test_vocab_load_and_save(self): self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + + def test_build_vocab_iterator(self): + iterator = [['hello', 'hello', 'hello', 'freq_low', 'hello', 'world', 'world', 'world', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'freq_low', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T']] + v = build_vocab_from_iterator(iterator) + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index 42329a5a60..a6dd44ebae 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -2,15 +2,15 @@ from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.datasets.raw import language_modeling as raw +from torchtext.experimental.datasets.raw.common import check_default_set def build_vocab(data, transforms): def apply_transforms(data): for line in data: tokens = transforms(line) - if len(tokens) > 0: - yield tokens - return build_vocab_from_iterator(apply_transforms(data)) + yield tokens + return build_vocab_from_iterator(apply_transforms(data), len(data)) class LanguageModelingDataset(torch.utils.data.Dataset): @@ -61,22 +61,21 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, tokenizer=None, root='.data', vocab=None, - data_select=('train', 'test', 'valid'), single_line=True): +def _setup_datasets(dataset_name, tokenizer, root, vocab, data_select, single_line, year, language): if tokenizer is None: tokenizer = get_tokenizer('basic_english') - if isinstance(data_select, str): - data_select = [data_select] - if not set(data_select).issubset(set(('train', 'valid', 'test'))): - raise TypeError('Given data selection {} is not supported!'.format(data_select)) + data_select = check_default_set(data_select, ('train', 'test', 'valid')) if not single_line and dataset_name != 'WikiText103': raise TypeError('single_line must be True except for WikiText103') if vocab is None: if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) + if dataset_name == 'WMTNewsCrawl': + raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',), year=year, language=language) + else: + raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) vocab = build_vocab(raw_train, tokenizer) def text_transform(line): @@ -84,14 +83,17 @@ def text_transform(line): raw_data = {} for name in data_select: - raw_data[name], = raw.DATASETS[dataset_name](root=root, data_select=name) + if dataset_name == 'WMTNewsCrawl': + raw_data[name], = raw.DATASETS[dataset_name](root=root, data_select=name, year=year, language=language) + else: + raw_data[name], = raw.DATASETS[dataset_name](root=root, data_select=name) raw_data[name] = [text_transform(txt) for txt in raw_data[name]] return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform, single_line) for item in data_select) -def WikiText2(*args, **kwargs): +def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 'test', 'valid')): """ Defines WikiText2 datasets. Create language modeling dataset: WikiText2 @@ -112,10 +114,6 @@ def WikiText2(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText2 @@ -127,11 +125,10 @@ def WikiText2(*args, **kwargs): data_select='valid') """ - - return _setup_datasets(*(("WikiText2",) + args), **kwargs) + return _setup_datasets("WikiText2", tokenizer, root, vocab, data_select, True, None, None) -def WikiText103(*args, **kwargs): +def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', 'test', 'valid'), single_line=True): """ Defines WikiText103 datasets. Create language modeling dataset: WikiText103 @@ -168,10 +165,10 @@ def WikiText103(*args, **kwargs): """ - return _setup_datasets(*(("WikiText103",) + args), **kwargs) + return _setup_datasets("WikiText103", tokenizer, root, vocab, data_select, single_line, None, None) -def PennTreebank(*args, **kwargs): +def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', 'test', 'valid')): """ Defines PennTreebank datasets. Create language modeling dataset: PennTreebank @@ -192,10 +189,6 @@ def PennTreebank(*args, **kwargs): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import PennTreebank @@ -208,10 +201,10 @@ def PennTreebank(*args, **kwargs): """ - return _setup_datasets(*(("PennTreebank",) + args), **kwargs) + return _setup_datasets("PennTreebank", tokenizer, root, vocab, data_select, True, None, None) -def WMTNewsCrawl(*args, **kwargs): +def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, data_select=('train'), year=2010, language='en'): """ Defines WMTNewsCrawl datasets. Create language modeling dataset: WMTNewsCrawl @@ -225,21 +218,21 @@ def WMTNewsCrawl(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets + data_select: a string or tuple for the returned datasets (Default: ('train',)) - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. + year: the year of the dataset (Default: 2010) + language: the language of the dataset (Default: 'en') + Examples: >>> from torchtext.experimental.datasets import WMTNewsCrawl >>> from torchtext.data.utils import get_tokenizer >>> tokenizer = get_tokenizer("spacy") >>> train_dataset, = WMTNewsCrawl(tokenizer=tokenizer, data_select='train') + Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. """ - return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) + return _setup_datasets("WMTNewsCrawl", tokenizer, root, vocab, data_select, True, year, language) DATASETS = { diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index 7413d2ab6a..a7cc2df9a8 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -2,6 +2,7 @@ from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.datasets.raw import question_answer as raw +from torchtext.experimental.datasets.raw.common import check_default_set from torchtext.experimental.functional import ( totensor, vocab_func, @@ -56,19 +57,12 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, - root='.data', - vocab=None, - tokenizer=None, - data_select=('train', 'dev')): +def _setup_datasets(dataset_name, root, vocab, tokenizer, data_select): text_transform = [] if tokenizer is None: tokenizer = get_tokenizer('basic_english') text_transform = sequential_transforms(tokenizer) - if isinstance(data_select, str): - data_select = [data_select] - if not set(data_select).issubset(set(('train', 'dev'))): - raise TypeError('Given data selection {} is not supported!'.format(data_select)) + data_select = check_default_set(data_select, ('train', 'dev')) train, dev = raw.DATASETS[dataset_name](root=root) raw_data = {'train': [item for item in train], 'dev': [item for item in dev]} @@ -82,14 +76,14 @@ def apply_transform(data): for item in _answers: tok_ans += text_transform(item) yield text_transform(_context) + text_transform(_question) + tok_ans - vocab = build_vocab_from_iterator(apply_transform(raw_data['train'])) + vocab = build_vocab_from_iterator(apply_transform(raw_data['train']), len(raw_data['train'])) text_transform = sequential_transforms(text_transform, vocab_func(vocab), totensor(dtype=torch.long)) transforms = {'context': text_transform, 'question': text_transform, 'answers': text_transform, 'ans_pos': totensor(dtype=torch.long)} return tuple(QuestionAnswerDataset(raw_data[item], vocab, transforms) for item in data_select) -def SQuAD1(*args, **kwargs): +def SQuAD1(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev')): """ Defines SQuAD1 datasets. Create question answer dataset: SQuAD1 @@ -120,10 +114,10 @@ def SQuAD1(*args, **kwargs): >>> train, dev = SQuAD1(tokenizer=tokenizer) """ - return _setup_datasets(*(('SQuAD1',) + args), **kwargs) + return _setup_datasets('SQuAD1', root, vocab, tokenizer, data_select) -def SQuAD2(*args, **kwargs): +def SQuAD2(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev')): """ Defines SQuAD2 datasets. Create question answer dataset: SQuAD2 @@ -153,7 +147,7 @@ def SQuAD2(*args, **kwargs): >>> tokenizer = get_tokenizer("spacy") >>> train, dev = SQuAD2(tokenizer=tokenizer) """ - return _setup_datasets(*(('SQuAD2',) + args), **kwargs) + return _setup_datasets('SQuAD2', root, vocab, tokenizer, data_select) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/common.py b/torchtext/experimental/datasets/raw/common.py new file mode 100644 index 0000000000..9be6505168 --- /dev/null +++ b/torchtext/experimental/datasets/raw/common.py @@ -0,0 +1,53 @@ +import torch + + +def check_default_set(data_select, target_select): + if isinstance(data_select, str): + data_select = (data_select,) + if not set(data_select).issubset(set(target_select)): + raise TypeError('A subset of data selection {} is supported but {} is passed in'.format(target_select, + data_select)) + return data_select + + +class RawTextIterableDataset(torch.utils.data.IterableDataset): + """Defines an abstraction for raw text iterable datasets. + """ + + def __init__(self, name, full_num_lines, iterator): + """Initiate text-classification dataset. + """ + super(RawTextIterableDataset, self).__init__() + self.name = name + self.full_num_lines = full_num_lines + self._iterator = iterator + self.has_setup = False + self.start = 0 + self.num_lines = None + + def setup_iter(self, start=0, num_lines=None): + self.start = start + self.num_lines = num_lines + if num_lines and self.start + self.num_lines > self.full_num_lines: + raise ValueError("Requested start {} and num_lines {} exceeds available number of lines {}".format( + self.start, self.num_lines, self.full_num_lines)) + self.has_setup = True + + def __iter__(self): + if not self.has_setup: + self.setup_iter() + + for i, item in enumerate(self._iterator): + if i < self.start: + continue + if self.num_lines and i > (self.start + self.num_lines): + break + yield item + + def __len__(self): + if self.has_setup: + return self.num_lines + return self.full_num_lines + + def get_iterator(self): + return self._iterator diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py index a867108978..7f6e606118 100644 --- a/torchtext/experimental/datasets/raw/language_modeling.py +++ b/torchtext/experimental/datasets/raw/language_modeling.py @@ -1,7 +1,8 @@ -import torch import logging import io from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import check_default_set URLS = { 'WikiText2': @@ -16,38 +17,8 @@ } -class RawTextIterableDataset(torch.utils.data.IterableDataset): - """Defines an abstraction for raw text iterable datasets. - """ - - def __init__(self, iterator, start=0, num_lines=None): - """Initiate language modeling dataset. - """ - super(RawTextIterableDataset, self).__init__() - self._iterator = iterator - self.has_setup = False - self.start = start - self.num_lines = num_lines - - def setup_iter(self, start=0, num_lines=None): - self.start = start - self.num_lines = num_lines - self.has_setup = True - - def __iter__(self): - if not self.has_setup: - self.setup_iter() - for i, item in enumerate(self._iterator): - if i >= self.start: - yield item - if (self.num_lines is not None) and (i == (self.start + self.num_lines)): - break - - def get_iterator(self): - return self._iterator - - -def _setup_datasets(dataset_name, root='.data', data_select=('train', 'test', 'valid'), **kwargs): +def _setup_datasets(dataset_name, root, data_select, year, language): + data_select = check_default_set(data_select, ('train', 'test', 'valid')) if isinstance(data_select, str): data_select = [data_select] if not set(data_select).issubset(set(('train', 'test', 'valid'))): @@ -65,8 +36,6 @@ def _setup_datasets(dataset_name, root='.data', data_select=('train', 'test', 'v "or ('train',), got {}.".format(data_select)) dataset_tar = download_from_url(URLS[dataset_name], root=root) extracted_files = extract_archive(dataset_tar) - year = kwargs.get('year', 2010) - language = kwargs.get('language', 'en') file_name = 'news.{}.{}.shuffled'.format(year, language) extracted_files = [f for f in extracted_files if file_name in f] else: @@ -84,10 +53,10 @@ def _setup_datasets(dataset_name, root='.data', data_select=('train', 'test', 'v logging.info('Creating {} data'.format(item)) data[item] = iter(io.open(_path[item], encoding="utf8")) - return tuple(RawTextIterableDataset(data[item]) for item in data_select) + return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], data[item]) for item in data_select) -def WikiText2(*args, **kwargs): +def WikiText2(root='.data', data_select=('train', 'test', 'valid')): """ Defines WikiText2 datasets. Create language modeling dataset: WikiText2 @@ -110,10 +79,10 @@ def WikiText2(*args, **kwargs): """ - return _setup_datasets(*(("WikiText2",) + args), **kwargs) + return _setup_datasets("WikiText2", root, data_select, None, None) -def WikiText103(*args, **kwargs): +def WikiText103(root='.data', data_select=('train', 'test', 'valid')): """ Defines WikiText103 datasets. Create language modeling dataset: WikiText103 @@ -133,10 +102,10 @@ def WikiText103(*args, **kwargs): >>> valid_dataset, = WikiText103(data_select='valid') """ - return _setup_datasets(*(("WikiText103",) + args), **kwargs) + return _setup_datasets("WikiText103", root, data_select, None, None) -def PennTreebank(*args, **kwargs): +def PennTreebank(root='.data', data_select=('train', 'test', 'valid')): """ Defines PennTreebank datasets. Create language modeling dataset: PennTreebank @@ -159,10 +128,10 @@ def PennTreebank(*args, **kwargs): """ - return _setup_datasets(*(("PennTreebank",) + args), **kwargs) + return _setup_datasets("PennTreebank", root, data_select, None, None) -def WMTNewsCrawl(*args, **kwargs): +def WMTNewsCrawl(root='.data', data_select=('train'), year=2010, language='en'): """ Defines WMT News Crawl. Create language modeling dataset: WMTNewsCrawl @@ -171,9 +140,13 @@ def WMTNewsCrawl(*args, **kwargs): root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. (Default: 'train') + year: the year of the dataset (Default: 2010) + language: the language of the dataset (Default: 'en') + + Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. """ - return _setup_datasets(*(("WMTNewsCrawl",) + args), **kwargs) + return _setup_datasets("WMTNewsCrawl", root, data_select, year, language) DATASETS = { @@ -182,3 +155,9 @@ def WMTNewsCrawl(*args, **kwargs): 'PennTreebank': PennTreebank, 'WMTNewsCrawl': WMTNewsCrawl } +NUM_LINES = { + 'WikiText2': 36718, + 'WikiText103': 1801350, + 'PennTreebank': 42068, + 'WMTNewsCrawl': 17676013, +} diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py index e0b488eff1..4d80df96e9 100644 --- a/torchtext/experimental/datasets/raw/question_answer.py +++ b/torchtext/experimental/datasets/raw/question_answer.py @@ -1,14 +1,15 @@ -import torch from torchtext.utils import download_from_url import json +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import check_default_set URLS = { 'SQuAD1': - ['https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json', - 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json'], + {'train': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json', + 'dev': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json'}, 'SQuAD2': - ['https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json', - 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json'] + {'train': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json', + 'dev': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json'} } @@ -28,67 +29,67 @@ def _create_data_from_json(data_path): yield (_context, _question, _answers, _answer_start) -class RawQuestionAnswerDataset(torch.utils.data.IterableDataset): - """Defines an abstraction for raw question answer iterable datasets. - """ +def _setup_datasets(dataset_name, root, data_select): + data_select = check_default_set(data_select, ('train', 'dev')) + extracted_files = {key: download_from_url(URLS[dataset_name][key], + root=root) for key in data_select} + return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], + _create_data_from_json(extracted_files[item])) for item in data_select) + + +def SQuAD1(root='.data', data_select=('train', 'dev')): + """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD1.0. + The iterator yields a tuple of (raw context, raw question, a list of raw answer, + a list of answer positions in the raw context). + For example, ('Architecturally, the school has a Catholic character. Atop the ...', + 'To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?', + ['Saint Bernadette Soubirous'], + [515]) - def __init__(self, iterator): - """Initiate text-classification dataset. - """ - super(RawQuestionAnswerDataset, self).__init__() - self._iterator = iterator - self.has_setup = False - self.start = 0 - self.num_lines = None - - def setup_iter(self, start=0, num_lines=None): - self.start = start - self.num_lines = num_lines - self.has_setup = True - - def __iter__(self): - if not self.has_setup: - self.setup_iter() - - for i, item in enumerate(self._iterator): - if i >= self.start: - yield item - if self.num_lines is not None and i == (self.start + self.num_lines): - break - - -def _setup_datasets(dataset_name, root='.data'): - extracted_files = [] - select_to_index = {'train': 0, 'dev': 1} - extracted_files = [download_from_url(URLS[dataset_name][select_to_index[key]], - root=root) for key in select_to_index.keys()] - train_iter = _create_data_from_json(extracted_files[0]) - dev_iter = _create_data_from_json(extracted_files[1]) - return (RawQuestionAnswerDataset(train_iter), - RawQuestionAnswerDataset(dev_iter)) - - -def SQuAD1(*args, **kwargs): - """ Defines SQuAD1 datasets. + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets (Default: ('train', 'dev')) + By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, + for example ('train', 'dev') or just a string 'train'. Examples: - >>> train, dev = torchtext.experimental.datasets.raw.SQuAD1() + >>> train_dataset, dev_dataset = torchtext.experimental.datasets.raw.SQuAD1() + >>> for idx, (context, question, answer, ans_pos) in enumerate(train_dataset): + >>> print(idx, (context, question, answer, ans_pos)) """ - return _setup_datasets(*(("SQuAD1",) + args), **kwargs) + return _setup_datasets("SQuAD1", root, data_select) -def SQuAD2(*args, **kwargs): - """ Defines SQuAD2 datasets. +def SQuAD2(root='.data', data_select=('train', 'dev')): + """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD2.0. + The iterator yields a tuple of (raw context, raw question, a list of raw answer, + a list of answer positions in the raw context). + For example, ('Beyoncé Giselle Knowles-Carter (/biːˈjɒnseɪ/ bee-YON-say) (born September 4, 1981) is an ...', + 'When did Beyonce start becoming popular?', + ['in the late 1990s'], + [269]) + + Arguments: + root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets (Default: ('train', 'dev')) + By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, + for example ('train', 'dev') or just a string 'train'. Examples: - >>> train, dev = torchtext.experimental.datasets.raw.SQuAD2() + >>> train_dataset, dev_dataset = torchtext.experimental.datasets.raw.SQuAD2() + >>> for idx, (context, question, answer, ans_pos) in enumerate(train_dataset): + >>> print(idx, (context, question, answer, ans_pos)) """ - return _setup_datasets(*(("SQuAD2",) + args), **kwargs) + return _setup_datasets("SQuAD2", root, data_select) DATASETS = { 'SQuAD1': SQuAD1, 'SQuAD2': SQuAD2 } +NUM_LINES = { + 'SQuAD1': 87599, + 'SQuAD2': 130319 +} diff --git a/torchtext/experimental/datasets/raw/sequence_tagging.py b/torchtext/experimental/datasets/raw/sequence_tagging.py index b4576e7f81..e45688f07b 100644 --- a/torchtext/experimental/datasets/raw/sequence_tagging.py +++ b/torchtext/experimental/datasets/raw/sequence_tagging.py @@ -1,6 +1,6 @@ -import torch - from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import check_default_set URLS = { "UDPOS": @@ -39,8 +39,8 @@ def _construct_filepath(paths, file_suffix): return None -def _setup_datasets(dataset_name, separator, root=".data"): - +def _setup_datasets(dataset_name, separator, root, data_select): + data_select = check_default_set(data_select, target_select=('train', 'valid', 'test')) extracted_files = [] if isinstance(URLS[dataset_name], list): for f in URLS[dataset_name]: @@ -59,78 +59,54 @@ def _setup_datasets(dataset_name, separator, root=".data"): "valid": _construct_filepath(extracted_files, "dev.txt"), "test": _construct_filepath(extracted_files, "test.txt") } + return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], + _create_data_from_iob(data_filenames[item], separator)) + if data_filenames[item] is not None else None for item in data_select) - datasets = [] - for key in data_filenames.keys(): - if data_filenames[key] is not None: - datasets.append( - RawSequenceTaggingIterableDataset( - _create_data_from_iob(data_filenames[key], separator))) - else: - datasets.append(None) - - return datasets - - -class RawSequenceTaggingIterableDataset(torch.utils.data.IterableDataset): - """Defines an abstraction for raw text sequence tagging iterable datasets. - """ - def __init__(self, iterator): - super(RawSequenceTaggingIterableDataset).__init__() - - self._iterator = iterator - self.has_setup = False - self.start = 0 - self.num_lines = None - - def setup_iter(self, start=0, num_lines=None): - self.start = start - self.num_lines = num_lines - self.has_setup = True - def __iter__(self): - if not self.has_setup: - self.setup_iter() - - for i, item in enumerate(self._iterator): - if i >= self.start: - yield item - if (self.num_lines is not None) and (i == (self.start + - self.num_lines)): - break - - def get_iterator(self): - return self._iterator - - -def UDPOS(*args, **kwargs): +def UDPOS(root=".data", data_select=('train', 'valid', 'test')): """ Universal Dependencies English Web Treebank Separately returns the training and test dataset Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets (Default: ('train', 'valid', 'test')) + By default, all the datasets (train, valid, test) are generated. + Users could also choose any one or two of them, + for example ('train', 'valid', 'test') or just a string 'train'. Examples: - >>> from torchtext.datasets.raw import UDPOS + >>> from torchtext.experimental.datasets.raw import UDPOS >>> train_dataset, valid_dataset, test_dataset = UDPOS() """ - return _setup_datasets(*(("UDPOS", "\t") + args), **kwargs) + return _setup_datasets("UDPOS", "\t", root, data_select) -def CoNLL2000Chunking(*args, **kwargs): +def CoNLL2000Chunking(root=".data", data_select=('train', 'test')): """ CoNLL 2000 Chunking Dataset Separately returns the training and test dataset Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets (Default: ('train', 'test')) + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: - >>> from torchtext.datasets.raw import CoNLL2000Chunking - >>> train_dataset, valid_dataset, test_dataset = CoNLL2000Chunking() + >>> from torchtext.experimental.datasets.raw import CoNLL2000Chunking + >>> train_dataset, test_dataset = CoNLL2000Chunking() """ - return _setup_datasets(*(("CoNLL2000Chunking", " ") + args), **kwargs) + return _setup_datasets("CoNLL2000Chunking", " ", root, data_select) -DATASETS = {"UDPOS": UDPOS, "CoNLL2000Chunking": CoNLL2000Chunking} +DATASETS = { + "UDPOS": UDPOS, + "CoNLL2000Chunking": CoNLL2000Chunking +} + +NUM_LINES = { + "UDPOS": 12543, + "CoNLL2000Chunking": 8936 +} diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py index d48cb6c812..5d114acf27 100644 --- a/torchtext/experimental/datasets/raw/text_classification.py +++ b/torchtext/experimental/datasets/raw/text_classification.py @@ -1,10 +1,12 @@ -import torch import io from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import check_default_set URLS = { 'AG_NEWS': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUDNpeUdjb0wxRms', + {'train': 'https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv', + 'test': 'https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv'}, 'SogouNews': 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE', 'DBpedia': @@ -31,55 +33,24 @@ def _create_data_from_csv(data_path): yield int(row[0]), ' '.join(row[1:]) -class RawTextIterableDataset(torch.utils.data.IterableDataset): - """Defines an abstraction for raw text iterable datasets. - """ - - def __init__(self, iterator): - """Initiate text-classification dataset. - """ - super(RawTextIterableDataset, self).__init__() - self._iterator = iterator - self.has_setup = False - self.start = 0 - self.num_lines = None - - def setup_iter(self, start=0, num_lines=None): - self.start = start - self.num_lines = num_lines - self.has_setup = True - - def __iter__(self): - if not self.has_setup: - self.setup_iter() - - for i, item in enumerate(self._iterator): - if i >= self.start: - yield item - if self.num_lines is not None and i == (self.start + self.num_lines): - break - - def get_iterator(self): - return self._iterator - - -def _setup_datasets(dataset_name, root='.data'): - dataset_tar = download_from_url(URLS[dataset_name], root=root) - extracted_files = extract_archive(dataset_tar) - +def _setup_datasets(dataset_name, root, data_select): + data_select = check_default_set(data_select, target_select=('train', 'test')) + if dataset_name == 'AG_NEWS': + extracted_files = [download_from_url(URLS[dataset_name][item], root=root) for item in ('train', 'test')] + else: + dataset_tar = download_from_url(URLS[dataset_name], root=root) + extracted_files = extract_archive(dataset_tar) + cvs_path = {} for fname in extracted_files: if fname.endswith('train.csv'): - train_csv_path = fname + cvs_path['train'] = fname if fname.endswith('test.csv'): - test_csv_path = fname - - train_iter = _create_data_from_csv(train_csv_path) - test_iter = _create_data_from_csv(test_csv_path) - return (RawTextIterableDataset(train_iter), - RawTextIterableDataset(test_iter)) + cvs_path['test'] = fname + return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], + _create_data_from_csv(cvs_path[item])) for item in data_select) -def AG_NEWS(*args, **kwargs): +def AG_NEWS(root='.data', data_select=('train', 'test')): """ Defines AG_NEWS datasets. Create supervised learning dataset: AG_NEWS @@ -88,15 +59,18 @@ def AG_NEWS(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.AG_NEWS() """ - return _setup_datasets(*(("AG_NEWS",) + args), **kwargs) + return _setup_datasets("AG_NEWS", root, data_select) -def SogouNews(*args, **kwargs): +def SogouNews(root='.data', data_select=('train', 'test')): """ Defines SogouNews datasets. Create supervised learning dataset: SogouNews @@ -105,15 +79,18 @@ def SogouNews(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.SogouNews() """ - return _setup_datasets(*(("SogouNews",) + args), **kwargs) + return _setup_datasets("SogouNews", root, data_select) -def DBpedia(*args, **kwargs): +def DBpedia(root='.data', data_select=('train', 'test')): """ Defines DBpedia datasets. Create supervised learning dataset: DBpedia @@ -122,15 +99,18 @@ def DBpedia(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.DBpedia() """ - return _setup_datasets(*(("DBpedia",) + args), **kwargs) + return _setup_datasets("DBpedia", root, data_select) -def YelpReviewPolarity(*args, **kwargs): +def YelpReviewPolarity(root='.data', data_select=('train', 'test')): """ Defines YelpReviewPolarity datasets. Create supervised learning dataset: YelpReviewPolarity @@ -139,15 +119,18 @@ def YelpReviewPolarity(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.YelpReviewPolarity() """ - return _setup_datasets(*(("YelpReviewPolarity",) + args), **kwargs) + return _setup_datasets("YelpReviewPolarity", root, data_select) -def YelpReviewFull(*args, **kwargs): +def YelpReviewFull(root='.data', data_select=('train', 'test')): """ Defines YelpReviewFull datasets. Create supervised learning dataset: YelpReviewFull @@ -156,15 +139,18 @@ def YelpReviewFull(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.YelpReviewFull() """ - return _setup_datasets(*(("YelpReviewFull",) + args), **kwargs) + return _setup_datasets("YelpReviewFull", root, data_select) -def YahooAnswers(*args, **kwargs): +def YahooAnswers(root='.data', data_select=('train', 'test')): """ Defines YahooAnswers datasets. Create supervised learning dataset: YahooAnswers @@ -173,15 +159,18 @@ def YahooAnswers(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.YahooAnswers() """ - return _setup_datasets(*(("YahooAnswers",) + args), **kwargs) + return _setup_datasets("YahooAnswers", root, data_select) -def AmazonReviewPolarity(*args, **kwargs): +def AmazonReviewPolarity(root='.data', data_select=('train', 'test')): """ Defines AmazonReviewPolarity datasets. Create supervised learning dataset: AmazonReviewPolarity @@ -190,15 +179,18 @@ def AmazonReviewPolarity(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewPolarity() """ - return _setup_datasets(*(("AmazonReviewPolarity",) + args), **kwargs) + return _setup_datasets("AmazonReviewPolarity", root, data_select) -def AmazonReviewFull(*args, **kwargs): +def AmazonReviewFull(root='.data', data_select=('train', 'test')): """ Defines AmazonReviewFull datasets. Create supervised learning dataset: AmazonReviewFull @@ -207,12 +199,15 @@ def AmazonReviewFull(*args, **kwargs): Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewFull() """ - return _setup_datasets(*(("AmazonReviewFull",) + args), **kwargs) + return _setup_datasets("AmazonReviewFull", root, data_select) def generate_imdb_data(key, extracted_files): @@ -221,30 +216,32 @@ def generate_imdb_data(key, extracted_files): continue elif key in fname and ('pos' in fname or 'neg' in fname): with io.open(fname, encoding="utf8") as f: - label = 1 if 'pos' in fname else 0 + label = 'pos' if 'pos' in fname else 'neg' yield label, f.read() -def IMDB(root='.data'): - """ Defines IMDB datasets. +def IMDB(root='.data', data_select=('train', 'test')): + """ Defines raw IMDB datasets. Create supervised learning dataset: IMDB - Separately returns the training and test dataset + Separately returns the raw training and test dataset Arguments: root: Directory where the datasets are saved. Default: ".data" + data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, + for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.IMDB() """ - + data_select = check_default_set(data_select, target_select=('train', 'test')) dataset_tar = download_from_url(URLS['IMDB'], root=root) extracted_files = extract_archive(dataset_tar) - train_iter = generate_imdb_data('train', extracted_files) - test_iter = generate_imdb_data('test', extracted_files) - return (RawTextIterableDataset(train_iter), - RawTextIterableDataset(test_iter)) + return tuple(RawTextIterableDataset("IMDB", NUM_LINES["IMDB"], + generate_imdb_data(item, + extracted_files)) for item in data_select) DATASETS = { @@ -258,3 +255,14 @@ def IMDB(root='.data'): 'AmazonReviewFull': AmazonReviewFull, 'IMDB': IMDB } +NUM_LINES = { + 'AG_NEWS': 120000, + 'SogouNews': 450000, + 'DBpedia': 560000, + 'YelpReviewPolarity': 560000, + 'YelpReviewFull': 650000, + 'YahooAnswers': 1400000, + 'AmazonReviewPolarity': 3600000, + 'AmazonReviewFull': 3000000, + 'IMDB': 25000 +} diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py index 19f5275d41..4d01b68f11 100644 --- a/torchtext/experimental/datasets/raw/translation.py +++ b/torchtext/experimental/datasets/raw/translation.py @@ -1,12 +1,12 @@ -import torch import os import io import codecs import xml.etree.ElementTree as ET from collections import defaultdict - from torchtext.utils import (download_from_url, extract_archive, unicode_csv_reader) +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import check_default_set URLS = { 'Multi30k': [ @@ -117,14 +117,12 @@ def _construct_filepaths(paths, src_filename, tgt_filename): def _setup_datasets(dataset_name, - train_filenames, - valid_filenames, - test_filenames, - root='.data'): + train_filenames, valid_filenames, test_filenames, + data_select, root): + data_select = check_default_set(data_select, ('train', 'valid', 'test')) if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ and not isinstance(test_filenames, tuple): raise ValueError("All filenames must be tuples") - src_train, tgt_train = train_filenames src_eval, tgt_eval = valid_filenames src_test, tgt_test = test_filenames @@ -167,53 +165,24 @@ def _setup_datasets(dataset_name, "Files are not found for data type {}".format(key)) datasets = [] - for key in data_filenames.keys(): + for key in data_select: src_data_iter = _read_text_iterator(data_filenames[key][0]) tgt_data_iter = _read_text_iterator(data_filenames[key][1]) + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item + datasets.append( - RawTranslationIterableDataset(src_data_iter, tgt_data_iter)) + RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], _iter(src_data_iter, tgt_data_iter))) return tuple(datasets) -class RawTranslationIterableDataset(torch.utils.data.IterableDataset): - """Defines an abstraction for raw text iterable datasets. - """ - def __init__(self, src_iterator, tgt_iterator): - """Initiate text-classification dataset. - """ - super(RawTranslationIterableDataset, self).__init__() - self._src_iterator = src_iterator - self._tgt_iterator = tgt_iterator - self.has_setup = False - self.start = 0 - self.num_lines = None - - def setup_iter(self, start=0, num_lines=None): - self.start = start - self.num_lines = num_lines - self.has_setup = True - - def __iter__(self): - if not self.has_setup: - self.setup_iter() - - for i, item in enumerate(zip(self._src_iterator, self._tgt_iterator)): - if i >= self.start: - yield item - if (self.num_lines is not None) and (i == (self.start + - self.num_lines)): - break - - def get_iterator(self): - return (self._src_iterator, self._tgt_iterator) - - def Multi30k(train_filenames=("train.de", "train.en"), valid_filenames=("val.de", "val.en"), test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), - root='.data'): + data_select=('train', 'valid', 'test'), root='.data'): """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple The available dataset include: @@ -274,17 +243,18 @@ def Multi30k(train_filenames=("train.de", "train.en"), Default: ('val.de', 'val.en') test_filenames: the source and target filenames for test. Default: ('test2016.de', 'test2016.en') + data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + By default, all the three datasets (train, valid, test) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" Examples: >>> from torchtext.datasets import Multi30k >>> train_dataset, valid_dataset, test_dataset = Multi30k() """ - return _setup_datasets("Multi30k", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root) + return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, data_select, root) def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), @@ -292,7 +262,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), 'IWSLT16.TED.tst2013.de-en.en'), test_filenames=('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en'), - root='.data'): + data_select=('train', 'valid', 'test'), root='.data'): """ Define translation datasets: IWSLT Separately returns train/valid/test datasets The available datasets include: @@ -439,6 +409,11 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') test_filenames: the source and target filenames for test. Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') + data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + By default, all the three datasets (train, valid, test) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" Examples: @@ -449,14 +424,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), tgt_language = train_filenames[1].split(".")[-1] languages = "-".join([src_language, tgt_language]) URLS["IWSLT"] = URLS["IWSLT"].format(src_language, tgt_language, languages) - - return _setup_datasets( - "IWSLT", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root, - ) + return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, data_select, root) def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', @@ -465,7 +433,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', 'newstest2013.tok.bpe.32000.en'), test_filenames=('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en'), - root='.data'): + data_select=('train', 'valid', 'test'), root='.data'): """ Define translation datasets: WMT14 Separately returns train/valid/test datasets The available datasets include: @@ -527,18 +495,27 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') test_filenames: the source and target filenames for test. Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') + data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + By default, all the three datasets (train, valid, test) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" Examples: >>> from torchtext.datasets import WMT14 >>> train_dataset, valid_dataset, test_dataset = WMT14() """ + return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, data_select, root) - return _setup_datasets("WMT14", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root) - -DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} +DATASETS = { + 'Multi30k': Multi30k, + 'IWSLT': IWSLT, + 'WMT14': WMT14 +} +NUM_LINES = { + 'Multi30k': 29000, + 'IWSLT': 173939, + 'WMT14': 4500966, +} diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index 41df4f6ba4..7bed1f647b 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -1,5 +1,5 @@ import torch - +from torchtext.experimental.datasets.raw.common import check_default_set from torchtext.experimental.datasets import raw from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.functional import ( @@ -18,26 +18,17 @@ def build_vocab(data): for idx, col in enumerate(line): data_list[idx].append(col) for it in data_list: - vocabs.append(build_vocab_from_iterator(it)) + vocabs.append(build_vocab_from_iterator(it, len(it))) return vocabs -def _setup_datasets(dataset_name, - root=".data", - vocabs=None, - data_select=("train", "valid", "test")): - if isinstance(data_select, str): - data_select = [data_select] - if not set(data_select).issubset(set(("train", "valid", "test"))): - raise TypeError("Given data selection {} is not supported!".format(data_select)) - - train, val, test = raw.DATASETS[dataset_name](root=root) - raw_data = { - "train": [line for line in train] if train else None, - "valid": [line for line in val] if val else None, - "test": [line for line in test] if test else None - } +def _setup_datasets(dataset_name, root, vocabs, data_select): + data_select = check_default_set(data_select, ('train', 'valid', 'test')) + raw_iter_tuple = raw.DATASETS[dataset_name](root=root, data_select=data_select) + raw_data = {} + for name, raw_iter in zip(data_select, raw_iter_tuple): + raw_data[name] = list(raw_iter) if vocabs is None: if "train" not in data_select: @@ -63,14 +54,7 @@ def _setup_datasets(dataset_name, totensor(dtype=torch.long)) for idx in range(len(vocabs)) ] - - datasets = [] - for item in data_select: - if raw_data[item] is not None: - datasets.append( - SequenceTaggingDataset(raw_data[item], vocabs, transformers)) - - return datasets + return tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in data_select) class SequenceTaggingDataset(torch.utils.data.Dataset): @@ -116,7 +100,7 @@ def get_vocabs(self): return self.vocabs -def UDPOS(*args, **kwargs): +def UDPOS(root=".data", vocabs=None, data_select=("train", "valid", "test")): """ Universal Dependencies English Web Treebank Separately returns the training, validation, and test dataset @@ -138,10 +122,10 @@ def UDPOS(*args, **kwargs): >>> from torchtext.datasets.raw import UDPOS >>> train_dataset, valid_dataset, test_dataset = UDPOS() """ - return _setup_datasets(*(("UDPOS", ) + args), **kwargs) + return _setup_datasets("UDPOS", root, vocabs, data_select) -def CoNLL2000Chunking(*args, **kwargs): +def CoNLL2000Chunking(root=".data", vocabs=None, data_select=("train", "test")): """ CoNLL 2000 Chunking Dataset Separately returns the training and test dataset @@ -152,8 +136,8 @@ def CoNLL2000Chunking(*args, **kwargs): instance of List Default: None data_select: a string or tuple for the returned datasets - (Default: ('train', 'valid', 'test')) - By default, all the three datasets (train, test, valid) are generated. Users + (Default: ('train', 'test')) + By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test @@ -161,9 +145,9 @@ def CoNLL2000Chunking(*args, **kwargs): Examples: >>> from torchtext.datasets.raw import CoNLL2000Chunking - >>> train_dataset, valid_dataset, test_dataset = CoNLL2000Chunking() + >>> train_dataset, test_dataset = CoNLL2000Chunking() """ - return _setup_datasets(*(("CoNLL2000Chunking", ) + args), **kwargs) + return _setup_datasets("CoNLL2000Chunking", root, vocabs, data_select) DATASETS = {"UDPOS": UDPOS, "CoNLL2000Chunking": CoNLL2000Chunking} diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index c54c9c4032..4374ad2594 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -2,6 +2,7 @@ from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.datasets.raw import text_classification as raw +from torchtext.experimental.datasets.raw.common import check_default_set from torchtext.experimental.functional import ( vocab_func, totensor, @@ -14,7 +15,7 @@ def build_vocab(data, transforms): def apply_transforms(data): for _, line in data: yield transforms(line) - return build_vocab_from_iterator(apply_transforms(data)) + return build_vocab_from_iterator(apply_transforms(data), len(data)) class TextClassificationDataset(torch.utils.data.Dataset): @@ -64,23 +65,12 @@ def get_vocab(self): return self.vocab -def _setup_datasets( - dataset_name, - root=".data", - ngrams=1, - vocab=None, - tokenizer=None, - data_select=("train", "test"), -): +def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, data_select): text_transform = [] if tokenizer is None: tokenizer = get_tokenizer("basic_english") text_transform = sequential_transforms(tokenizer, ngrams_func(ngrams)) - - if isinstance(data_select, str): - data_select = [data_select] - if not set(data_select).issubset(set(("train", "test"))): - raise TypeError("Given data selection {} is not supported!".format(data_select)) + data_select = check_default_set(data_select, ('train', 'test')) train, test = raw.DATASETS[dataset_name](root=root) # Cache raw text iterable dataset raw_data = { @@ -95,7 +85,10 @@ def _setup_datasets( text_transform = sequential_transforms( text_transform, vocab_func(vocab), totensor(dtype=torch.long) ) - label_transform = sequential_transforms(totensor(dtype=torch.long)) + if dataset_name == 'IMDB': + label_transform = sequential_transforms(lambda x: 1 if x == 'pos' else 0, totensor(dtype=torch.long)) + else: + label_transform = sequential_transforms(totensor(dtype=torch.long)) return tuple( TextClassificationDataset( raw_data[item], vocab, (label_transform, text_transform) @@ -104,7 +97,7 @@ def _setup_datasets( ) -def AG_NEWS(*args, **kwargs): +def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines AG_NEWS datasets. The labels includes: - 1 : World @@ -144,10 +137,10 @@ def AG_NEWS(*args, **kwargs): """ - return _setup_datasets(*(("AG_NEWS",) + args), **kwargs) + return _setup_datasets("AG_NEWS", root, ngrams, vocab, tokenizer, data_select) -def SogouNews(*args, **kwargs): +def SogouNews(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines SogouNews datasets. The labels includes: - 1 : Sports @@ -188,10 +181,10 @@ def SogouNews(*args, **kwargs): """ - return _setup_datasets(*(("SogouNews",) + args), **kwargs) + return _setup_datasets("SogouNews", root, ngrams, vocab, tokenizer, data_select) -def DBpedia(*args, **kwargs): +def DBpedia(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines DBpedia datasets. The labels includes: - 1 : Company @@ -241,10 +234,10 @@ def DBpedia(*args, **kwargs): """ - return _setup_datasets(*(("DBpedia",) + args), **kwargs) + return _setup_datasets("DBpedia", root, ngrams, vocab, tokenizer, data_select) -def YelpReviewPolarity(*args, **kwargs): +def YelpReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines YelpReviewPolarity datasets. The labels includes: - 1 : Negative polarity. @@ -282,10 +275,10 @@ def YelpReviewPolarity(*args, **kwargs): """ - return _setup_datasets(*(("YelpReviewPolarity",) + args), **kwargs) + return _setup_datasets("YelpReviewPolarity", root, ngrams, vocab, tokenizer, data_select) -def YelpReviewFull(*args, **kwargs): +def YelpReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines YelpReviewFull datasets. The labels includes: 1 - 5 : rating classes (5 is highly recommended). @@ -322,10 +315,10 @@ def YelpReviewFull(*args, **kwargs): """ - return _setup_datasets(*(("YelpReviewFull",) + args), **kwargs) + return _setup_datasets("YelpReviewFull", root, ngrams, vocab, tokenizer, data_select) -def YahooAnswers(*args, **kwargs): +def YahooAnswers(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines YahooAnswers datasets. The labels includes: - 1 : Society & Culture @@ -371,10 +364,10 @@ def YahooAnswers(*args, **kwargs): """ - return _setup_datasets(*(("YahooAnswers",) + args), **kwargs) + return _setup_datasets("YahooAnswers", root, ngrams, vocab, tokenizer, data_select) -def AmazonReviewPolarity(*args, **kwargs): +def AmazonReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines AmazonReviewPolarity datasets. The labels includes: - 1 : Negative polarity @@ -412,10 +405,10 @@ def AmazonReviewPolarity(*args, **kwargs): """ - return _setup_datasets(*(("AmazonReviewPolarity",) + args), **kwargs) + return _setup_datasets("AmazonReviewPolarity", root, ngrams, vocab, tokenizer, data_select) -def AmazonReviewFull(*args, **kwargs): +def AmazonReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines AmazonReviewFull datasets. The labels includes: 1 - 5 : rating classes (5 is highly recommended) @@ -452,10 +445,10 @@ def AmazonReviewFull(*args, **kwargs): """ - return _setup_datasets(*(("AmazonReviewFull",) + args), **kwargs) + return _setup_datasets("AmazonReviewFull", root, ngrams, vocab, tokenizer, data_select) -def IMDB(*args, **kwargs): +def IMDB(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): """ Defines IMDB datasets. The labels includes: - 0 : Negative @@ -494,7 +487,7 @@ def IMDB(*args, **kwargs): """ - return _setup_datasets(*(("IMDB",) + args), **kwargs) + return _setup_datasets("IMDB", root, ngrams, vocab, tokenizer, data_select) DATASETS = { diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index 765d102877..8f1473e933 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -1,6 +1,6 @@ import torch import logging - +from torchtext.experimental.datasets.raw.common import check_default_set from torchtext.experimental.datasets import raw from torchtext.vocab import Vocab, build_vocab_from_iterator from torchtext.data.utils import get_tokenizer @@ -11,18 +11,13 @@ def build_vocab(data, transforms, index): def apply_transforms(data): for line in data: yield transforms(line[index]) - return build_vocab_from_iterator(apply_transforms(data)) + return build_vocab_from_iterator(apply_transforms(data), len(data)) def _setup_datasets(dataset_name, - train_filenames, - valid_filenames, - test_filenames, - data_select=('train', 'test', 'valid'), - root='.data', - vocab=(None, None), - tokenizer=None, - removed_tokens=['']): + train_filenames, valid_filenames, test_filenames, + data_select, root, vocab, tokenizer): + data_select = check_default_set(data_select, ('train', 'valid', 'test')) src_vocab, tgt_vocab = vocab if tokenizer is None: src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') @@ -140,11 +135,11 @@ def get_vocab(self): def Multi30k(train_filenames=("train.de", "train.en"), valid_filenames=("val.de", "val.en"), test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), - tokenizer=None, + data_select=('train', 'valid', 'test'), root='.data', vocab=(None, None), - data_select=('train', 'valid', 'test'), - removed_tokens=['']): + tokenizer=None): + """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple @@ -155,23 +150,21 @@ def Multi30k(train_filenames=("train.de", "train.en"), Default: ('val.de', 'val.en') test_filenames: the source and target filenames for test. Default: ('test2016.de', 'test2016.en') - tokenizer: the tokenizer used to preprocess source and target raw text data. - It has to be in a form of tuple. - Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) + data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + By default, all the three datasets (train, valid, test) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" vocab: Source and target Vocabulary objects used for dataset. If None, it will generate a new vocabulary based on the train data set. It has to be in a form of tuple. Default: (None, None) - data_select: a string or tuple for the returned datasets - (Default: ('train', 'valid', 'test')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - removed_tokens: removed tokens from output dataset (Default: '') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + The available dataset include: test_2016_flickr.cs test_2016_flickr.de @@ -232,15 +225,8 @@ def Multi30k(train_filenames=("train.de", "train.en"), >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] """ - return _setup_datasets("Multi30k", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - data_select=data_select, - tokenizer=tokenizer, - root=root, - vocab=vocab, - removed_tokens=removed_tokens) + return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, + data_select, root, vocab, tokenizer) def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), @@ -248,11 +234,11 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), 'IWSLT16.TED.tst2013.de-en.en'), test_filenames=('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en'), - tokenizer=None, + data_select=('train', 'valid', 'test'), root='.data', vocab=(None, None), - data_select=('train', 'valid', 'test'), - removed_tokens=['']): + tokenizer=None): + """ Define translation datasets: IWSLT Separately returns train/valid/test datasets The available datasets include: @@ -264,23 +250,21 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') test_filenames: the source and target filenames for test. Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') - tokenizer: the tokenizer used to preprocess source and target raw text data. - It has to be in a form of tuple. - Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) + data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + By default, all the three datasets (train, valid, test) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" vocab: Source and target Vocabulary objects used for dataset. If None, it will generate a new vocabulary based on the train data set. It has to be in a form of tuple. Default: (None, None) - data_select: a string or tuple for the returned datasets - (Default: ('train', 'valid', 'test')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - removed_tokens: removed tokens from output dataset (Default: '') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + The available datasets include: IWSLT16.TED.dev2010.ar-en.ar IWSLT16.TED.dev2010.ar-en.en @@ -428,16 +412,8 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] """ - - return _setup_datasets("IWSLT", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - data_select=data_select, - tokenizer=tokenizer, - root=root, - vocab=vocab, - removed_tokens=removed_tokens) + return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, + data_select, root, vocab, tokenizer) def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', @@ -446,11 +422,11 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', 'newstest2013.tok.bpe.32000.en'), test_filenames=('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en'), - tokenizer=None, + data_select=('train', 'valid', 'test'), root='.data', vocab=(None, None), - data_select=('train', 'valid', 'test'), - removed_tokens=['']): + tokenizer=None): + """ Define translation datasets: WMT14 Separately returns train/valid/test datasets The available datasets include: @@ -512,23 +488,20 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') test_filenames: the source and target filenames for test. Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') - tokenizer: the tokenizer used to preprocess source and target raw text data. - It has to be in a form of tuple. - Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) + data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + By default, all the three datasets (train, valid, test) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" vocab: Source and target Vocabulary objects used for dataset. If None, it will generate a new vocabulary based on the train data set. It has to be in a form of tuple. Default: (None, None) - data_select: a string or tuple for the returned datasets - (Default: ('train', 'valid', 'test')) - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - removed_tokens: removed tokens from output dataset (Default: '') + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) Examples: >>> from torchtext.datasets import WMT14 @@ -540,16 +513,8 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] """ - - return _setup_datasets("WMT14", - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - data_select=data_select, - tokenizer=tokenizer, - root=root, - vocab=vocab, - removed_tokens=removed_tokens) + return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, + data_select, root, vocab, tokenizer) DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 0473c57516..011f1bf165 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -14,7 +14,7 @@ 'BasicEnglishNormalize', 'RegexTokenizer', 'TextSequentialTransforms', - 'pretrained_sp_model', + 'PRETRAINED_SP_MODEL', 'load_sp_model', 'sentencepiece_tokenizer', 'SentencePieceTokenizer', @@ -185,7 +185,7 @@ def to_ivalue(self): return TextSequentialTransforms(OrderedDict(module_list)) -pretrained_sp_model = { +PRETRAINED_SP_MODEL = { 'text_unigram_15000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_15000.model', 'text_unigram_25000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_25000.model', 'text_unigram_50000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_50000.model', @@ -221,8 +221,8 @@ def load_sp_model(sp_model): - text_bpe_50000 Examples: - >>> from torchtext.experimental.transforms import pretrained_sp_model - >>> sp_model_path = torchtext.utils.download_from_url(pretrained_sp_model['text_unigram_25000']) + >>> from torchtext.experimental.transforms import PRETRAINED_SP_MODEL + >>> sp_model_path = torchtext.utils.download_from_url(PRETRAINED_SP_MODEL['text_unigram_25000']) >>> sp_model = load_sp_model(sp_model_path) """ if isinstance(sp_model, str): diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 001e64405c..5fdf5751ec 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -1,7 +1,7 @@ import logging from typing import Dict, List import warnings - +from collections import Counter, OrderedDict import torch import torch.nn as nn from torchtext._torchtext import ( @@ -77,6 +77,25 @@ def vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4): return Vocab(vocab_obj) +def build_vocab_from_iterator(iterator, min_freq=1, unk_token=''): + """ + Build a Vocab from an iterator. + Arguments: + iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. + min_freq: The minimum frequency needed to include a token in the vocabulary. + Values less than 1 will be set to 1. Default: 1. + unk_token: The default unknown token to use. Default: ''. + """ + + counter = Counter() + for tokens in iterator: + counter.update(tokens) + sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) + ordered_dict = OrderedDict(sorted_by_freq_tuples) + word_vocab = vocab(ordered_dict, min_freq=min_freq, unk_token=unk_token) + return word_vocab + + def vocab(ordered_dict, min_freq=1, unk_token=''): r"""Factory method for creating a vocab object which maps tokens to indices. diff --git a/torchtext/vocab.py b/torchtext/vocab.py index 3a03317b69..59f63105b5 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -542,16 +542,20 @@ def __getitem__(self, token): """Mapping from string name to factory function""" -def build_vocab_from_iterator(iterator): +def build_vocab_from_iterator(iterator, num_lines=None): """ Build a Vocab from an iterator. Arguments: iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. + num_lines: The expected number of elements returned by the iterator. + (Default: None) + Optionally, if known, the expected number of elements can be passed to + this factory function for improved progress reporting. """ counter = Counter() - with tqdm(unit_scale=0, unit='lines') as t: + with tqdm(unit_scale=0, unit='lines', total=num_lines) as t: for tokens in iterator: counter.update(tokens) t.update(1) From b074e00bf2dd371c39e5e8a2ad54c9a6d4bbf6ce Mon Sep 17 00:00:00 2001 From: Brian Hirsh Date: Mon, 16 Nov 2020 14:32:48 -0800 Subject: [PATCH 30/68] make duplicate def() calls an error in the dispatcher. Updating all fb operators to use the new dispatcher registration API (#47322) Summary: Pull Request resolved: https://github.com/pytorch/pytorch/pull/47322 Updating all call-sites of the legacy dispatcher registration API in fbcode to the new API. I migrated all call sites that used the legacy dispatcher registration API (RegisterOperators()) to use the new API (TORCH_LIBRARY...). I found all call-sites by running `fbgs RegisterOperators()`. This includes several places, including other OSS code (nestedtensor, torchtext, torchvision). A few things to call out: For simple ops that only had one registered kernel without a dispatch key, I replaced them with: ``` TORCH_LIBRARY_FRAGMENT(ns, m) { m.def("opName", fn_name); } ``` For ops that registered to a specific dispatch key / had multiple kernels registered, I registered the common kernel (math/cpu) directly inside a `TORCH_LIBRARY_FRAGMENT` block, and registered any additional kernels from other files (e.g. cuda) in a separate `TORCH_LIBRARY_IMPL` block. ``` // cpu file TORCH_LIBRARY_FRAGMENT(ns, m) { m.def("opName(schema_inputs) -> schema_outputs"); m.impl("opName", torch::dispatch(c10::DispatchKey::CPU, TORCH_FN(cpu_kernel))); } // cuda file TORCH_LIBRARY_IMPL(ns, CUDA, m) { m.impl("opName", torch::dispatch(c10::DispatchKey::CUDA, TORCH_FN(cuda_kernel))); } ``` Special cases: I found a few ops that used a (legacy) `CPUTensorId`/`CUDATensorId` dispatch key. Updated those to use CPU/CUDA- this seems safe because the keys are aliased to one another in `DispatchKey.h` There were a handful of ops that registered a functor (function class) to the legacy API. As far as I could tell we don't allow this case in the new API, mainly because you can accomplish the same thing more cleanly with lambdas. Rather than delete the class I wrote a wrapper function on top of the class, which I passed to the new API. There were a handful of ops that were registered only to a CUDA dispatch key. I put them inside a TORCH_LIBRARY_FRAGMENT block, and used a `def()` and `impl()` call like in case two above. Test Plan: Imported from OSS Reviewed By: ezyang Differential Revision: D24714803 Pulled By: bdhirsh fbshipit-source-id: c809aad8a698db3fd0d832f117f833e997b159e1 --- torchtext/csrc/register_bindings.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 920167af5a..278c8f52cb 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -5,6 +5,7 @@ #include // @manual #include // @manual #include +#include // @manual #include // @manual #include // @manual @@ -174,16 +175,14 @@ static auto vectors = }); // Registers our custom op with torch. -static auto registry = - torch::RegisterOperators() - .op("torchtext::generate_sp_model", &generate_sp_model) - .op(torch::RegisterOperators::options() - .schema("torchtext::load_sp_model(str path) -> " - "__torch__.torch.classes.torchtext.SentencePiece model") - .catchAllKernel()) - .op(torch::RegisterOperators::options() - .schema("torchtext::load_sp_model_string(str content) -> " - "__torch__.torch.classes.torchtext.SentencePiece model") - .catchAllKernel()); +TORCH_LIBRARY_FRAGMENT(torchtext, m) { + m.def("generate_sp_model", generate_sp_model); + m.def("load_sp_model(str path) -> " + "__torch__.torch.classes.torchtext.SentencePiece model", + load_sp_model); + m.def("load_sp_model_string(str content) -> " + "__torch__.torch.classes.torchtext.SentencePiece model", + load_sp_model_string); +} + } // namespace torchtext From 854f715f0f588c84febaea9e27b20866b8b68863 Mon Sep 17 00:00:00 2001 From: Brian Hirsh Date: Mon, 16 Nov 2020 17:06:26 -0800 Subject: [PATCH 31/68] Revert D24714803: make duplicate def() calls an error in the dispatcher. Updating all fb operators to use the new dispatcher registration API Differential Revision: D24714803 Original commit changeset: c809aad8a698 fbshipit-source-id: fb2ada65f9fc00d965708d202bd9d050f13ef467 --- torchtext/csrc/register_bindings.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 278c8f52cb..920167af5a 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -5,7 +5,6 @@ #include // @manual #include // @manual #include -#include // @manual #include // @manual #include // @manual @@ -175,14 +174,16 @@ static auto vectors = }); // Registers our custom op with torch. -TORCH_LIBRARY_FRAGMENT(torchtext, m) { - m.def("generate_sp_model", generate_sp_model); - m.def("load_sp_model(str path) -> " - "__torch__.torch.classes.torchtext.SentencePiece model", - load_sp_model); - m.def("load_sp_model_string(str content) -> " - "__torch__.torch.classes.torchtext.SentencePiece model", - load_sp_model_string); -} - +static auto registry = + torch::RegisterOperators() + .op("torchtext::generate_sp_model", &generate_sp_model) + .op(torch::RegisterOperators::options() + .schema("torchtext::load_sp_model(str path) -> " + "__torch__.torch.classes.torchtext.SentencePiece model") + .catchAllKernel()) + .op(torch::RegisterOperators::options() + .schema("torchtext::load_sp_model_string(str content) -> " + "__torch__.torch.classes.torchtext.SentencePiece model") + .catchAllKernel()); } // namespace torchtext From 522e59b9f52fbe9f84ab0737285637ccfbbaa34b Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Mon, 30 Nov 2020 12:14:52 -0800 Subject: [PATCH 32/68] Import torchtext on Nov 20, 2020 Summary: Import torchtext on the commit of 633548a1bdf0bac1e38f98da375a537ce0c2994b allow-large-files Reviewed By: cpuhrsch Differential Revision: D25127691 fbshipit-source-id: 3a617f5f4849df452f8a102a77ce11a1bce5af1f --- README.rst | 21 +- benchmark/benchmark_experimental_vocab.py | 10 +- benchmark/data_construction.py | 2 - docs/requirements.txt | 2 +- docs/source/data/functional.rst | 38 -- docs/source/data/metrics.rst | 13 - docs/source/data/utils.rst | 13 - docs/source/datasets.rst | 40 +- docs/source/experimental_datasets.rst | 89 ++--- docs/source/experimental_transforms.rst | 28 +- docs/source/experimental_vectors.rst | 16 +- docs/source/experimental_vocab.rst | 18 +- docs/source/index.rst | 42 ++- docs/source/modules.rst | 23 -- docs/source/nn_modules.rst | 29 ++ docs/source/vocab.rst | 3 - examples/BERT/data.py | 2 +- examples/BERT/mlm_task.py | 12 +- examples/BERT/ns_task.py | 5 +- examples/data_pipeline/pipelines.py | 4 +- packaging/build_conda.sh | 2 +- packaging/build_wheel.sh | 2 +- packaging/pkg_helpers.bash | 4 +- setup.py | 10 +- test/asset/wikitext103_vocab.pt | Bin 0 -> 7718255 bytes test/common/assets.py | 11 + test/data/test_builtin_datasets.py | 351 +++++++++++------- test/data/test_functional.py | 8 +- test/experimental/test_vectors.py | 20 +- ...forms_with_asset.py => test_with_asset.py} | 94 ++++- torchtext/csrc/register_bindings.cpp | 2 +- torchtext/csrc/vocab.cpp | 8 +- torchtext/csrc/vocab.h | 10 +- torchtext/data/batch.py | 2 +- torchtext/data/example.py | 10 +- torchtext/data/field.py | 10 +- torchtext/data/iterator.py | 2 +- torchtext/datasets/sequence_tagging.py | 3 +- torchtext/experimental/datasets/__init__.py | 10 +- .../datasets/language_modeling.py | 72 ++-- .../experimental/datasets/question_answer.py | 23 +- .../datasets/raw/language_modeling.py | 46 ++- .../datasets/raw/question_answer.py | 14 +- .../datasets/raw/sequence_tagging.py | 29 +- .../datasets/raw/text_classification.py | 44 ++- .../experimental/datasets/raw/translation.py | 81 +++- .../experimental/datasets/sequence_tagging.py | 12 +- .../datasets/text_classification.py | 32 +- .../experimental/datasets/translation.py | 64 ++-- torchtext/experimental/transforms.py | 22 ++ torchtext/experimental/vectors.py | 23 +- torchtext/experimental/vocab.py | 26 +- torchtext/nn/modules/multiheadattention.py | 7 +- torchtext/vocab.py | 35 +- 54 files changed, 863 insertions(+), 636 deletions(-) delete mode 100644 docs/source/data/functional.rst delete mode 100644 docs/source/data/metrics.rst delete mode 100644 docs/source/data/utils.rst delete mode 100644 docs/source/modules.rst create mode 100644 docs/source/nn_modules.rst create mode 100644 test/asset/wikitext103_vocab.pt rename test/experimental/{test_transforms_with_asset.py => test_with_asset.py} (68%) diff --git a/README.rst b/README.rst index a69be1e1e1..06d5a3ddc9 100644 --- a/README.rst +++ b/README.rst @@ -15,8 +15,11 @@ This repository consists of: * `torchtext.data <#data>`_: Generic data loaders, abstractions, and iterators for text (including vocabulary and word vectors) * `torchtext.datasets <#datasets>`_: Pre-built loaders for common NLP datasets -Note: we are currently re-designing the torchtext library to make it more compatible with pytorch (e.g. ``torch.utils.data``). Several datasets have been written with the new abstractions in `torchtext.experimental `_ folder. We also created an issue to discuss the new abstraction, and users are welcome to leave feedback `link `_. +Note: we are currently re-designing the torchtext library to make it more compatible with pytorch (e.g. ``torch.utils.data``). Several datasets have been written with the new abstractions in `torchtext.experimental `_ folder. We also created an issue to discuss the new abstraction, and users are welcome to leave feedback `link `_. These prototype building blocks and datasets in the experimental folder are available in the nightly release only. The nightly packages are accessible via Pip and Conda for Windows, Mac, and Linux. For example, Linux users can install the nightly wheels with the following command:: + pip install --pre torch torchtext -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html + +For more detail instructions, please refer to `Install PyTorch `_. It should be noted that the new building blocks are still under development, and the APIs have not been solidified. Installation ============ @@ -28,15 +31,17 @@ We recommend Anaconda as Python package management system. Please refer to `pyto :widths: 10, 10, 10 nightly build, master, 3.6+ - 1.5, 0.5, 3.5+ - 1.4, 0.4, "2.7, 3.5+" + 1.7, 0.8, 3.6+ + 1.6, 0.7, 3.6+ + 1.5, 0.6, 3.5+ + 1.4, 0.5, "2.7, 3.5+" 0.4 and below, 0.2.3, "2.7, 3.5+" -Using conda;:: +Using conda:: conda install -c pytorch torchtext -Using pip;:: +Using pip:: pip install torchtext @@ -64,7 +69,13 @@ To build torchtext from source, you need ``git``, ``CMake`` and C++11 compiler s git clone https://github.com/pytorch/text torchtext cd torchtext git submodule update --init --recursive + + # Linux python setup.py clean install + + # OSX + MACOSX_DEPLOYMENT_TARGET=10.9 CC=clang CXX=clang++ python setup.py clean install + # or ``python setup.py develop`` if you are making modifications. **Note** diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 29f1c18e80..4183c27f6a 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -6,8 +6,8 @@ from torchtext.experimental.datasets import AG_NEWS from torchtext.experimental.vocab import ( vocab as VocabExperimental, - vocab_from_file, - vocab_from_raw_text_file + load_vocab_from_file, + build_vocab_from_text_file ) from torchtext.vocab import ( Vocab, @@ -68,11 +68,11 @@ def benchmark_experimental_vocab_construction(vocab_file_path, is_raw_text=True, for _ in range(num_iters): tokenizer = basic_english_normalize() jited_tokenizer = torch.jit.script(tokenizer.to_ivalue()) - vocab_from_raw_text_file(f, jited_tokenizer, num_cpus=1) + build_vocab_from_text_file(f, jited_tokenizer, num_cpus=1) print("Construction time:", time.monotonic() - t0) else: for _ in range(num_iters): - vocab_from_file(f) + load_vocab_from_file(f) print("Construction time:", time.monotonic() - t0) @@ -121,7 +121,7 @@ def token_iterator(file_path): print("Vocab Experimental") t0 = time.monotonic() f = open(vocab_file_path, 'r') - v_experimental = vocab_from_file(f) + v_experimental = load_vocab_from_file(f) print("Construction time:", time.monotonic() - t0) else: print("Loading Vocab from AG News") diff --git a/benchmark/data_construction.py b/benchmark/data_construction.py index 1a1621c353..388bdb3dcb 100644 --- a/benchmark/data_construction.py +++ b/benchmark/data_construction.py @@ -1,6 +1,4 @@ -import torch from torchtext.experimental import datasets -import torch.utils._benchmark as benchmark_utils import time diff --git a/docs/requirements.txt b/docs/requirements.txt index d78a0af94a..c4dae765eb 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -sphinx +sphinx==2.4.4 sphinxcontrib-googleanalytics -e git+git://github.com/pytorch/pytorch_sphinx_theme.git#egg=pytorch_sphinx_theme diff --git a/docs/source/data/functional.rst b/docs/source/data/functional.rst deleted file mode 100644 index ec8d28f9d5..0000000000 --- a/docs/source/data/functional.rst +++ /dev/null @@ -1,38 +0,0 @@ -.. role:: hidden - :class: hidden-section - -torchtext.data.functional -=========================== - -.. automodule:: torchtext.data.functional -.. currentmodule:: torchtext.data.functional - -:hidden:`generate_sp_model` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: generate_sp_model - -:hidden:`load_sp_model` -~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: load_sp_model - -:hidden:`sentencepiece_numericalizer` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: sentencepiece_numericalizer - -:hidden:`sentencepiece_tokenizer` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: sentencepiece_tokenizer - -:hidden:`custom_replace` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: custom_replace - -:hidden:`simple_space_split` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: simple_space_split diff --git a/docs/source/data/metrics.rst b/docs/source/data/metrics.rst deleted file mode 100644 index f0c73ca9e1..0000000000 --- a/docs/source/data/metrics.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. role:: hidden - :class: hidden-section - -torchtext.data.metrics -=========================== - -.. automodule:: torchtext.data.metrics -.. currentmodule:: torchtext.data.metrics - -:hidden:`bleu_score ` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: bleu_score diff --git a/docs/source/data/utils.rst b/docs/source/data/utils.rst deleted file mode 100644 index e89811f3f6..0000000000 --- a/docs/source/data/utils.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. role:: hidden - :class: hidden-section - -torchtext.data.utils -=========================== - -.. automodule:: torchtext.data.utils -.. currentmodule:: torchtext.data.utils - -:hidden:`ngrams_iterator` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: ngrams_iterator diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index 1f98ec7a4b..708fe943a7 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -95,66 +95,42 @@ TextClassificationDataset AG_NEWS ~~~~~~~ -AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: AG_NEWS - :members: __init__ +.. autofunction:: AG_NEWS SogouNews ~~~~~~~~~ -SogouNews dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: SogouNews - :members: __init__ +.. autofunction:: SogouNews DBpedia ~~~~~~~ -DBpedia dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: DBpedia - :members: __init__ +.. autofunction:: DBpedia YelpReviewPolarity ~~~~~~~~~~~~~~~~~~ -YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: YelpReviewPolarity - :members: __init__ +.. autofunction:: YelpReviewPolarity YelpReviewFull ~~~~~~~~~~~~~~ -YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: YelpReviewFull - :members: __init__ +.. autofunction:: YelpReviewFull YahooAnswers ~~~~~~~~~~~~ -YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: YahooAnswers - :members: __init__ +.. autofunction:: YahooAnswers AmazonReviewPolarity ~~~~~~~~~~~~~~~~~~~~ -AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: AmazonReviewPolarity - :members: __init__ +.. autofunction:: AmazonReviewPolarity AmazonReviewFull ~~~~~~~~~~~~~~~~ -AmazonReviewFull dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: AmazonReviewFull - :members: __init__ +.. autofunction:: AmazonReviewFull Question Classification diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index 20cde70f2e..2f8842639a 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -27,88 +27,62 @@ The following datasets are available: :local: -Sentiment Analysis -^^^^^^^^^^^^^^^^^^ - -IMDb -~~~~ - -.. autoclass:: IMDB - :members: __init__ - - Text Classification ^^^^^^^^^^^^^^^^^^^ TextClassificationDataset ~~~~~~~~~~~~~~~~~~~~~~~~~ +Text classification datasets are subclasses of ``TextClassificationDataset`` class. + .. autoclass:: TextClassificationDataset :members: __init__ AG_NEWS ~~~~~~~ -AG_NEWS dataset is subclass of ``TextClassificationDataset`` class. +.. autofunction:: AG_NEWS -.. autoclass:: AG_NEWS - :members: __init__ SogouNews ~~~~~~~~~ -SogouNews dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: SogouNews - :members: __init__ +.. autofunction:: SogouNews DBpedia ~~~~~~~ -DBpedia dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: DBpedia - :members: __init__ +.. autofunction:: DBpedia YelpReviewPolarity ~~~~~~~~~~~~~~~~~~ -YelpReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: YelpReviewPolarity - :members: __init__ +.. autofunction:: YelpReviewPolarity YelpReviewFull ~~~~~~~~~~~~~~ -YelpReviewFull dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: YelpReviewFull - :members: __init__ +.. autofunction:: YelpReviewFull YahooAnswers ~~~~~~~~~~~~ -YahooAnswers dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: YahooAnswers - :members: __init__ +.. autofunction:: YahooAnswers AmazonReviewPolarity ~~~~~~~~~~~~~~~~~~~~ -AmazonReviewPolarity dataset is subclass of ``TextClassificationDataset`` class. - -.. autoclass:: AmazonReviewPolarity - :members: __init__ +.. autofunction:: AmazonReviewPolarity AmazonReviewFull ~~~~~~~~~~~~~~~~ -AmazonReviewFull dataset is subclass of ``TextClassificationDataset`` class. +.. autofunction:: AmazonReviewFull -.. autoclass:: AmazonReviewFull - :members: __init__ +IMDb +~~~~ + +.. autofunction:: IMDB Language Modeling @@ -123,29 +97,25 @@ Language modeling datasets are subclasses of ``LanguageModelingDataset`` class. WikiText-2 ~~~~~~~~~~ -.. autoclass:: WikiText2 - :members: __init__ +.. autofunction:: WikiText2 WikiText103 ~~~~~~~~~~~ -.. autoclass:: WikiText103 - :members: __init__ +.. autofunction:: WikiText103 PennTreebank ~~~~~~~~~~~~ -.. autoclass:: PennTreebank - :members: __init__ +.. autofunction:: PennTreebank WMTNewsCrawl ~~~~~~~~~~~~ -.. autoclass:: WMTNewsCrawl - :members: __init__ +.. autofunction:: WMTNewsCrawl Machine Translation @@ -160,22 +130,19 @@ Language modeling datasets are subclasses of ``TranslationDataset`` class. Multi30k ~~~~~~~~ -.. autoclass:: Multi30k - :members: __init__ +.. autofunction:: Multi30k IWSLT ~~~~~ -.. autoclass:: IWSLT - :members: __init__ +.. autofunction:: IWSLT WMT14 ~~~~~ -.. autoclass:: WMT14 - :members: __init__ +.. autofunction:: WMT14 Sequence Tagging @@ -189,14 +156,12 @@ Language modeling datasets are subclasses of ``SequenceTaggingDataset`` class. UDPOS ~~~~~ -.. autoclass:: UDPOS - :members: __init__ +.. autofunction:: UDPOS CoNLL2000Chunking -~~~~~ +~~~~~~~~~~~~~~~~~ -.. autoclass:: CoNLL2000Chunking - :members: __init__ +.. autofunction:: CoNLL2000Chunking Question Answer ^^^^^^^^^^^^^^^ @@ -210,12 +175,10 @@ Question answer datasets are subclasses of ``QuestionAnswerDataset`` class. SQuAD 1.0 ~~~~~~~~~ -.. autoclass:: SQuAD1 - :members: __init__ +.. autofunction:: SQuAD1 SQuAD 2.0 ~~~~~~~~~ -.. autoclass:: SQuAD2 - :members: __init__ +.. autofunction:: SQuAD2 diff --git a/docs/source/experimental_transforms.rst b/docs/source/experimental_transforms.rst index f134a29048..9076995387 100644 --- a/docs/source/experimental_transforms.rst +++ b/docs/source/experimental_transforms.rst @@ -22,7 +22,7 @@ torchtext.experimental.transforms :special-members: __init__ :hidden:`TextSequentialTransforms` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: TextSequentialTransforms :members: @@ -31,47 +31,41 @@ torchtext.experimental.transforms :hidden:`load_sp_model` ~~~~~~~~~~~~~~~~~~~~~~~ -.. autoclass:: load_sp_model - :members: - :special-members: __init__ +.. autofunction:: load_sp_model -:hidden: `sentencepiece_tokenizer` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:hidden:`sentencepiece_tokenizer` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. autoclass:: sentencepiece_tokenizer - :members: - :special-members: __init__ +.. autofunction:: sentencepiece_tokenizer :hidden:`SentencePieceTokenizer` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: SentencePieceTokenizer :members: :special-members: __init__ -:hidden: `sentencepiece_processor` +:hidden:`sentencepiece_processor` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. autoclass:: sentencepiece_processor - :members: - :special-members: __init__ +.. autofunction:: sentencepiece_processor :hidden:`SentencePieceProcessor` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: SentencePieceProcessor :members: :special-members: __init__ :hidden:`VocabTransform` -~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: VocabTransform :members: :special-members: __init__ :hidden:`VectorTransform` -~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~ .. autoclass:: VectorTransform :members: diff --git a/docs/source/experimental_vectors.rst b/docs/source/experimental_vectors.rst index c07cfd7822..e4d57b7232 100644 --- a/docs/source/experimental_vectors.rst +++ b/docs/source/experimental_vectors.rst @@ -14,22 +14,22 @@ torchtext.experimental.vectors :members: :special-members: -:hidden:`vectors` -~~~~~~~~~~~~~~~~~ +:hidden:`build_vectors` +~~~~~~~~~~~~~~~~~~~~~~~ -.. autofunction:: vectors +.. autofunction:: build_vectors -:hidden:`vectors_from_file_object` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:hidden:`load_vectors_from_file_path` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. autofunction:: vectors_from_file_object +.. autofunction:: load_vectors_from_file_path :hidden:`FastText` -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~ .. autofunction:: FastText :hidden:`GloVe` -~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~ .. autofunction:: GloVe diff --git a/docs/source/experimental_vocab.rst b/docs/source/experimental_vocab.rst index debe7644e3..91ae03d40f 100644 --- a/docs/source/experimental_vocab.rst +++ b/docs/source/experimental_vocab.rst @@ -2,32 +2,32 @@ :class: hidden-section torchtext.experimental.vocab -============================== +============================ .. automodule:: torchtext.experimental.vocab .. currentmodule:: torchtext.experimental.vocab :hidden:`Vocab` -~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~ .. autoclass:: Vocab :members: :special-members: :hidden:`vocab` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~ .. autofunction:: vocab -:hidden:`vocab_from_file` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:hidden:`load_vocab_from_file` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. autofunction:: vocab_from_file +.. autofunction:: load_vocab_from_file -:hidden:`vocab_from_raw_text_file` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:hidden:`build_vocab_from_text_file` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. autofunction:: vocab_from_raw_text_file +.. autofunction:: build_vocab_from_text_file :hidden:`build_vocab_from_iterator` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/index.rst b/docs/source/index.rst index a75692252e..2072db4adf 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,5 +1,28 @@ torchtext -=========== +========= + +This library is part of the `PyTorch +`_ project. PyTorch is an open source +machine learning framework. + +Features described in this documentation are classified by release status: + + *Stable:* These features will be maintained long-term and there should generally + be no major performance limitations or gaps in documentation. + We also expect to maintain backwards compatibility (although + breaking changes can happen and notice will be given one release ahead + of time). + + *Beta:* Features are tagged as Beta because the API may change based on + user feedback, because the performance needs to improve, or because + coverage across operators is not yet complete. For Beta features, we are + committing to seeing the feature through to the Stable classification. + We are not, however, committing to backwards compatibility. + + *Prototype:* These features are typically not available as part of + binary distributions like PyPI or Conda, except sometimes behind run-time + flags, and are at an early stage for feedback and testing. + The :mod:`torchtext` package consists of data processing utilities and popular datasets for natural language. @@ -10,15 +33,14 @@ popular datasets for natural language. self torchtext.data - modules + nn_modules data_utils data_functional data_metrics torchtext.datasets torchtext.vocab torchtext.utils - experimental_datasets - experimental_functional + experimental_datasets experimental_transforms experimental_vectors experimental_vocab @@ -27,6 +49,18 @@ popular datasets for natural language. .. automodule:: torchtext :members: +.. toctree:: + :maxdepth: 1 + :caption: PyTorch Libraries + + PyTorch + torchaudio + torchtext + torchvision + TorchElastic + TorchServe + PyTorch on XLA Devices + Indices and tables ================== diff --git a/docs/source/modules.rst b/docs/source/modules.rst deleted file mode 100644 index ca8b30e8e4..0000000000 --- a/docs/source/modules.rst +++ /dev/null @@ -1,23 +0,0 @@ -.. role:: hidden - :class: hidden-section - -torchtext.models.multiheadattention -================================== - -.. automodule:: torchtext.models.multiheadattention -.. currentmodule:: torchtext.models.multiheadattention - -:hidden:`MultiheadAttentionContainer` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: MultiheadAttentionContainer - -:hidden:`InProjContainer` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: InProjContainer - -:hidden:`ScaledDotProduct` -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: ScaledDotProduct diff --git a/docs/source/nn_modules.rst b/docs/source/nn_modules.rst new file mode 100644 index 0000000000..064f51488a --- /dev/null +++ b/docs/source/nn_modules.rst @@ -0,0 +1,29 @@ +.. role:: hidden + :class: hidden-section + +torchtext.nn.modules.multiheadattention +======================================= + +.. automodule:: torchtext.nn.modules.multiheadattention +.. currentmodule:: torchtext.nn.modules.multiheadattention + +:hidden:`MultiheadAttentionContainer` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: MultiheadAttentionContainer + :members: + :special-members: __init__ + +:hidden:`InProjContainer` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: InProjContainer + :members: + :special-members: __init__ + +:hidden:`ScaledDotProduct` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autoclass:: ScaledDotProduct + :members: + :special-members: __init__ diff --git a/docs/source/vocab.rst b/docs/source/vocab.rst index df565149eb..a981725e02 100644 --- a/docs/source/vocab.rst +++ b/docs/source/vocab.rst @@ -36,21 +36,18 @@ Pretrained Word Embeddings .. autoclass:: GloVe :members: - :special-members: __init__ :hidden:`FastText` ~~~~~~~~~~~~~~~~~~ .. autoclass:: FastText :members: - :special-members: __init__ :hidden:`CharNGram` ~~~~~~~~~~~~~~~~~~~ .. autoclass:: CharNGram :members: - :special-members: __init__ Misc. ----- diff --git a/examples/BERT/data.py b/examples/BERT/data.py index 2f62459c1a..b5e669dc9f 100644 --- a/examples/BERT/data.py +++ b/examples/BERT/data.py @@ -10,7 +10,7 @@ # Set up dataset for book corpus ################################################################### def BookCorpus(vocab, tokenizer=get_tokenizer("basic_english"), - data_select=('train', 'test', 'valid'), removed_tokens=[], + data_select=('train', 'valid', 'test'), removed_tokens=[], min_sentence_len=None): if isinstance(data_select, str): diff --git a/examples/BERT/mlm_task.py b/examples/BERT/mlm_task.py index d0623a9607..57962e23be 100644 --- a/examples/BERT/mlm_task.py +++ b/examples/BERT/mlm_task.py @@ -123,7 +123,7 @@ def run_main(args, rank=None): try: vocab = torch.load(args.save_vocab) except: - train_dataset, test_dataset, valid_dataset = WLMDataset() + train_dataset, valid_dataset, test_dataset = WLMDataset() old_vocab = train_dataset.vocab vocab = torchtext.vocab.Vocab(counter=old_vocab.freqs, specials=['', '', '']) @@ -131,11 +131,17 @@ def run_main(args, rank=None): torch.save(vocab, f) if args.dataset == 'WikiText103' or args.dataset == 'WikiText2': - train_dataset, test_dataset, valid_dataset = WLMDataset(vocab=vocab) + train_dataset, valid_dataset, test_dataset = WLMDataset(vocab=vocab) + train_dataset.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) + valid_dataset.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, valid_dataset))) + test_dataset.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) elif args.dataset == 'WMTNewsCrawl': from torchtext.experimental.datasets import WikiText2 test_dataset, valid_dataset = WikiText2(vocab=vocab, data_select=('test', 'valid')) + valid_dataset.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, valid_dataset))) + test_dataset.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) train_dataset, = WLMDataset(vocab=vocab, data_select='train') + train_dataset.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) elif args.dataset == 'EnWik9': enwik9 = EnWik9() idx1, idx2 = int(len(enwik9) * 0.8), int(len(enwik9) * 0.9) @@ -150,7 +156,7 @@ def run_main(args, rank=None): valid_dataset = LanguageModelingDataset(val_data, vocab) test_dataset = LanguageModelingDataset(test_data, vocab) elif args.dataset == 'BookCorpus': - train_dataset, test_dataset, valid_dataset = BookCorpus(vocab) + train_dataset, valid_dataset, test_dataset = BookCorpus(vocab) train_data = process_raw_data(train_dataset.data, args) if rank is not None: diff --git a/examples/BERT/ns_task.py b/examples/BERT/ns_task.py index 062ebc343f..06786a82dc 100644 --- a/examples/BERT/ns_task.py +++ b/examples/BERT/ns_task.py @@ -137,11 +137,10 @@ def run_main(args, rank=None): if args.dataset == 'WikiText103': from torchtext.experimental.datasets import WikiText103 - train_dataset, valid_dataset, test_dataset = WikiText103(vocab=vocab, - single_line=False) + train_dataset, valid_dataset, test_dataset = WikiText103(vocab=vocab) elif args.dataset == 'BookCorpus': from data import BookCorpus - train_dataset, test_dataset, valid_dataset = BookCorpus(vocab, min_sentence_len=60) + train_dataset, valid_dataset, test_dataset = BookCorpus(vocab, min_sentence_len=60) if rank is not None: chunk_len = len(train_dataset.data) // args.world_size diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index 10818da8b2..4e2db98021 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -18,7 +18,7 @@ sequential_transforms, ) from torchtext.experimental.vectors import FastText as FastTextExperimental -from torchtext.experimental.vocab import vocab_from_file +from torchtext.experimental.vocab import load_vocab_from_file from torchtext.vocab import FastText import argparse @@ -57,7 +57,7 @@ def token_iterator(vocab_file): def build_experimental_torchtext_pipeline(hf_vocab_file): tokenizer = basic_english_normalize() with open(hf_vocab_file, 'r') as f: - vocab = vocab_from_file(f) + vocab = load_vocab_from_file(f) pipeline = TextSequentialTransforms(tokenizer, vocab) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) print('jit experimental torchtext pipeline success!') diff --git a/packaging/build_conda.sh b/packaging/build_conda.sh index f7df266a15..3dfac7fd34 100755 --- a/packaging/build_conda.sh +++ b/packaging/build_conda.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="conda" export NO_CUDA_PACKAGE=1 -setup_env 0.8.0 +setup_env 0.9.0 export SOURCE_ROOT_DIR="$PWD" setup_conda_pytorch_constraint setup_visual_studio_constraint diff --git a/packaging/build_wheel.sh b/packaging/build_wheel.sh index fb9c190789..4f1604e722 100755 --- a/packaging/build_wheel.sh +++ b/packaging/build_wheel.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="wheel" export NO_CUDA_PACKAGE=1 -setup_env 0.8.0 +setup_env 0.9.0 setup_wheel_python pip_install numpy future setup_pip_pytorch_version diff --git a/packaging/pkg_helpers.bash b/packaging/pkg_helpers.bash index b7254c19c3..7ce802ed14 100644 --- a/packaging/pkg_helpers.bash +++ b/packaging/pkg_helpers.bash @@ -173,7 +173,7 @@ setup_pip_pytorch_version() { else pip_install "torch==$PYTORCH_VERSION$PYTORCH_VERSION_SUFFIX" \ -f https://download.pytorch.org/whl/torch_stable.html \ - -f https://download.pytorch.org/whl/nightly/torch_nightly.html + -f "https://download.pytorch.org/whl/${UPLOAD_CHANNEL}/torch_${UPLOAD_CHANNEL}.html" fi } @@ -186,7 +186,7 @@ setup_conda_pytorch_constraint() { export CONDA_CHANNEL_FLAGS="-c pytorch-nightly" export PYTORCH_VERSION="$(conda search --json 'pytorch[channel=pytorch-nightly]' | python -c "import sys, json, re; print(re.sub(r'\\+.*$', '', json.load(sys.stdin)['pytorch'][-1]['version']))")" else - export CONDA_CHANNEL_FLAGS="-c pytorch -c pytorch-nightly" + export CONDA_CHANNEL_FLAGS="-c pytorch -c pytorch-${UPLOAD_CHANNEL}" fi if [[ "$CU_VERSION" == cpu ]]; then export CONDA_PYTORCH_BUILD_CONSTRAINT="- pytorch==$PYTORCH_VERSION${PYTORCH_VERSION_SUFFIX}" diff --git a/setup.py b/setup.py index 7efa31dbc4..7c71a0ddca 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ def read(*names, **kwargs): def _get_version(): - version = '0.8.0a0' + version = '0.9.0a0' sha = None try: @@ -49,6 +49,12 @@ def _export_version(version, sha): print('-- Building version ' + VERSION) +pytorch_package_version = os.getenv('PYTORCH_VERSION') + +pytorch_package_dep = 'torch' +if pytorch_package_version is not None: + pytorch_package_dep += "==" + pytorch_package_version + class clean(distutils.command.clean.clean): def run(self): @@ -82,7 +88,7 @@ def run(self): license='BSD', install_requires=[ - 'tqdm', 'requests', 'torch', 'numpy', 'sentencepiece' + 'tqdm', 'requests', pytorch_package_dep, 'numpy' ], python_requires='>=3.5', classifiers=[ diff --git a/test/asset/wikitext103_vocab.pt b/test/asset/wikitext103_vocab.pt new file mode 100644 index 0000000000000000000000000000000000000000..8974e7fd302aa32f3253d05ef6da72a217f127ae GIT binary patch literal 7718255 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®2b`1kV=SH}o!( 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%0AcH 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 z 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�U zRctJm?_^HDh_4AgmU{+ftl!L2B6Y0k9^zSzP7ctV7Wo?!KomaxhJ@P}7Z~o3Z`v$R zrr_R|#WJd76cZh1+2-hrR0yFPEnpW+un z_ty(A#Doc_?1^96f18{aO3GrWk6($@uW%-%5FNi3tI{Vwv%T+Z_^2r_{vz4h`MBdF%>@!2oal|o zg-Q3NjULq$RZoS>{RyLCx_8Fk#CHGRYp8c*+56x9OL=*4?aiAg-|$7y&YOzqcah?m zOXoj?D4d+xf5^Z$NgOZv2W$Yom_m%#p!lc5?wNaM#+=#lFPrCNU$#Yw^{R^hEnZb6 zta`&K`X7;vv*WC3bK<`?PpRh2Iq|a11M{aQSo7(2{EFDprbkD-?qr%D&gQh~b7C2r zH)nJ9j2W@4&5N@+bO+<8kb9CbBU&w%4gV`-b8yKi)!+`wzE zY$X9UPDx^0~VZ;xpU!juKV^(?EZ@lg;gO3g)ZT z*x5c`Del9Q<-6`8O$o>Sh@89HtmKTSQL%~dCQu?SWkZMoB{%dN#p#Zd3u(Rh=Dd)CMCig9qFAON7$_UQ}lF1 zr_C};cJCFbtW*FczK~cbMg%KVbEq{J z*>zN4z4}qT)J!5eU#z6b$%7X~lwj!yU-O*dXF~k@IRNS+BW-%3Emm9=_BnZ~j)8W* zw=NW2m6{HpBuSsoZ-F_mQNJ$~ygY@cVN&+OyY)eiMZ$kf*fJ(ukkS`wv2as}F~z0{ zfx1MIe~8t<^>+za=bFX)HCLcYeT!rrIoxX}4E|@rbqCIBKb$b<+WDqBqR?+Zrm)csAt$}HAnXTEy2D)a&TWuD1kKWmFxy{Y;uhBOm%q+d^W^7cjj{koL~^!C zc0@v~s^kVY3jI45kh`W_GHw!l`c-k*o78xlr@mQyr<@TF$amVjv)*lVXq-GV3)}N1 z;$6aZ3GEwO`o71mLD-911RG`1IM--Iy<3IKDu!rBw9o={qh}RBl!j+9E9(;Sy|JfXLfwR z<{NU3ThrrCTMs7fg6>&ym(7){$(iv%o25q^;duIx&2_Ttz>K)tRvm;R{WIgkHrL4K zMlzTY_t;*uh^NO#Y}Ls&vUp&6eAIRw5uAK8<72j)d+uVM^4|J;o^<@y$8E0KywZ%g zuc%eZczeUIOQ0rg!D1HuC#$?JA+3ITj{f6H|A2s4OP~_g87_7?A2UOXU6BHDIW*S@#Y+yh)2aPPa%~bNxw1r zenIr*d_XYIz%Pm%lv|Rk?>vke_-l#%B~KZQ)|hS|6IiuwdsPcr_Bs(?0`I)9Ztz?K zEAsoxf~eM0fS)~mT0AbWTJ4Q)wj{beZVXR|Zai84EAO?qu2M%7948>Z4919f(&m%J zFImqd=Zmijt&l#qobU4~(FRl3=b{~7^G~bg+f3>-;wiEJ=HqZH8HumkKD=1?;P4WU zeGjm22$w4+mKJp{CeI|E&0q%}P(s*woqKq~JS!S9tw=YjjK`jYnYw)VXAm|4)x+CD}W- zQ_r+`&Q|5i?CPH$-?v#?d<2H_1Dn-#1VQkJHcMLTLU{X;&DZBhh@d~VwN1|M|E^BY z!=L!4H|AQLb?!c?^VI=A zej!yc9QEP9w0U1Gf1KpXMetX4Yl?OEx|@G3RTcdmQEdK=?cIuHE=Df?t?kN3qe`+T zUT}nsYT;5Lhl7|E@H?q0sXv07uKI)Vd$Fp~q!$nB7<&IfaJPIY?A0+uF}-oBE)(Yf8J|W-r;S$_!oHQ2uH24XNEj#^J#$;-Ve@ z@(-KlGkEO$+h!%An_Q{5TnX-wdx@DCM)FJM^Izc-KUi)r+uFQdrne(rv03J@k;Mq` zuRDeIO7%Ov(_$H$tL58u`7M{V-6)Se9A9s{2^6=kV>^};sZbt`FVGTmjJzt~W!BeQR# zaCF^nB)WN>D6e^EZ!G%uJW=4q#vyOwkgL|-(zwQ&m>-)8zOBwn*a~N%F1(xB`7_Dp z;FuZCu(^a&i?^D-oocq)P`8kBdL3L)vI)18@PPW6Mkmsatt6{Jqal0&aHc>FwYA{7 z`70QoTDp~PW9RXb6SaZ)e%p#YS1!4#tH@LXx}E6mbxg6i)0D5{`}PhxCs%$E=Lr-$ z2){ii7_SwqN;?Wv3c<Hq&o|R;)=0i^vtUF4xsbZRA;E|*jWuO-gT8i7#CEPsMSiY@K zFhlIXB;@pM=};XpQ*iHmwT$}F5}8vo%RlU!pWonk7Q}3kU9*1^q`-MH2e7kUx5d1k znO<)XDJOG^nOI^^fd_M%bc6N>kY)A~eOIoMzTSxuZ_RrPot}imtl(qLA=n%HfKHkM zSl{WOvagi?mrpbKy98Vc9$K$xb_8yQt=Qk*vl_$uNXMMnvs&>c3ClD>;%YoS;sBAR zV9oHLJ_|?y2MT__+2gpB#6gaQuWYIk$p(@(+k>U5c+LqF8qDpyc(Yj9k0)BhzAcPH zL>fEY;1W!FoMVTImC4ZLL6`|f;xMsdHijn?&k3(P9MC!geq|HOBl@vUkC3zyDqyEU z0Un*wonFg^FUi`IyBsOqTJ_L_SXGs%j*^lnIn_3%xZ;7*iS}q|-<4~h&xGTZbd;`A z6vropEMo0AR&3j4(iW1%hf%uV*rI>iads~Uu>k_KDNz&03yswPt>LVBe}Yg?&Z~}6 zcwPxK(O~I>dXm5=k^;$q$2(b|Ud+cW<;f|4lZ+3Y)4bFxoGRr8xpJ9M@1v(l_QTqy z?sD`grZ72O_{EZix+vX?@5&Fe4f#nCR#0%X^uODQ5M`{-VewtrP5#%VPc}GA)!4Ry9)|2)MCRz+_3U=hLH`%h{*5i$uemm7Xjv7 z6l=Arhp&G&=F>!uaBa=+WfP*nUm$c=K6~nLyg!84DLHedLuRYwjk7KMMD`|;X&ZI=u`gGDQyNLC&?*FRO*J~boj z-qRE3ITQ)T@@hAwV``i)*(aOL|AyW3ce#fqaRSAIKjg^VXucRGP1@n4h&x`n{pJOp4-bgXB2k>iSk`zEdwx zQpdR5_O7+rxKnd(3pJci!Pe*)Ov?BU(NN2A{776$}4}Pgby~g z0MKN{P13E93vMoNYFNn4((GFbPm&jQHxo*)Q zGO2e9T$4b@R12njSfE0)XWPEV_DH@Gne33F2)JZ*e+0Pmxnlnrv**_NsI+}Ki$vT_ z7RmgWXhjQ{k9{=m6{tA4%m@!>{PLGqg2I<@E+6dy|L}%f(&O`CB6vl{ryOCEx)mGDhu+rdeo&ZD zRTqPWAY`qK@Q@=kI$p3v1bRL!bY$)v9?FC`pSJJ8bp&KO9z3ojszjaUCg9`6BSPQI zDa}rGNO~W`-Aa<) z9EfyldHeaA&syoU z%y;m}{-z^TM6YR0C_|*L%eO>#%-@;|?XH}x5X~V z7c+wdfsg{_{Dg4NqqO6@LjO&faNr(*!q5sGbFw^haWCBfv4c&q=jS z4nKhaNp(# zzf?CVZW-(+B2@uElK82;@b~j$F4Ah!6F-w=R=u;G;^zW$^V1De`W5H&c;0SoZoBc) zUj2R{)pv3>r%s(2zm#IjW(BkuI({WVWk$!N*`k)emgcfz#_UpLP&O-%{TnH_%GXna z1;5AJO04dK?OH7Hf>0UyP=E5NDQNUNv90r2@ff4)MEqXplpGCH(a8KkG=_fw>%4Zw zeEuwFPTDld%C~@wsqOfa?NXj1M&K`5LgSx>|B$2UR?eY46n}BF73w{3V@5Y%F06L^ zpZJuTgD!4&gguJfT{4bQ&G9#f`({2bS2Km__`6V9z)+)%#*4OR=dMrwgCZO2@IOR1 zd+q+$XE5_if~BmQbj^={f^~kOc%SYdI4cCSqXS7p_n*Yu})XSh{VAw1d z75{PUKjyMv{o-c(Ux5wsxzMFdMj^Z`S{`CJN^nPqpY_Kp4!UnW1X(!PB+0H{cPcRT zTs*`(rcI4yY;RD48sQ6EH+o`OF~XMRq>0I^UJuy3efKE5Fpa#+Nx5suLUTt4nw_}3 zq(|m+E7XuQO)^q;`J>ZkPm2{LC}((-1>+M#^Wa3Wl4uE^bKvJI+dMDV3pyjknN=L7 zabzQq)+GEr@dm-qm4rBhG6t*K?d|zf)22>|)%-Kknm;|2_Ug9(xqKu3vDFZ4lQpj4 zA66*BnKP%ynvQdC>A?w6AT8uTI!Uf2zHcs{^dMmetZi4KSKXR;BUov49ifW~LbvYI zuPfBtveEDK_7e+E=}^&=>L!CC&8OiDtPhG$jvoMLAEX*i_YI`Pkt%Ov#OJ{E;7c1y z*~Cp}@y(4STTqJ69)gNCmY_r-u9q+*JhX(qoKrFf1=ObYz(>?6nu&wiX8!r6Y+B)Z zbDMod-7zD!usNR18B=D)mNrKk)*+2+RZg0@)xQm%xvPCIt53^_uJ7H1 zR;;ig*lAO05>=h}(e>siFdFLJ9rdrZJ&=leV~S)aRuT<@n+PKsBy7hUZHJ^EY-E3P zfod^n#Z)_>B5{4RNc4u1e>kQIqNnvU_H}p1bo;*4$egW-Vk{`?gb&KKO2I_)xy}@+ zI3A3Y6EVwyt}9W+j49?0kJ%DEmA^O-uAggfj@aXgp^m8#jy=Tcv_oMq5PLe<{pAuh z;5o3D1UF@;jBau2_ZE93_Y{{pG(Chq3LTUJ)zm2+b7EiHRVS!DGJ#|l`+-ab?ZHk} z&&2*x&B~WUPtAkIn?x4oIOO!}iUVwaGbd>lYyUt8nNe$h4&@{cvP~jeXLhV*BsCJq z!S-o9s}-BGj^CRFtH^EEFeUEMzVB|%9vE?N94f+9-i69!yZ3ZpJxut}x^<8%oc(^d z$Ztyw_h<7LjsQgFtx`N$#Aebg+9~-ZdgLGL(;yK+gvs|;{Y3Fmm>({t7d zPcj_o1pD7uk3wnT%t&yeR2$~&SdgcixD9U$eCv~>{#nh3xt{PR5}7$E@Dgo~mL`en zuFS9a!lyc7IjYR(Yg4Y^G?BWr;>Sw7SZ|zezt5I}mWZdk_MIWwiuoRJnF$hZV3;5T zQn<3SD(>>)Lvfba*ON;Pj_8%55&vw#X*p>c0vog?dUB51>cRQaYE{V=0Jgn{zvpJf3rMRgWjfzY@K%WqM+)qrn`2hO6=(pPm`H6cb zlxPP8DtwDv71XU56lfwqykZToFXoEvmG3pocJ_`!IRwDY|J1azRY~j;L(+}s==ci5 z{)VMlzch-tWyuL*M552vDkBmQv%J6!#Vv4IOP{s*Vv7^Q@fJ~$A6y{zaIPGzJM6Xy zkj^($OeIc6P429=bd{vuxB|WD#)Pg&+X9nEes|s={ouwOp{WbkLs}11aUyq=hXz8S z_J;N%ycR}ck%R1)Q%(eAD;C?{J70u5HY(c*fztU~u^VqF=5C4L?)lU#AGg_CM4ria z8y?4fS%K*su{Cq-xuf(tmv(1YNm}@v1f>(=JZa8J8YDa_hT7ga7ZwjldV~ytyFj%0 zep&+^{X$1OqPY(AvJcyFkz{vd=iHs>wg$%HV$oOfLmP};qUQ zC8graM2>D)!>a*1Zxx-$@w$4AST%L#<$%g2c|jc*HQ4Y9p?wPKVhLcSyV9<81DHp= zJ|%6h64^TklbevLmN~y#uxh&5nN7HDN`jvK^|$<3STSam^V%y$Tv zeutl)7dP6TneWjaC78yP-EouPoZPFjR(ZkALObU)4Urds?etEN&Rr_}0N=XNZW3?n zHuElVgfe&fTmruJ*SJLt_mz~(M^)4FCbv3d`Ih%CW?#J9cI81Mad}xW-($xoN-|=_ z;`*rX{%xW!lyrguLE9c&=yuV+mF5CRnBI7=z#YYN2x7BnV7yQ4!_~E`wU{-4PAcvI zZ5%Fo$c0C^7-dDpHqQxUv9KV^>FEOwu>R!o#qQl3cMAQwl$A~O-Mj2u_b}1`^5HAs zQM9rvEF>l+K4iy9TeRVby(8HF?v`rj{Nc%Y@XLL;hE(b#$FX-UCi@=2E0T5`om8f? zVu+6jU!7mI&PE6L=xYO*kVb1G1xE$T>k9iJ@p*jfd&M>>W5L*X7i)|QE!Lrri|;VG z%q+k{%~7#ZI%2+dU3>zh^OeeM$T5k=t9I@urL40yZ$|bJ zke?UaB4?7KE`5D21ke9R#jD(lo;L*I#TSH18POW%ML1}`C{&IvlT{|#u~hJ^d`O%~ zUH6ZHbpD~{YJsZn50q3B@m1+6D3+`*+zMOqHOZ(?>cY*kV40!yDGAFD z#wxeuLBt@p(=JAa10W}+gZF6>fTjbG6CO4pq#CL?McoxDb%B#G}d>6Fy*kWGZMKW{K_XIyt zHkQ1}LF#-y>k!}1m(6ccv6F%`5+t9Xd4Hk&z9W3I_$Qe=$a6#`RPY~&UtSDmcmlDz zCw^%EyHWsc4MB+o5{X0S${+ccsrg;VNXHfc`>_K&UP1#x6KUIg4~PDV)MbsuQ;ZO^ z_^HULIpdLclb_l7_PRz8{$<^#vG}>*!nz;8{o&ou+wYJ}g8_F_`OP=1RKxKLsqZZ_ zAA$`+Dm99Fk=f&y_BuY#Ws*KKbP7(t60K?yN-BuH9vQ!Ol=EvE;L;eZ<2MpExmDqQ zckw2tdR51jenm1$DhS2VLLbcB@^)%fi)+cNeEIH z#8uSZ|K}e{Zsu}47Js$9SNUYJ2hWs z;rI~jXVMq)KTq4K+#oRbxVeq0+D!vrh{HnpN)UFTQ^V|b6PB(hp_3R4x{Oh0VIm4$cC_o1#I zn!<@#MW{^nFlAPIH}Nz>@dn|}oMf(9-Lb0eMfELMD`V+N7^{g^=GxXm7(=WsFc|<^ z9+NVKHGn%eD!dPmhRF>7Yf4@@yRDmNCdRcS9jZGKpEHwatSyG)o9m5r+9M-gM{K)d zcdxAuRDy`p#U?e4GEv7smxAG6~&0&#JQJAoV zGJo{e{$amdfbd(AELkC)PrQwIshVLie9UbDCN+B;o2|i#R%|Cxxoua%_=(tF=*i+^ zuTJ<5f)$`eDKXe_Z|vxBQSXk}!S$pSJ4sePD_q*lMXyQR$`}JM9R&*A2)i_ zitH-XXh|@4aFFZ<(z!wTJB%%qnZ+9=IyCnHz8~X5WTI>V`sjPgZEsKx>eER%jsnaT0 zmPNC#*nzp&OQ6&8lHU~>snSV&g)R#KeH;Yw$Sn6!{#v!(gw=W!2 z?pVFq?uU!4S?9j_vbdccA@r|$3Iuu-rc_M;USiM ziuGk$P8L2e-;Q&z5^$U%){~fGN@{OT6+5mu-75QL3Y@2jSG85-N|H>*=_0G-M#q&! z4bmARD^GGPUQlLeEX|qzVcq;8JU$2T6`P2T%hgshS7oo54eE?Z3Alr&!7T9TcV zi-_C0rQw*eF2TwgI;5M$Ky-^-ohuNJS6sLa6^b6w$}Z7Gb@aYo7F(}a6(S|_)Ll0* zbx!n&Hd!^9ossAlsJUs<2ck?AJ2fA99)XKIUknPZpOb(#&80P0WdB53q`^mQm?u)z zg_;FFB=VCSs2_IY+zkVD{-kyqBAT-lBVr$~jKeA_dMhjbsJ%U@!- zl8mw%Cd9zchY@d($5zd1Y4C3dJ4Zxbli zgF%9xZx<;4ATCj@RAoh6E82K&;11jy*8z0iP+Zp3wA}vUdWm{-a0CXH&iZuubcW)4 zlpF8&Z*@`Xmv_OLRp~w;yd;;&0zU7jY_4AG6Gw-Ecu=4_ z|Bmz>57F%Wb|XxvOBsoWgk0Q3MRy+d2)4PXSm$V{^)SNci50uZplT z$|rkTM|{muCRr15Vmu{K7f_PgkwKm8Xm;AFHWWccbK)D)?3vR%My6U+LA~)!vFnm$ zunMUd&IuCnExW$I)+>AugAN5zrQAAuL#Y*&*jKUAzER;Vc>t->?EIZtoE;qP z%}S<#@Qd?MPkdKsmpb@iQ(Rx-dqTg+c_6|=-Pp4Zbarj{jw!R)S4v;bkJ?%*RT)3Pa7;a`fZ@cV^ zwCBVxY_}RNLn!qxZI?3!0XrVbzXH)*ou9vB`t|;Rs{B|3-@4EBmH?NywY- z>EB9sRMHUvhGpml=|~S=HRA1drJJ#b{$>X z@q6P>_V~r*jLl}o{w&ER`F%6NG}G`GiHA67FmQX#E{AXfS{E&~4c`IK6>fEE@#iU5I zR>eOh+ja5{$$VzJA`$g2M1S~ik=nL+b5D)`*ghstFch(d9Ppj~EBKLIC$N~&k$!SV za!kD}{G%FuYRBw&#dh6zxrm}t9i52RoenlH$D4~M9kt>)xt0;EM02c5gkc>_V_DG7 z-_}GnyN>#$l2-K%o^N_AXZyYRn|N@yVtLz3a{AJk)DtU+RH`I;%!(ClcQsErWp=D& zyP1=zc)_e}yK+8vOr16@RwwZy*u&vb+a#t%f}iH7j^#6X$`& z2?-p*e2 z%1(!1`4m9Hn@$y|yq;~06@b%3ewxQ@jQZkE{SwB4ck&3ZV%=Yi2`QV1;$kyjbM6oK5GcEUq;Bf<;h&}wn+Z&y+ zH^0!kZcj(}P^~Y7!P0r`C0IU8#YALadkdCK%I!wkb03klY7t>b0NEEry;}+_)coV< z-cO?P2cj$lZio8|)J3VI!-M-x0$Ws{_JAAV0FgWMwJhrB#2yIL+0`g7iO4`Sje{hs z6z>@Q*oFgfu+W(~7S}w~zVT*}X}K)W6^;$$S%>eP;|*8P0(HsI{*%hL43CG}qvQ{~ zX>gDli^HUD&L>g#`&(z6-IL^U25l2f^IjZ2Q%+xUg8|3%TeGtdm3yvWlf@A2h*AvG{wR17+ zj@dKgc-ynG-POYT_yjvODr$3xVUdUvrJ3}XskI#^N!MRYuD_*#zMKWrh`v0|O$7#09;5IN$q}=JYx6N;Y!FR3>)!qir05;`n-Vjkc;{h3G zN?HzI?bg!!5kSupS)+*HE_$?`ZAVRQZ5DJ^F+u@;OLEjY^z^Z9?nh*O-e>TYCt5 z(STS5MKD(w%-DB8oxiGmjPjd@n=A5_`i^Kzx>Hv*&z_~(;JHxUF1;&;#L5<{`vuYm zAE6z?_CKmgnqXaaf^BPCPOZe+u=dR8?$5R~FP^l3)zd3l$Z6 z=D}oELb_78VxDMaFlSp*F0U>?g9cI|JSKQ&-BsBv=-$-1PQa%Z93=#9k!&(+bYon;rhP8cs`~XSU3i;pT-i=9da!U<6XcS zdW*=>`K5FYbGw}*REky0cgT>>71}RXwt0-m<4o7{1bCA+7%gzl9FI9?+5o8;uIL4Eq` zvtBB`e5sJRft444hPcc8!!h}y%nv65Wdwv)&lez`bDRxhjrGexJAYA^Jkdg_>Zw_#m$_OYa9zXW`J?lTl6f55xzgI;Hq5rvb^c z?-Z$=SIX!lD8I{&oPu)kR7`Vfd{C+)oYh;}$g$pA@*h zvEB1#la6xt+x2t#b}$6o0oA`fAb5WMF84SUZ+iZHO7wta)ugIGBlDm@XZFpLms691 zqJouyM@uc+^ z_^QYTIiOq|{zCdWvD#YbvbkQGXZ0z;%W^-EDlWO~*M&;J&^E`W{f0=T6Vl0PY(Vc} zRB*2mvO73)<69t|kDd{p&bkHNg{c;CV*y#fD*bk8_Bs!27nNRYf)Y5V-ln zf8slWpUz33)Kg<`iSLS56=*Wu%JB8~|DI@lB&<`JSmaru59Kr<@lIG*ES?i9S6a3m zjEP)>FuLypcivZ=fppYE{rGhMK#UA0vzY{DC)WF0T8zp`( zQW{>?$RdJ9;txUxgTCrMaQvGL!mek==`%_gME7&79D> ztCf>+K7RMjmm@nCb*!OY5I#Nbw}qFSS0yXVD8vg4@MkR)bS@J$U{GbtOd@&>WzQ{=+GAU*#P5m4cYS6qvtB~QMZ$au32v#wICE>u-A z^qCADT-FflN-`L4dPJ`&v~Bu$;|IoZ)D$^{dM*F7XMQc6nHXbjkj^8T=^@{{%VQm> zHc2Y&u_*i36)BmTKo;&SJmGrw#C<{;juVgf*5#Q1T4}3R_iL{h8;I6*3rQr^#yZ2H&h<+kp-v>}lxT#R-QaD_?_z;_c z$ikJQaP88cBsQ0-m0xT`>oJwbdSVN~jq>YoPizfmoHyTMOY!B(eYwkU5_To}0iJ&= z|59@7t6U5bW^3R{g9mOUED7{|VyGH@3Rq~{b+fJAH_snLp+)*5&4+w}?ZkITQtnyQ zb&uFysMhSO&Z)73V?J2|xRLz~xubMb^W))oBahih36?W^v-#wO(?lB^VUt*5I*|3QG+3tQ!Ger= zlbIp$J++i3CB$~j6n$g9zxm)ejAEA1rTJD&nu!ilx|r?Aoh5_~>lQUffMi{1r1HjO z>>P%{J?y_t4q5xR9eWDhoKWAWbuHSlm(bSvZO{N?T#vmS538t;{=cr~-La3f<O3N~E5;rqK0T+AtErlEzr?|!N8|~M>m>zAX?I@TSjX@&Ooy!Q zI7G5ad&FIGgyZ~Bk?V^KAv7@khuM{oIuS%EV0c)_QdQvumARURh@o?MH<&B^h8qR?cuBKU8`C7mQ% zQO;Dd&ZlX|$$~F8FJlt7)Hj?WT2=@cix(^OFuieVjo_PeafQF7LH0D!iu+~rWrnau zmw&o{IUt`GRVpWmAM^~s&Se@ggIEG~f}UPyO8enlbm$S47rNstvCZnngEw7!f?GMW z-5qE9hpU>CP(e&~)^cD{iOC1>pk>o>rgTZURZ_CR@e(wIu3NC~79~N$<9o!0lMsf1 zFQCa}dIi_a*~zFei@&y`Pqd1=bFb%6O8a~C3vZUoo$v=E<`{+&5W*#DbhY}(s?!sL zLMP|4!*VZ&pDXh9>^nK6%xRwRCOHAf!sRZV?>gikHp^G#m?9MtyL?!z&ah2B~0K(jEeLng13pM+kBBS6rfvDVqE~zxqM@KAk!RTB(ELPZC@Oo*PDp8z(`IR zi&0N|81I8RvPl#xniqk zU-=-4M1fg3!8TJ7c)nO2j%mfiC95452$oTUPlP+;SX?M{PEN5J58mP;kj`7{X3VQ$ zI=fh!vdE%BqUNaWvPlzAg;$;J3RNE;DNo?ItS~J_sRZ;Z>udB@@w%UzY!zW@EG`$T zV%i+nhAUnHqOHg6k@q|AFINg4SfJNI^)YdkeT#kMdCCXkSFV# z1FF6A=#ICE?U$He6;4P6QhUNNQ`Jhm7%K`c(T;1SUAb95Z8G($M7U039A@&E#b!r} zlQwrI*2nddua%=9`;PF9;T`R`LAb6Nn3VV=WAP55M{?j+Pns*>5jP4}RVnm+J-%(+ zBz9(Ud(VTo+4f1rBioJ&8IZ71`HCMBE*-uVJ78#cJ08{5ltW9aOfgca9?H*BA(NUp?-ATD zpVgxSk2`xFRy|wTwbev?RH90krP_xRK0YQiJh?$(_Ds>eVu$2dV`hVnj|)_d0BcXG zW{&&BDm5%9e+^dnYy)xrmC@cNa*U4E7foqTlBElPOr}e@14i%b?uu^`xoxm-XJ|@ys;5~ zD~bn&r!d@_Lv6`8|2_iT7`9Pw;SKOv>F^CrX`2%b4gGL@PO9>M<`ZxMWysG<_|FoH zkp6n&QHl1+T`=q}_=4@Hi=P>GPZ0`{@{?w*^b-MKm3}m3jLPSm#hVm5Z@>zbmv$37EL(nm7^PJHda|cPJgCZ1q`3 zT$~d-+)WObk$6tz{k7~{Jj;C?7jM`uQ>E6@E1tn-(} zsIbhBpsf9|WKBK`JPAn#IuJh*t8|t`edkR7RH)SS^HGg5_dj#26Y7lN%OV#3Tx8iY zMX}Kq@hZ;?tx@7Kxt%gW$uAtLR7U;1#O%i}1s3PDB2v@K@Axah%Kl*rwchx(z(X@q@+a&Ul|qL|B~qCB0VLUf zdBK0@=Of5i6ZQ%sRRe&F!+5M{yVmD0hfHs*Bv7&>TMyZOuy-I%8a0p&XfWYap0 zMn}k_3-4dkZujSeb5F@j&{{&p>Usu@HeOqxBDXnxa57uRfljF9r0WB>MYMT>6t(x9 z;wHe8r{R1(;VbJ$2g%xRc8&GLI_f2L!f;h>0LHCEnUO0f1>`-z*Q~jiuTtfo?o~2ziy{!8+scGwO{^rFbwO&M%%0edzE+yYuadxMcSa#^ypL zxz8sUtrc4cl*$B?iW&fz;Ff~r$Aq{(&T+VvNV%Js_gD#fYoRT2bmTsIqOJq#e7tU2 z`1|2}r=E6O(FKJj(?bhGWedBPW2E09wzpl89eUBiz;_U-&yZi!C)?4nrdL1+`2neA zA<-LiuV7@tBbSHWSt4XEd6#36M{JiG%hTLQCuJ^*mP+?P9hhiBiAUotc9ZhMIhA~O zq8M}Uyis&^j%Xk#Z?(I~=kkk=b0*KnDM#6Hig0hv3X3}xVjV(XNsfzrGB(ORx*bym zi(OQj7JEhr#eeS*p;C9CV$G#+s8Gojd=fs~VFG0VH!~AuZ4VdOvd&mk31*(9 zKm}mu{UyoB=kT-QyLF0gRWd@428uXRWktuf4n5WtO%9aq#EIErJOU%n-BPd*pYZnOi$&S{hNvVHo*>f`BD%R_NA^$T8*FE9^>FTTDeg#pp^bCno|%7M%YIapxo%H=5J z@Z=1Nxx&ZgEa_!|E=}OC#TwW%cuEY#5LoB*n(l%A7?z|0DBuy?1*xSf#b@diLx;Oq zNsk{L6-MYyWr})X=W@Q?ONqp7lQp5N%3<3gJQ`3mFK z_+g$2Ru!yxQKeAz_7^+aDz$4_Mne;<;!7kew%NNF-@=GXMSh%5P9{{^5>J2hdLtX`b9&FP7&o%mk)Y8WxJO}|TIaV-NV;}*v{yAg0lVS_yP ztP&;JKkew!oxh;fg7L8xJ~$o*JtjC|3}qX2Y6al|DRsE zySrm&c4q_Wl=#pM0@E`)$^Fdi?kp(XDAL^}QWAnlvl0RV3W7*C2qFT4ipcNvI_DYu z{{EOh?t9LCKF@RG+;dM-Sc||M^g}oXr(^wPJ}OsqTRZb5Hc zQ~GCdhBo6$p*w@ApsvIWe3d{Jl+HITSA*1MNfBvuAC+q)EBSo(n|X~o%e8{zVN?>K^N7Ol3FVqkL^$&!;Q>TS3=J@l*Grd1;qM|c;7mUk&aWd>f@Fm~>HwvyFXMvyM3*97?+Rm{PCYPI&BE%*#l%b35M6Gm-Xl6(Ai&^Akyc4@4W_dEqN#x3YNc-eJ|9&jY0cu?^>V*dtubqZnkmZz5>c@&BGIEd9XACd z4Ih+pN-(%S!YdxKnYDh&QcxbYnVzkK&04HxAc)Qsd^;YF?yQIUt^%LM;F0q;6>31E zZe?hOxkIx?9+fU-|3OMGmd7MoG`BLj4GE5aT#EE>#j`nVOTQILE(62uCP_`2sh!WT3cwRBFPx{2;^7!U_q>nV7iz+Ett-6tsbGz z*b(<7N6n}a>`~|fuoXNj;rF69W)`ApILylL1rN+a7_Q70qhS-He!i2e&EWTgB4I$M;edru^CGeVU`f;4ylr*rZCO4(Uepw=Ay+9h^)C1$BRURiG`F zGFQ?W0|f+u}_LAI(!3Ic7?EOOnf3GeusMxxg`0@$hsD~kzWSsjEeahcN=SaM0QOC>oFhj zrAR8P4&&$Ju=z?X#g|Z5Q;R}mLT-Bwe;@v@ByyugpalZVzlAOdD)b2>KK^T=HDW@i zpvL`=&5Y>Pmum(e_>E8|XoyTE<-ZBY{neL>Ym^D!%J z-r3nlAu(8H%eJp)p$z4r*@e;te$e!+j`kd44@WnIxuG&AZIk0FUL!}LX=6&~5+n_5 z9QF~XOAs60bN0Qm8Wdg=(PM6*)JRX~^Vy>Fh@@+0jQ6~@Gbjl~4+=TzObD$X+fEm8 zD#Qw;s~$Qj3@E(A0%AwRkGX#28w(2c$7B-1CWl{0H=cHr1p7PaT+F}l-mL0n9dNtMiumuy*FVC|Gm&0rb={Stzkcx9{6wQo{Y%7l$2AeyB2$vm_$BcX;CEE*s={2iCf0L%jVktE~!01u)-e)ncJi+ zXM5!!BWnS&fTC1eSzb6xVY`eS+7*O$jh=&4Gbk(Cej~n|f)X&Mp|XRp-utxYR8%UZ*V8dAIn`~%1OMy=sKdEeFvn}3bVnb6IYxCq_ zf897~=gHh4_*ylAW1C8&?ev7`?H=Z+87GkQURmJSIO73ppXa*KlVAp=GfI<`J+bj- zbhS@mp3#(v9TC`J0Lpx2qF7264c_=C*{;T98WJ8Kd#+~dmDw$l*6$Nd}5dxv%Uccxt6nGD{(y_ZE9NucK)0qhzc@w2u#cI6fpo zt>LHp3Z=tE!&pip>}Pwa(Usg-_P3ob`0dyQ+R6a}IapIr`IZA|tNU}6E#8XL4I#3R_omSZTa4h>nM8?Ogd;G_B=uokFqt{`>9q=RDx#TgX z50@6(3&s*ZtQ!M|&5RL7aP_2X6G=;TAf;WPGniK$_KRAr1Elt3D$d#%<4!5=%@xDp z#(`P7gtD3|uNq9Fbc@Yj4O7#kGR5|UxW{l^=&_aV&P?9GbjQB;|MX~N8}!-EtfEvX zAtb_6svpn-W1g_uG_mb-YL@}wE%Gka&@j2F4BC0i{P{)-3LR#9uXtgtF?pE)T3tcbDn5 zD=wrSa>RC3&B0|0r|B;<1m_QysWH9uct<&0aIbh01r7Vl5w^F=C)2b1(Dudg`iMx5 z;EzO7w3$MVxpJiKv!aLMQ8~(X#us7h!d%649xavuy_i{3{y9c$@py8_ume$!6-hJu z^kBHh2~=5S#!i@6j<=l|f>5y|vYr4?JG+{Zu}$O3iBe?xnuf7WlgmlASC1L#9Uh2t z=47FfWUwW^~UNSH+fR| ziOqU^RWtSA7?0CMDz?@zZc_QF?YzZsVl*ZK*U#Sx+A5Qc1ET1UftU z<7E9!LOY}*+ULWe*@Nm3BveT2yGZz8qO3BjefYf7b?sAn#x@C7Xx7Lvf za%?66RXLjpCC{pxIxp6WBe6sU5E1Mek=|wYhUwj)0Zx zC8}nsVe+{0bKB`cp9LJfag`fH^9D5;f#61)Swa;j3RwS50(-?xzXiv2)O70T2=Ww9 zT^#pj?(|;pZUMA%y5d|9feOEnC>6QPuUQgqm7;a@7@ah!+$PCRvF*R}Vl1~yg~yD? z1+pS(aH)nW;Sb}R^&1W0{Fh=&1tUZ=T_+&k*}YRVw=?!Ms$ZbjzRM?WQ0a$MRuJGR zL@;Xz)MNSfyX`kNj_2yyiINKIb@{dbI3Yx6xY>91xqE!Tp?Nhx3X7F@ucWE-#uBE3 zb-7O{)7+TP0wt6{mP6JnCaS-e2LwNh&zm+d&=zy^pxF8GdDX4a9s7{z0zrurGLz3* zeHg6v!(7lNGvZff3LTQ`lDd)h{EasxhZv>K!S+m+pZ$ zd8hZ5KiGOHo*n^=MruDNmibd~q~%`uybmFtou@2bPwa-c#{E&c+{twd>ZW7C3!;n1 zSD@-|?qMMgl@|pUjc>>MqlXMVe-c?ahueG_-Q^_^quv}K{Man}`)7%^jkn7?76bCK zWR(K~R$g7h$bR;Ulsm_86Df&$>D3aQKJnJHh%wL3l zAKSRY>^>jael*6fojfB**v;i*u?u6Qrl6}u@g#6ubV6k~SU#a$yCmH-aQ4@%_BSD{ zx=u|lfbyxm9*Ske1>^6wGD$dsB(d9Sc$>>-!k@>w(R(@LLdxf&X=AK&nI>F^W%-5R zvcYlmo+(5)a&Lp<|HFS=5${{acGp$D6i8RYNV%Y?bWX}Ez zRNFQu5+^?HLijd+D_y2yk01ex9~=sjWt|YbGGKdFu?e~Oo4eeGvx!vv6LpS?kJ*JX za@lwdqBsGx>udWW4;=mibBf%ZQ-u>=GnGc>vR6IErWZejZju3)F=9K%%-~HldM%$@ z^wvO0v`x`1&;K%y=xVtO*{DibWnM7teX<1ZPy=e^n8o=d&HHW})ll)QoL^*(_%8k8 zQ6MiMvQo@+M5Sr(x598)(0^O&* zk+GDN(_@QLudggE*#l{-m@;5d?`0%dG7RGX->0IQ@;__EJF$31%5t{T<^HW>ZY<0D zs2#FoDlb)5@ZXtt1#7!?tjdZ)E5{QiQ_;PwWIL^ER%bQ=ff}@xh4W(vTf56DHrI() zp58E_tZFm8{OY}0idF;A3tq9M4@21M5-b?ooV)89w)TpDb`DK1Yua2a_~~~OhIhwW z!YOUFI-qOYUN_cg=b&G+jzETv#Q3gDyS7VS4zPaK%X$(l7QforQr7q1cUEhS)2AvS zwt?{0d0rTg$BDh6P-UTS!KBdT<*8ma@^O=s!zpi%wY^q6ez3JP*y-B2<1<3@o@F&k zqg1)hNP9(@#(EhiX-mEdJAr#xWQQCtW$J1NTd{vO+1@sWiFTP_Gb?f<9O5N8QQ(wV z!2^S=d@c%;@)0sv(l1(5XR^qaF=`+MvO6Vxu1bm5$sG8{2_`v`p; zs{=<|oHX{e=aU(Kh38x{sQm6AC`kK*RA8h-FG1mIAa5f$y@_BAT z6Wtz4+icz5Ia;{!mu3kr{cbYiT?vO2ofHo;JQ7yf3Q}7xXC9llZqIE(tbR`;SU;ys z)U0k7UbtE#R36|hI)Ey>XFs7RQ&>)=Q|!Z-*_NjM(q*$D#vp3AoBy?2tT{i&a@s>> zipXoZ>NQu$YkR~xVxAB$@Xl*1y+WyDvE)d&^!0(&-pr-rtW*wQXtN}KB7UXLoNAaB zN$UybO5!h2%MXgB#g1$*EG9ndFdwNLp9Mxf|mW)rt#gYw0ILK77RbtY5Oes3eb_Nq-Nx-|2ilstx=4wZN7*a1+ zMg%v?yEBGBmUSkXogw~J{00hOE7dfY!^Jj;wT)jm{P75Y(L90P)mX*oyQEq-X001$ z@gtj0#f!zH9%&y;!0y9%EcT?M#85)Xs(MBqxuM?m$PMLaz$%WdN7v5&a*Sk`reYKY zu^PBzg>J4~toWXY96V0&uDqHPok6tIP&po~GQk;Vgsyv_oFJBWMr?)s?Whb+6iV+= zo^I?4+x#S-_k42cE{vr^ylbH4%RFC{pxlkICRmo|lbrWWN zku(_>j4Z_hyI6|ZafmUtllqn`RjV(9Y#--3BaKfafa+B1TL~|?(`kQTzk2h)4qZKxMi#=Mi$9UY3 ze_{K-xnsIX>nV%|D963lMfOevRXWe(jhoy**+)6fjZpgW#t2( z5={M@Wh5}K*URt3-irCKC^07&ET+9YEu7b>hKVS6pP}tI$XnO}EX8L%1Yoyv??>#4RMtVj8gZ}coq_?HCX3jRQ1gxY#=0oS5 z#V8`G(B-mxLG;~G-)It~L@pKA#*6-E)%bSYxO@!k;7@`l2I#wz1qutmOM+P$41Y3t z_@6;))6yl`!LKf+FAF!M{)!n7i|Z?5OQ+om^=i=ZN8E;+#tdd-M)s4gZ zbqQZe_Q>RfDdG*WPjcI`ThL>W{s(6Jru`3z3F_xo5vejz47?@$>-e5FJUl6ZhoJqo z;9da|WI+jSRKVpOz}l>{=cO5`w9ef@+b|D#SNgn-)D0UTK2l>zLKtrO*as5M zJZ2UhH9FL1mcNQ!oj*&072fOk{-#ITtYyo~Q_`d?2D3RSaUx<#R7&*;o#_|u5W%HNAf!MR; zOToi~ObLzH<*z{Wwi*30B)alXsSb%3p{5ZIRsWJ`z5ERHVfn)4-;!lE0HzjObNN~% zBX9Nh9HMk-`H$EFF~%sNlph(H@{Q=)@phzVVQreE@4te{TA1t9Wqd1kO}sHPp)z}x zW{~xwE9Q+ZRU<=XR>6H@SEKdwfNv|aiQO2#j0y;;AkxFkF1mA4=2|6Q60Ej(<@m%& zj0SH`A$-UdoCQe*qg^DF$_vw6J|V-Ju-TCEP>+l;g01mmodd(nmUUap+@h5q$3${i z&*M{%txTd5u}ID<@I@{n{L#_A%qIeaQ6B5y=BGQFm4N5>Q5ly<)`xJyUO>|Slk~0= zKPFUa5-t$qLw-xrmA7+aUr2DSD9^*JPaUBA7Kf2pVcW~X{%?){(?M6(MFbzrY0FqA z*UzG$wS)3?arx&4x0rNy#%9FWH&hmvqO!wvYN=g9U}kRDE-ND}DX@MXGB9ba)Jyr0 z8*@sLA~@4w)JqF49TSDK2N;8}j95C1amyZPAD+tlFY5zmQZQW$biqfUhAAd|sy7I#-Nr^l;7nFF*sjOdFx=*8T zI=Di%idbX(hSyYC$Ereo$s7k{YK$(Fs|nv7;}%^i`;d-8J38SIR%D`j)cv% zt7JXVtUqJ?G5phXC}n-&_hX){^ar2e?At&vO<3*tD7&uE$_ZwfjhWY*%3vdbdE#r( zxhr^%6DP&|wYaA@({VysKZ{B{_|A?O zI522=qgGhg@NFC2f#6*Tef-Hs8<<5EuF14M6(w~m_*?QU8b{-XuSy~)xf;+|Q zSzbxTw~NpwF-92c*k_RLDwaD2CeE3!!fQ9dtTv#n6GZ|-#O{LE#RG|~fr*r|2T<*f z6qvh)S#EnulL0cZN8@(7mtfZ3s}C8zu(#bReclw)Jn*6QvX5kQgoFtL9yAYXD~ze^ zE1nKJnE6R{W^cS{T{he=ac?O5OOn=AguT*^28lylM64wDb* z?jXCT+dp@HFRUZw2V%Kr(XcV>y5Suxm}z0jL#0D9gK&soCfI52Z6OH*N#n|)Nf}Gq z9nbYmO^Ck-fWLI6dJ}`MC=QM4pbv^;k((Y!IyW zS)NRKU^*;^Nw;p$c>=}JRK&iB^%z{4y;2wYCU%-b*G*7G8=x)x5}?018xZSM@X6HIQAKo=5UQ4ilqz}YDRrN%8vvOjB#ZN@l#o+ z^hn_!1T!2MGI{?|0_z8WA33q1M+>yZ_-T=kQgO$KQ^j>TZvR!;CAm&8JE_CnWLP6VkvH(NT+aQ4A=s$BmkNqcl^ z0N760bCWxsEWT9yBHPx(h6kS_xLgb<%*CVyKKxYC#RILzUi384h zjhbn8&`&^WV@9?3)Fj=9I?UJdpK&emve1z91}gt3sqO0Cp<2OHY>=K z^F`7R2K#GUTud(zn-O1-M`-Zxk#eEUkzVwPC97>bUy|xh7#GRlfX67=KX_}(wR!q zYXxV<0|*Qu{bU3fT_<`_Ob@k%RS61I<o> z?pEi>-NMsijo}kROcJFMfNJ}u8kFi;k$>kNu{l#cgX=asS@LB6wBs*doP+7MfRCSl3=3`h~pov9;_8p-C%jp-bcsUn1(+*9Mg^Pkm!N2D;p+J zVDMr4t(BJpWCGRoGbQ;Tp42eWs#?DhI5t=v0w6B@=&fR+9`PUPV=$I`?xQx>3;pXj zitasT^On#tQ{MVe@@a3GD_Fm_PDST4GbpAwv z6uOA=l-QZk8Q&Uo0xZnmiRBz1`k~0_El&%b7Hb4KrjGIB8Idbv{zC6Zt|q7TS>c=V z^&48s?`_VVhV@eZK&$rY+_5RWzV^iR;W^PU$$w1gjXv*ryQRk-I$h0N)5;&kc8rz5 z!Ow-cUS6>0?3r3GqM&rPMGH4lUX=LSm?1<#0yu5w4R&ald_C<`%S%En@oH#@|LmiP z1(iF=SL%_Yio4{?{sVu-P%0?!;cTFd^A)?VA0Ik(YQ4N_bI%w@jwMuIER)y7G7}+X zBl)b?eO47b$?4Tz-jE{e^bYj2ls9dDFBZ)Vj=Z+=mcX((`=z{X_ce0+a(;4#YNLHe zn##Ski}Y0WfvM$PvE}1!+PcjF%ZI!tmVQaxb}??VBHs6j@Od||XU>R4D?gBMLbXyk z3^B~11c&-V|B-@=+EaNYU-=i&)#DM)9r97Vd?dDYV4cktDB@c`2CE&OcLIK^ul!X2 z(}LPav{;01+N&W}2i!VhT+jnbg;mx)S?`+K+*3Z4EI*_lo1S%*%HPE@WfmE+(QiyG zp9y85FNKg}8ok8-I zSYAsII*p2Jpe=lS2*&PYytc>7w)e*tPQ=EE>?Mr81}5^WNjr4{knX!}`OAX_0n z(?CWCWL7Z532!6tHr<_PlWMUP9GGH`ba>V50j4#8(H@Qiat=YPReso1v+@MHozo}& zE5Lr@P6(5LH_s*M_~b^z6nzZ7H%7{9V~9HjNSG!KBDLnSZrnoW@!yk!^O7-!Gl&OK z4MD2?(yycs+vI$)}Ks zg)0k*EEW3=fqr3IkA&w3>2Rx^pP#vi|5_jxC2j}2-l76u2Y{xQF5) zypw!F)5Nl@|IUi%gNjl3ka9*ZCtA4-5Yt3;zoD|cSW9&5ZRsd0_#kxDE(7lKNJV8u zq3zP6ZsMeIWhHy0Q|@@If-BqXi%;P|ZD%c&RfHCeXHqVqtZH-Ne7A=2Wi^}0=von` zSGT#(cXB_9R&F<58Q1V1XT|avXfd;|lfI^42CGG;W-qjBiLDtEjneR$sIDWrecF9=N=4XGQM#`1JP8A$3W_DXo-j4B9apOeu1_0nqK`zfKq7Nk zHxQf}#|7u`|L_gPGZ+b#o~7)V=8b$J!l-O^^s~xXDOZR!$-DCq#3HnKqM4f+Uy2s8 zvFM=FD4Kc7Ri}gqg@2uB-d3ZECPOtINNbC~gaQy{PVM||NXNwjK=1&M#kWGT+7j-b)EE*nd;Zu*!C9fHlJ*)2Yd`=BCQy=+m@h23%( zr|z<)$Ujo;IIX#@s{FQDX|4xMK^_siCn|67;?F?rA#!SLz0rUZ3HKCUEnrre zb~Kh*PuWX2g}W}?Zy?+or1pBU8zg+)Q1%g8GM5$7GkF-5BKEcG$1&v$5Go}Kz3nHK zb3@`WEqHGG{Y7_)59DmZEDVn?2l&uxFOUol4|C490|k3hoG>7Bq#Pvjajr@H)zNFl zBKU#ubrsLRo?h8F4;DT+slgca*x`o=|Fq&eynrT=dN~xda^%5C%1inA&62*Ck|vyl z^BSG2|7h_am{in0`D!W_TYbWEF{p4YlGWwUwMmMviQ8Q5EZUJe+G1$iW2-h2wca63 zdp<6X0;aB0?2)|JBTTgAHtMqD%kd+vBy~_v025Ki#{?0?@8!MaDK zQjb`B${(cM3t_KUY=xwof@;@Q*yrfZ-NwvYbYf6Zl*X^jpOUnqqb!!4*}AoAZ>4vKyw*zb7(!4rdwJE^;ONMuqB*i=GV zhiO_2%B9Wzk!X=YueR9xk54Oa^c6FZe+oA+~LN0KcgQj`91U;7T!0=uHVdWbO2nABm=z zi_^T(-Q`Fi(-k^NXfE(6Bkh`GRVp3qU+p7cM@u)7OFVS^DbODy=`Z8uQ60$yC}$w) z6?q458R5)l;~XblWu8{j;=JIjJzn(d5bANIXfG$&bGPh?GtWRB%lV1Yw8r~&jZg{= z`ROFdmdJPR7%=T&PdQn#YF(Mm8LoGVWKAgzQ%jR*R)HhZksoe=4l}Rlr`b2leRN@I zmOs|Zk0st@bn|u~UWCx`6XB(E91#A)Y{u}M?jtseaiHW^GUuO)WiX&+z}TT@h@2DO z+haV?nYL4Tk8}Q@1q;eqV(B3nX#(-)6G@fj2)m6?C};Q_(W$YtSlozW=L+nSYYh+6 zzH%NwZH^o!bj(~c+spY9Ro8kPjKg8+0Ht293>L{2YW{aUGy-fuQ`LeG?Povq{JL(o|i6_$|^>u2H__sNmT;Z7~m>%}G| zZG`+(bp?Mep8n2U=j37aa)a1c@#=gF=3OqqUw5nUd>K=i6|X{4xeXW-mEC7vubaZ{ z0#)%O!t+S%dWT59NVt|Ld;ij>;clRql6N;<`tB5klY5^f2~1bHOMqiaG7Fq5#i7pg zfrrPI4i7;BTke+d$<&H*ds40bYpGJa=f*1&Mptu>biYZy+u5umY`IrxVk&lUeun`f z-GnFqeLi93m=-nUfO#U`FMd~ibHjwm=-VC;*ddoPZ|JVzw;mMD@+Dn5H@P|=5=%n? z=f65WN8@48+JhAnwRAnaZKl{+>4P$PEKx+iv1@CLP16M0kJ!#MQWO3Eqqc`~VPFEM zmK3}EF~LkOVlG~5em)LV8u^#Pea z!=nc^A>M#u>&1w3OCv<%4+5#&*6`V?cz+$mn_eV%#1OC6ZEnVI9UHExL|;U zKEvx3;9dZ%Eu2bTwm$pdMag!J&r@_ExPvpW{7Jg+=YAO=l}TTDNxJmt#(01R;?Dx< z(B0YGGV==9mnpCO44i!U!=|)f`dcwH-aQTl62G2dnN@rEv>_PsiV6G^R@Yb%lQ2bpm3kvd0QT>M%`WdJhibF6}W`f;(F6ERM zl70*a1eh{eUr2azo+y3ZQ_4Ri%N(Xt^M>-JG=sS|*cr&pwaK%Eo7w;2c*)$p zvBPS47WI-~t8#`d|Fsj>0Jl4l3%-}i-fx8;%TMeHfq0fy9?%!B+B9KYnbl@yweYfD zX0!c#j2%psx{b|ccA?6sU;#8gW)88+-;tbN=t|3+33(5J0}<}T)8-OO2`Igqn4U3W z+r}?=XY1pO=LV|nnYw4RZ*)iGn@74sgY99+>?!j~RQYO5Yo8u=_W7jAOc(fTazpkM zonP>v>JCGtjQ-Am7ZA>3g6bP8bV1R)TOb^9T`LQTB&W%H=E4G9c?1uPa1Jgauu}{n z%eX9R^SgXllgnbZGe>tT?rWGF78j}Fwj;rwX>*nkTsRg!3zW#yvSfC21SugHHt@2P z*v&Bt4Gj}e{Mp_*UWW9A%=0n;ri7b~Uih>u>;FHCr{crVU0Ta>A~{v=B)nP5@AWNNAY(o9 z8`m6G0w3g#a;rtl92hvAj~5|yPb&d|7qE^fgw_Jb;gnJXfxZZ#4oG7<@8HFx4HPs!6g_F zMgAoeUlPT?KcJyHO~m^%CH)=q$VWk7R@T!YCGU_t{-^Y>p0bB%$`&L+lUvI}^uF zE_>QOp=viyDtpsyH;&#**esDw z;s>H6@(&epBcnhH@F~Q2XssZQ=3cL~E94<9MkQCRhS3 z5_P9ySAPm#gc)y@G94gL;?=v*@{~5Q%waLo9wj+O(C5*6r(~Gu(p*=e%%G^VBW)T<#X^c{*;Ov$N+aIb{UPyYdLWmGbM9 z5%9F+4$>>xHZf4D@cK)iz-P&7svMUgLG{}e#-Y^V(DOj0jsamV6v6Z+jc+J}0!UGc zWE^c_^F7RGX0jYO11gy!kOw|5+*|5)!cE@&uE^Spt5_M5=&pDZ+$d3_s?b3w8)_T+#H~Q)*lC-21wIr%5=bL*T+7j>mm|g2+HZEg zmWZu#6wTV0tA|thbUR*u~vUiD=q`{A7;QP&r>JoPki(z(b7~392p=9f&8x z#Y41kdtVOhZ9;v|P_wm~tiOJR#HqlX2FJwj3^rY^l$JUn-j})Vw8FTrlJKz@T{TxO zva6*!Z_e0MahcN67+-OX|Jgc+Y}DkU;^kU#B90f~xiRmZik)He<-gbY6B#ZVrMQ?b zOo1e}6JIwOA78{3kRiF=M-jB`D^gZT1IEv#%iB>)-?Var6fiO;lWsV*bPbgorP(UE zqk~Xx5=fnzwI8`z-Yk;--ln+7%jGSC3s(!Hx_$evpn0#t=Rz(XzpH+UqUlA)8eslln)t zJW;!XS=YU5YFlfWX*-$iU^lMp-n)MT=8@^ag-xj!Zzl)i5lQp1uVtU}=24NBYQ(UN zvuPg_$}6MU@bPzfTqKK_u&B9x5V|(ye1GIXnMgb6h@Z?1b_hO>f)o4V*lOa0z%`icHQkZqkJEN1Lz2667Yu zUVcH~FFE%E_!;7jO#V8-J!AaT<~0)s`6nRDr#kkP*4UwVNy?1^fE2Q0>xm+U0lsM{0hIGKm1__rzWroj;0&d(ipX@B5ETUqrv`2N~fAK$Q9ZKeg|6xt6G1OZW13=~DTD=UPWcy?iFoJSm;` z4QP}7JfG#`QI4a*Mq?*5CSI6eC2V}TWBwt$SO|sWawAHnwco?3d?~(Qe8_i4+gD(w zBXaf0wNU99Y5z}2GZ+BQSpD3;1T*|znVP--Z;^dsje8y#$Ob78pfED5cp3@8@#thzB%pF8k0(#3bWN(=8_6sT-bD& z(e$<-BZ_586pa>91ntcoWp2A?qAy0n#aiYOIy2s)Wq>R8ytdP$oG=qpOU>t_UP=of zaKxj{hvZ#c_;k&*}9o`FbSxlm2! zuSlZRR+bYwE?9HZ#PMZ$o5S%Xc4;pw0I2X*_GTaARJWoed5&>@qiHKEiKK~!tpKN5 zSs<^D&66Dwy%_7{kyP_!+BZSJwi9BwoD)ij>s_7mRP~BP^O6 z9%YTBbElbmj!U>w*P5WlHapj?cnUzcmV{M$Gd%6rwwb=UWXEGf2mFC`l1LpD>G*hl z)RXKj>x!olrb5;eIVgAda7&w6O&P`YLFGce4nfy^OvsrVNW4t)4uc!jsOv|xq42$*N#4+ zjFU1wC{*T=c|wKhc+s6=X&ESPFe*h(1viS{LWb5yAr|Tc;p7tR+VJU}2vl1(Spb{1 zuS}BWruZoQ+|mr`g=n&PMocg+>0`_2l#PAByD7PGb0r>E!dLTr!{4d7Y$EVj02ri5 zAG@hQO4_3mb932DFmvv48!4O99CcS6o_SN*!hatfUld79um^jbZYg|Huy4X%)Lx<5 z6U$U}<|k)^ZtcVH)lo)=NREZyo@76cCt{vJy^b>n=jgV=DPx-R$2;>#*-kK(G`z7^ zQ51bX6zl2iJhX|@M&Fm_PvC3BhlDK^ADwvn(Hk?J!iE(V~ zCYUTcEQL`CVfO@G?x^P4J1jU{FMEjI8H2^O7mW^z`#c3i+z0T!r>pyy;7SdqIfdief?LCN!-`00#)`CTrysRpw6%mm;J>u zMuK`TeAWQ~wXaeeh`t4nJt^*uS%vFpN#P<#QB>ji14b|#$+GSB@&nVIbv^xvN{m=Nz?_DJ{3xbYtq&B>n`UZc$9GJ?#MWfV_rF0WS&^W z$RcUjWp5q>TwA$vXed~y%CQor5P>8{iZa~qgfeKFGIg4^kGI=m3&rxJ)*!!nf;7!> z`e6tQS1A_ziPGU18`5x>hOLM;K1uk_ZE_WQdY5vVWGIdza*CVEXf}!;OZ#=q=g^4ad~f-Q&^jp{XglvOr;B7JNE~AN zBbD_}#d6DQ%dLC;;Umugw*I#~nJ{GID$W$bg@XTF?GpR%{4o=W?mE zPv%hjAu2`Gv|T1)CIY}!j>}%TJP`**IR=jk^hj6OeU5a6m$wd>%rLm@m69j3gu5fQ z8_05%U`q@e@(pJ%V$#)OS#pPM%&V4bL^9VUm&7ioz;|{y3|>uDduPwvwkqNq0wc`K8TGs|#*7_2a4} zpm&O|98!wj&3D;6GDap60;qe2hx|%-$5`y$1^4;8Z7&cbmC938c|ubI;x-Tr`5vL1 zA+*b+`@UCTG>#mmt@-snv5d~-NKu$akq4$=6nhCb--siAK*GK9H)DwV%Y)MWDYuvD z>=}%QguYEX5tA5;|6zNk(hOw}_JA@|Buk^99WmD9HzH5PaC2>84L;(7ZqEm)3R6Y; zs6?r!?jy$_>(?lP$3!!g8uoZRbM%6F-0oLrB?6SP{pGh({V`s@rM)}KMm{0Uu4$1U zY;Gf`{F4&BA8*ma25m1-Nm8-BSoqW0UH;{F;wY><$2vLeT!c^Cd94_r{9Iov%M(pcc~R_7v83Q66s4eDJ1(U~(=QX`T3(W7 zwRjQ-F-D8>XQ{5t14M-@GxxI4p(**0uL&0WirvB zSt4Kjb%{#+Tx5%BD{n}}X%L4S8bCbG-41U`xJ?ian(uj_yd`08&Ic@b1y1Tby(7M5e0fWIdq;WKzSEOicfgNE%6lTm<{5#)*q?mgPW4zBEheTcA4v1; z=ncJ@8foQ2Y1Rxrz{S5ZME*rE9nZ~}N1%9H`ABTV99O-(>g8jfM&>ow6A9g^#nE2= zDmI+oL@wS|?I54nvnAf0`(;=8n>5en4n$9&>Go4eb_tRmmEC{0owGrWWMYNU)CujG zFN!XY<;$Z!7rY?)q2g~YU)X*#UJ|!C&5r*NSv}ve3-3SP`%9sgcoKsW=_aU10a&{) zUkd$zJm8P7J83CY~Rpjz` za3G3$vx!ya6!h*U*O^@?y)6_;%r;u)0MoAJIiPu&Wy3a}Q_73-EeP!yDsxG;QR;dk zZo7<;WbYtp)zz`gEzlP)!L1o~1~`w{#xa8Z%`;eS?PXq}|-M+K~%m`h28nvUrUh%J*~?37%EGPr7IeV&f3c|J_)CRIr2%= zpOBzR#AAxNf+Bo5i9XIZ@*ta0mKPaHq+MUgvVsVDBNv_4PlvXwD98qM(iNy#pp5rQ zqT40fGGfhP-+yIMoLc-Q>XRU`;b;d&l|j3!Fw$GIr>rV?KyofDGp${5^iZKf{FuOr zM)ew=PA031|0eKC&E*j|Qq~YZC)W|Cr111!6HHZszsTm~jjcetmgo)DhH7suBZFKj z*S34gi@n1g)d(UpW|HU)rF=dy4Af@_E|}q}NAJGrVc$)&1rBVw=YZQQWWWKvO47wRt3GC_DP^ z%pIg!+C0Z)C$SY{)H-@eAF#9S7vgvN)W4LPK&6Z_t;;U9PtJLFg5|xt=0n^a8pOQ) zpq&#O8&4WHZX92=yFdyr5u3yY*hA>t_)zY%)96|D6#8Whzkw))w^Yqk_7cytp8HUo zU3&|?84ly4LqKxFp~woikN?X{XnlZO<)!SK4{-XX5^`N-h%WmHXV%TOnRns?IHT+@ zv`g#(y`u(NVg?QneLOxKX9qR`lW?HeWr0POV+Z3Pu?)uK%4%%y4?spk)`m%&s`Bw* zsq&7-FAycqsdtEUo8{d@mV^(URM*FwsPsThQE#E}g=l6L7>Acxi_ME;T{A%le2DWr z=wG?6(S!ByuGDIk?1p$(4rv4hPULp648RWW&5*Rw%L!)Xxz!z#(%kq0u{PE)Sg%;RjLB!) zP;ciobaovwTRQr#V&Vz#ZQpEw{kF@8YZntccD%Z<#VgLs^HkHaK;Ge)#>9@6i) zh#nAMhc=(JTDNP@sB5r!UPx`?3l2%SK>Rdn22~0~C5mkj+pOM6$qV~ZmcgGzNfYXw zX=0xwlQ1!D;sxVNlW8^>29;Q>}KW94^s2G2g1>*lI_J zq=l1GK6uoWABv=DX*`KBe&jQ@%mpEbicdLG@U8@hhC4}_%qls`j_K{tIAL-*+UB$I zY2!(%e~isvMYDkfV8{A|Tav*vPG~I0**T=n5+&PfV}JkpRzzaWgI>i zCrUL}b;858lw?klWTD`-oFt=%c{y45iuiP3xy&hcCel}~UPlT-_&rsK`ZKa4{QmVS zW^AmfGC%f_EwLcD@WAoH>G3C`m5LnBq&QAEtl*xx(WWvtZRMvTujF`8 zy8H~9wMlcu!z|}AV8!?k=KX?Yd{M@2S*!Ea%%!CKYu9TtFAt3zsxyxp8ALhg~R98k6+> zM+(145;V+nLSky9dbwDdb7KqGzyyis&oYG^ueTjut6lRei?i7c-Rd0)6$ ze7+c7oli(6g{k)z!Jbg5q6kshnYJXNU;WRb@v>Zoy$`@byh_~aKf2@FRKU4)u#Dd( zTDiTjO<*=EP;M7ZRSSC^k3%-r9b&ay(zyA-0DdWwG4|eaQK*rgq}(aGL6{qGExU_W z?d&RZsySS#C-o~S9?gA(M>OG&ykNOIpXMs2CIsRi>V#j5jb^Py8*`6OyErvU^=XV! zxmV*dF~Zl)6&)I5qoT0 zaetD|>0bG$KlA3GQ<+Q~ zRC&oK=NcuOEcTeb@@L7qD)oC5>3LaXgB)a3>fw?3ir9O}3~?HP@4V`xGUS@Lj;v$M z9xShkXKoUXHm^MlQ8ekfi!sOS90gcuhfE@B>d?*NX5qEaQtq%7^_UBOwBS+da;+1|5rsy*ct zm`KX|Qhl2PM+)gSx6lV-Ty$Ioy(Ew4{#rh?>y`2P>9d6kuAIW|v`29Eq5VK_?hzLXF6X8_T_jKb*i=^~7p-W?h zlNGM7d`i3abegTE5#WYQjc=Vqc_E7MLpSPYVyjhK0b4Z@u_9SWtE&6T6n)|Iu1_I? zLx3SI{}7@wt8xX(SF><`Y1hMJs*K}BbLa?sC3;z0LKJW?&U@#UJr9+C`o9BX6Zj7@ z;rZ0#Qsio%PRzJ3`ERL~j=^bb?#q!aUkfI$LxRvl>OUeWHJSAA8=F-GXMF_AY56Zm zZS9nMkZma@r5Ws7=`tM`3kdNFfxOJp0eDhO+hBc!n`mp96-YgcQUZH_N|{ZX6=Hgj z5_Fmg|BuWMV?w;SBQDsgavP>)n#ARe*IKfh%4fpKqyuj##KdTNiDXS$dEQ8m+ETZl^8AyOONE$1uu!-J@`>H zmo)_DshAT3VZ|%i^P1ur1jPA_FJ4bsODMBvJJ_szw&~h{wM|moz$+Io5yGA8WgTgs ziQmz{TQBPhWNBhID(}6XJ*Vb1ks*m9-w4aCWqnES&yQB&hQ?0P$5Xh)tEX&edy!1r zGin7es%j&99$Il3B6spk8Y`MkQf-vTDh;;Z%jpkIQgdk(8i*Cv%2JfimT_X62ia(@ zsPRCxvoiz$pEOLe2+l*LNy?+E1zxcU7sv$hP2#EE<#CfDNuH0WQVg0ODP5%}N%=$s zsDy8VwruLkn=7ZkO!l97@FGTaPcIt_Tpz2P$N|by>gD!5AH4dgn$<9TRb-n;dSo@d z#zLA?lj+!0YL?MlEF-mKxaMpov}$G+`#Y>Dq34g zR(bJZImG{wci&2|Io1LEi<*yH3v3$zYCI^m5tuuU>o^^GQk;)vTmO;z8<#a>?U-&S znkKuc)M#KGZ7*_uY}Cd^-0o;vEPF1#ti8L=7?d5PcrykeEWLxnq%Py9cNEV;9(YAX z2;@#e8HH2FqSA}WroHSem^CGt9hB%Jr3O@+HI@F@=KISo0#%|a{SeGvva9_v1E^on zPnm2)l!%tv&3|Pn6a>*!m80bo&A{@;u_`L}5V$`UG@?A?Ww=V&Q#7R$)q5koWiOE0 z0+sTB`0c%IACvRL+mPgFr0gR$Zq68}Rzg1a^(l+SDnbUA)pDNhCzvXl`Y`??-ct7$ zOS@SQ4pfL(2Z-z&L)>f1Fx>1!I;sPZX+FsI#WAbq{p;p}YOvvOKFRIn}g5+_XrxHp5k+7ObyA&7A%XSX3u?+L4?tuN*Z?wHpQJm++pqwK z!
OF1Jy#O*<-rexQ|n;_YR@nuk=gOfdHtZgf&YB@~Gd14lDV&s&veMY>TLGmM| zE^tW9Fm?5`)(-h3Mk!y6MJ4we7No|crxBKH7RyvSW^@vgBpILB2h)P8;uZsap5bM> z*qQ0W5f9I z>Xm%Q=^TV@!{r!>8iGitV_3$qBDn&X8LQQHm*d28+p3>Ljz3j6SZ9WnY_9{=5(n%s?VhvI^0MR8pf=&jlU6fwinE6J^DUv-L^Fmw;FLbIvruU^3 zC>$2?xv!iinxnN&xrl@hIXnXD!vMj`loh6pWf&T8ufQZAL*!s~Me>@Ie zqms%wqN~MHKq&F-U>BV$xL>Sq1eJO@k9O_HDXPIn*`VPTalY`;)tTu4$H9MrollD2 zL0%+IAI)aHTqwF>ipb=ClC|C`DTV4bjD+=ajrdYQIW1#ot_7)mm6!TTDlgZG?U>FK9Y`@fjY5mZDkV&$udm!B@IvxZ zxSt2>%|2$Ql<6@XhVxCm+#=yNL8uskp{x8tsGckv6<@l@-YU3RfQ~Ze119t~!TEv# zRJy{dBKz(BV`2<%--yQ*tmY1|+EvxOz`4-!iQJdkaAMy~iOlMz_N~2FiQiK7f$oF- zdY9lM`H7@zFXdMPnN9{#$K>C4i)6*(%IH&m4OHt&nI480{LOWJkE9#L5kAy)Sh?5c zZPCQvq}*q7(U5aUVUMUdn%z!32f>uPX_kIKusdF?Wq|T=TL>n!GL5m$;xt=}b zKbFc7h;mBhVG$f;wFj6jMfIt#H`8Yx6tm)dYH$0Eq-#~Xp`~S@qqRIDRbF(+7T)C~ zKPq%=44qzU0}83-F~MD8HmuALH8vjianz&tCOgp@q`#Hu?Dz~W?c^A6~AeJo<^VSg69HTXfM$Sp66JQ~{CZf=oIGfXYqAYbucsWQ?3f}GYQqTvErqR+nvB-@zVr4qt{l9e?##3m`L*TqQiX?!03U{V-nU@!VmH-$Pvnjo!^!ge+B0Ul?Q6j-tvx=8GNgQtn2e#$+pj9z$InXJT~Ba!VBemd#Qy#zi;QX zY-3-=o{VZwDDQq|2da{Te<+&85xMF2s5$tHP-kvZMB$HYPK+@{R>2*;d<>%RpxXy! zBFrN4!~(D6)6TzXex`z24o%y;u9p*J8`W zibcOpj4W+0IU#{YN=;70Zv@w^_A2rw{r)Rd=~ftTcFngwY1=r_$zDFxrB;@Dww<7h z#`DQL-Cky;U3)Vtvd_G{%w}_&+^1d5GjBnHo82Dig+V-gg#OGS)jaw8Fd#pAPO0vR z`PbcOE-8>IBMK4yx-vaUomnm|Wg*+CdcduGvKBB>dL%Qd&a@@%kV*+o*$9VO zN@(ubXu3zT5|+0AoN3HMLm!!kdF(R6`z0G-zvJpk9$@m|2``h|l1jf6jpqDki7n@I zmyYK~(%6x*yp$(ap)#cZ94RYElj?wmiA`h6ic(+)@SLLZ!Q`@%zmVhR!wvbw53?&2Ymz+jFntNEbAa+5WT_Xu2FqBUc^b--QLu=($3PODEV zYuZfv6~91+1$eYxy%B+3j^^;LtSNQy#am)O` zKFWGxs|E){?5AJ|^)G;G_oXO91ximVhpO<;q_+gcjLKCfPW(8~eKMbEQF|B<3A%O|$jIH7%Flc4KE#}>&l z#*5}1j%vwXMw>vaYd?lLoQ6HrSjY)ti>EZowUwKlfqfJ0yJc)o2dBSG5?DAkF@AC8 zm}bvT7W^Q7*MN!YcQ+PIHP`=ka`~QU3iX`>Gp~eoZX%Kwzp#3e8=QT!Dd=boS<`!% z%Bx;B6Wu*8vRVdt%d)xsmydTOe2wFJ3yBWN3?H}<Q%v)3mZzq`fSy8zo zm-|863+@#AW(G0(<@>fX=A4vP%=8Wd4<$D>or3N~23hYYes?T;v=?Qk>=$+fBIA7F zva?tgvdH4fhJDloQwcaoQAC49b`eTO(#peO>AQ-gzNBlI%mTa7uHBzY1K;xCY`aU7 z6)dQMfG&iKNqp;?wq(vNL8EGdtF@{iJ#)Cvp&JBAr?Hmn0JMqCg4^UF#BM4rwkuJl%TNXC*$QnKpX+VDt+WZ`XQY~o z_0}7zq#p@SzQ+BiO|Hp&}CC$JJzYxbJ6bFY1ZXa`sdoeNvM`01m8pFe+r%r*b zE_i-$b~cjXxCrd^GL*EA63YElUk;0P#WUIZt;FP_>k~UVW-qK3nB}={0M@4G`GoBg zoy>H}(nTc&(Gh{uVrf)4^=62i5Niu*m?9R#<#3_Qu439RTr;_!93i-RY<|+@wQ=<3 z-271d@Eoz>?iuArwo|e}XO51#90^kUdAP_|bODSj(=NcUX?? z7?Go5aS%kpLOWJqt6($ZCN`Dhe8?B6(8wA*U;N1ET&0b7G%o%!0kt)Y%7ub&r?MJ( z6xre;5l-_lZmepdUo3{c$FJh-rqoHf1PF!@$iRT1W0y*_Wj>0lI!d9-q)G9?M4mA8 z%SDcjH#5mBN>^2ZSBPd}0Gte&B(JYm3Z~C6%61COm8(RajIGt&=E0}C#MOf7?4TEN z1WA=^1jofE;C+h;cBot{bU{pC{xUyto!EQH<(Rnk-zt>S1iQNphdiXU+k6~a>oGj8VCHoh z+%DlBIdQ%4M=DoHMKFp~+``b25h*Lx>%lzQn!9?-ozjfH7}5@BHd9U+TJgtnQE{YM zb+*0y%FbDSD9qnpk2}lVqU*%m!v-jarFx|NTC^$G@aSzu>U+d9DRfIWQ*$rv+VN?$ z`7XSM6nK)g#T4RQMuDyS1u`R+5;dvk9uS!?NO18)e0osex#}k~4@kG2D;yg*<4c*t59~U0r-J#b^b0%U_{ue|bdUn)uxBu4(P%QPE{XCfAbGY8xS^i{uTD%xn5hn2^fZFkS7+GxM&l22{9H>K| z>M(J?EV@*lVB;o~S8P@Vu-Og>5uP!x`l!mcEdzc?geSIR1_d>ZYb>wZ^U8S8*h!7$ z4V#lRpG+kk^dQ0L%qHiy1g|}@k7;hS~O)7xi5gm$Iri8WZ z=v|TT1szrABIO?<$9tf)j@&PG%$^n;U|YQ}d`EI}5?oRyvV36wrg$O&5$dNu6#4GJ zZY7&3HEHd*L)8)AI_}LMNtPLD`i4^wCx%wKT~gG+e+`4iUq#UDDLSRXfrH=^`~E!U zsYR7c`I}UPtB!#R=`uohK9wjHyLIl15s4C&0CydtT&5_b>Sj9ue(|P7w|C4o5`a2QoX6d4RaQ-qsK{=IrnH8+olWq>< zI{M0N(o}9$=p+$?%Ird!whZo!T;+j1hhWBy;ldL)x;cgR4&68BH+qj&BBWFb)yrJ| zE4}Pc$@a!&W(?S9keeH+w;SgiZsT)Hn?_bvAxuSid>+AtVt#SpBwjNvRP&0y7)wPR z1`0i&*_=xZnF|+(`6bDE_i}E$LQv#MMKJf=455VzL(*7K!n6Vo4=OH|g+$JZ)z2<5 zug=0E2gVeSpgkatolUj~VD0Wo4>m|93RK&FI2Pp}w5(N3qfkqg$S)g@hxxAI~cMtx<-R6{PCTsbKeD ze|A@`D7tr`qh}h6btTcpIJw$J>K(jIY{8Xq|6&ehP zDPo?8uoc=msmKo^`&nJ6FMc_ct}}1&fLTK{)7Kaa++BsIt_fT_B#$RDJ8<1vOTs<# z6}!!^f;>rf!L@}qkEv$eZ~<3UzK&p8V$kJ!ePcDPEBIb~4E|oNU2U+V^~9QEVe0aR zT2EkRyrdUThR8ev8;C9+s537w0^Lw_^O!BdgeY)f`;HujmJw9+y=AP>sxeb<9re@F zU~`kWHefk!q*YrkuO1nQKFaKr6;F_e_1WhCvEhH47so?AOc{=jR<)< zhL#^ncSS0{Wg&W7xwP1IWjARzh;0*k^LR4vF1U4k0Vg3TD9aw!-!#wZ4(`cj*;C}m zyw*Z&?LR zofw<#o8-!Ck+$#@mG9aQuy#dWdhB#vUCRDqqjR-1Q4p#DKfucQ@+RC(C(-$IA~{er zQ~S1}&%z*2AUQjYJrN$2gN5?IWu3Jn4TBlMyB4@MI@dY8PVk$pVwF7%igV2s+pOJ) z1A**xqe@+p9kXxn{M?X8@1$wQIKWltCNx+kONX>YUc3vZHe%k1ROUCV29{Tc^=^;3 z=_WcBH)f|u%9*h-;Q`|z+a;LdR>L=jgGjfHU7d2zIv}fyZ|adUz0AE?+OYvca3}ah z{K~-4^y#dWJ}YmLQyGFEZZwGw$~`ia0n9uqB|I{DM1o0$OHnyQ(v&CFy!&7Y#duI1_ zNB{ILF8OIvrL3w2>j@5nVTmruGgNJLnJz#URcqn-KYP$6>dxupga<6>rgm@OR~ zooF@jx%M>WaKZkVdGZmomLsgVcAhM7{>FkjQj&af5}SemTt1wR5==D!=MVinS|FVV zMn16|BerPVd?AlSCM{=oEU@u7=Ad(&#SIJuddhKvujf+IdyyO$BDi|`D*euDh=urL zaD=3OtpS#yJVE4{Ko}vH;fW&u3s4FzH^Wv>;J)YOPa%YHisuRVT>A z>g81F2D7sSks$b1PdQD(*>is&AHw_qk)3o)#qi>+r*4zu{|v#j=R!tXrVN)eMH4V$8je&#+Gv_)fP|w zt%^;iXy82Ir*pHhZSjY7vz;%xPM*Rjy4`K{@>4-xSsq_d|FC0nk%YglKBLn2{!A>rG-I2hrzk(S>T>yXLu%IBlz}f7OL@VZ!m;r!o%;UwqbRnnrr_l4BekHh8F z(ybnoD)YrpTqDUTIY3-rjV7Wyi5`whWd3fH>nwj1#Z`|EHRTy7;}?oX z$)RXem>Y%uFXx!s!l^)tS#GkSqhpFxF2bD3&fFZ$RT}S!V@8!*B)c@)BN(?vHMfc! z7(Ku=s9A2aoW`z`HkeRuw}lmROY*ws7w?cD^UNY;;npMr>YZYHCF?hFY`M!yaAlr6 z+J72Z`EIe7zU#`^@+<3n5j{o}gk)OfPq{}l{l7;~oHV-JYqj_C_eoUAEAKv$Q!BO& z0}Ee4zqZzXaTmXR>&-l&|dOz9Eb`HjeY$(qOg;0nx>*Zl-aIJQs zkZTO*S&1%-rU}KN!m9jEn&Er|we}40EDV|Iqf+jZlgdLtDGZm(W1>gK9JXQ}%c=0V z)frn^?KosZ20{OR?;jAt#H~O&Hyk9N5Nf17L$@LD%9FO2Q5|`z@O)~Nr-WK_qrrS@ zK=ZWqPR;mNy@(hb$3IAx&g$GtnqmG?)jN@P@p)yeKeXG|giZ9`vhw>VCS*v4XXP3KCg0_@zC7LVNbYF{oF8>i(JCNSa={Px- z?{$Lg7z@%1E^G;PRGSIBwqBmt8IPTSchY9mAf7-GFNS+qKGd_zDL3dMi zz}18NMN5QPZQz#ZwLgYdqRb}g1^GK-O}sH@7yD0QykmH2)XN-JP4S$OC_-Oc<`nFX zY3I&i`uaM{Tw=4w5*$TN%(*RY9fP88W@nj4V8PfhWL#+}^HLs(=EJ2!XAN3g<`aG_ z*M)2ZY?DEF=ePD=)hbn|#vc}tw6ZpeS1GgBRu+_Ur5Nh)!X%xnbbF>`ek{gj3rq2C z$RT+Cp*$FDrsjPS|B!4nvj`Kgs6g7bF-7ntWii|OHrX=vV-+=aap^L&H#QQ)ytBMn zjK##!qso$2!peJ2RtVNf_4I^YN}?m8qbRJDO)V{wyWNmX+%omDj940H;(etbxZefQ{zqsNw2E#DTMtsENcZptMGlDLW?Z(Nm zzSNr}n<}eWWQ0dayV1y}(NW_&`JNmt^=hdpC;hKa_Ax>*b#pL`NS72aHp|#(HN`?o zuHwZs&Q`yS9<-2}mfw#ncf9aQQ6Jk?ST{N_L97wX3K9?6jKgfAtrE`2pBikLmf$48 zX39s&AB@Ol11o6Vs!w>}`3~xF%4Qqh8rZAhjc$uLj51 z*H-qbj@-0^z{!0-=~Bv~Xq^GyU*wGFB<8`y#}fWkJXXE0JDdrXHpvqpQ$iF2o9RwA-=7> z$2gL8fn=EpriMPQ2Pr4eJ~1trfGY-~Pm={F#oF!BBpE9v*^zePL!!NUqm{+n0Z`j| zL_Ux3F7!*Cl2!62Bhg@lCmm07J6`GJRYY}5xP5+l3VC`&GX5K;mukCut$Jt<{&(Mu zn>BQ)C~o1g4C~)7l8R6ES@_uv2yGtC;|GTMQ8~oM#wMrK3KLFrJZY8>8p1C7?M;!x zqN}{WJZIqzICMbwiwkvtFy2EpG(EpD7IR;jBE@!jZsB-KdK+dAXt!!@xp1ZloRbHc z?kEWAhi&Qpyz}Wb9hfcxW9o6GUm<$HL#>x?-`tT3ha2TEu{^IBVh%9o<8ZObgjSm~ z1{$-9I3A7wu6>k;EHg|%nIlE2+^+bapc+3)gbP+C(nyE(adF4*-XTFXBsI1jA zv?oVYvm7gSeS8tZ1|rrEmg9tSXxcHagsnSXBt`A;d5G*N*Ty72G@YQWCs@W3z~4p$ z&B{1Y;)*(Q%}lDl%IP3X(0t z+jusdCU|i49G!UBiJvYsE^7L2<6F)UNz)bt#L7|56iJypF(a^Kzhyv^h=_{k2of2WZ#A>~W7(tGg|Ni+TU4Ja0F+<_J7+z3^o*4GJs})!!hJterCAMjsQ~QEn8i)baRz;rMlv zNE#B#ZKL$zk#n=)etEm}p{2cra;-Ht4FiB8ncL|*r!`h0Q*xfe6r6~W6`xlpdz5Gg& z*4W0{Z+4V>1SW+Dv#+h(YZaot`8Xu2t^r-qqzsq)q{<+#3I$l(zm{^r5eu}+kO(Qm z{oPH-rX zSEB9{-2PGPX6|5slq5eU6(i))kEN+8S|67z(~l0ss{Fmc`1nmGwY?+6@=plXV=}mA z8it5?QfR*T3Z%6?LH3l`9??9JmImp?(;}5R!y`|1?H|N`6~DmU-_{*f|0tNR6{QZ5 zS_WrX(AsLb3eYISaAQ~}a)2q zNSJi8Qix_0M4rm}C%!0>#?J=d2!-!UVz0z^=_$;a|7Vd+@`M{A8t}`MYxCyQhsUZO z5U&W`lkX9Xka<-y_pe%S{}?r1`0Qqe^EI(`0)y?5-$tA#Hcxy&?@)(%Qpy`bv&Kmk zvOokr@L+F>X3Q8LO~k(w$Yhfp;c@=9z(Ua!T5Y0;_Ljc@)pp7AxJw(DcLa!>v+5JN#q_CO!m># z1fh2M)N)s}IE9x`y?iE+myTX7N=XsZ2`(3-x$ zlPagRZ)^Ep7f`;e_02U+eVIvYF#2w`G#4;kO|VnOUfr!^-s3Ao12G8HHr&&V@L>QD(C|J_eB~L1fRZHM`h~@wzbXE-I$HxaY7v(znh_d+?+x zFnsAVL33IoUv+3gMCKCNBIddsOT~Jb+sdtZiDE?2Qsxnunvb6L;hxDYnD~WL_`Fu_ zi@i5f<*0;F8nCLM^ zFip;^B}DeAR?JxBah6XD3OEn7+e?Wgi#&S#=y7Ff%lk&>h|-r1C(DTaEhgV54%^Bn z<+7p|21=S^mLB=0Fpm?RH-B*g($M8CUz)pvct;#XrK}(}x>|yh%8C|yV|kF**HoHi zC84yDQ{$$I@5(~Q#Md_QwQDJ>2&@{_c+W&c@KuHWoS!G3Q!lHD^h9^+vXZM?{wRLB zw?3_`VX6QnjSUzQU3n3NjstBjH^FZD1WCrnHkEw)?y zbQP|EpB`i7X{oEOcTQtdjTM2Vos*3ck>fboddfH}?;7LQ&*`kW=Xjw{at5#&pwDH3 zP-dyZ!C3aFOca_g_G4)HM%))Bi7y>f9N(s;(FS6vsdEBd;y)1DG)}eusa`e|9vgkc zq)bK#+51L-wbOGTLNvitZY;KLj)Z1EVM4fx;5JE!1xM)1Hnqic=R}Ul*=z98%>>tp zPlT;#B{D(TTB!LHnMh2 z^=Y`ZV7@}(YPj&rHX`X$P1O*7YztKTJfGTFUpPG539X#(4=ts)x4c$0o$+%!*iO2~ zsmh1d+EJtyTQEFxA{t)V$(oHE6Gz1JyC!8u1H}`lrR;1u`-F>sD6n@C`ZShkFI+PB z;I20GLUM&&{2u(k4<$Mzi2AT5V8ibwvR(8c1h(lXu)9@x=X>U32(5uk*+a_XVh0oN z1xfs#0y$J2L?7bW`y-J%qcP7O!ohl8>}6vI<_D1tt)mPhK9ll+m^|O z@FEeXd0z=%k0#-?UF{|(*iSSw9Zkl(lMEA9y(&3({L2xhhCRpu(p8aOL%gN>#-UDW$c`CM8>QXAq5gr-d- zAO8kGMy6W_G1Y;L+)+PRU&S8@HUt%n9(`O2aChN)Y2|=YmPeWtiN;! zr1O)``ShSu=1#p5Nm5Taa^^W z;wx-ZIis5bnQx-M-K%I&Am9BYAut?(ySxl#MOUV_$Z&CG3Q+BVk!K&zvA(dPE>k5< zxl9+2b=sUJl2Y7ZWG!Xbng`{q_Y4oUcH&T6rb{$y9Fzup;_7x8_mxA%)7}U6gu@2? z!C_*Vs}-p#ZlMGeU`h@bUO2B!LwI;X906vuQ+aVNA!Im5ikz71U1@g{6Op5=naMf3 zh#$$~Ia*}h828qO^GhmNp=Dy$kQn!{FypOttZ-i5m|8ZLFpF1%Q!+BT>V&uSodwp8f6bhnNRqnjv^-cCK`9EsBav$u^m z#}s(4pNK6Gy9$ZkbY_)kNab7`c`kP{yrLT3^CZj!*4TYUChc;*Wc#NqL$Y!n}YuZ!s;oUU>0< zHFGi8p;Gf3fWPBFyv5k5H%fX`{5->pjRxoSO=6oxbtE9De011vFEmsp#yLUrV%o9w3p0G`f7hgt^w42IJ=bM!G9=?KOwk zW?;XSDzhy`Tx7#U0zV*}R<#(^_sIf1D3s=Oie0<;xEVqhN1y*E{`flMSdbY} zo{4%`+C5?+wi*15>W>J`nTuM7m{^^^6WlC57-chEc~syRS&@jogg-8i0huGsGfyME z9yr%h9+xl$#$>{xk52LL1=HL+1GeG9YVD^}4iL-#Nr648LFUsip0n2Z@tded!g2Iz zp}pcK;VGt15BBB{g1O^xYvswzb@4~BrJ^qRM*6zBGM^F3HxZ87iYEE4X9YKpQn4jkMN>_xr2FE%DxCngPcCH&$CVtLZ~K4VLl4~4djDK-zq-ze73 z${FG8AH}e%ReaAR9r;IIMSx%jl*E&gQ8s%%T zQ)7Mz_=;&+z5Jih6LH0HvbUCRC~G}57qc;vkBDvYtz@Z0X4;5-*H``{<#V|=LmceA z_PuWCeifhDgEK1qnn~osKwA5!Di->_$i{I1bq|?yb!LGv0icA%0Bsh5T8=SyQ!tma zid828XAy=V^)j1S@}}&0BR9lCnH|{U##@5hRW0=#Qs%3fu!!6wE~q)BTOr4cw{&lr zORBA+BdjJmKexb`*x^$;AHJ-wtMj1~$~=OZ$_S^}-ZHP{v@y{&gmuTJnNKh^+^7gS zQs);qA$aaSw4nXG{3G+^0^)1LZ*s!%+F4Lwz5uxL*sKcy)ILu;OU-Wa=jCm`uwd?ExKYJ&^j(tcNrkfR%2Od)0K7;%SyR- z^aXFqq4u(zKuX8SfMXhjvb<0RZ73+^`pXIekHzZXx=M4o6~T;o7|(fpn7PNxN@7o> zq<&b7j+L#Lk57)G*tx3+9gwTj(eEp(icE-(hE~+$XP~SmdU9-&p$19nSEpP%CPQs8 z5Q+xYkYvf~%5;Ic#MTr%K8K>MW5zWwk!uO%&c)i25no#%S9U8l!@e@hI$$G4d<}#G zJmku{(tVR{@r+YRwVq@Tr-4hPcpnLIy1umQM1NV3^)kwGe!5nB{rKyQw(h~ntPqJL zF1j&d1RnRSL4mLCAEP(x?ie4|-H8W6D4WI!J{+AvD`0BQGG1sz%`+J}M0nOs5PdAz zN=~#00WbeEQ8+cZO>9DVf5R+J65Kg2R8uHn$JHns0O|?pZl10vrKS8py6a<(xVtzJ z<38T-zqP%k22G_~HWIud`iZ-4?DCCmaMu(PaPx-$s#KfAXAk0Q6ynoOCEGBCDD*s^ zJ(~$WQgIqMD0d*MA%ld~E1kkHY5)$xErc>tk3n5I5w;XrBz~i=fxSY6t;Es_zh$b@ zm#qOtVx(#F9*>`Gq)KP!%8{0pwXI;r#UUskrXkx2Y#qad3520>wioHklO!y=cMw=L z?x`sqqsxvIYiA`}HhQ$_b9a(p&sa8uhi)k~%R5F3Ery^jI}7|X0Af(U?(AY4`{X+i zg35up>?%BOE-tnL=K@J0#BjOyd5W~7vhfag=iO{J<1aT2ZAj;Lm-@4cmo^sx*dCHC z7xNAcndF0U+*7n8m!d2pgYzSy6@pN0I1H=@!d{{)#|WAE81dKMA{)ly3W#!C|UoY?JAl`A&B_h6w^;B&^aoVgrSbI-_bN zA7CrB30)U6NknIk0Ly6?rsWenb3^3$WLk!%m&q1$!Qu$O%~0A!Zi6nO&hS`rc~Q0r?Csoy|T?7DV~ppyGzS-OxXmgpejRC zN}t7Ajw&((OxOf&j_l>9KxnamFmQ>{Iz%Y7^Mpn%-67O3f|msyA?4%U))dNH z(&rB2HwaSuV?x+47i>t{)hbf+FRk*XzKNHWXS*A&rsU+cw zm6w!Zp}fKjW;R@=TMOeLYcu9dTY^H;wE$SPrvZ8bxx3geBJD(mj~_4T~i$ z!+jGSA>7D|K=W$Ulj&b@q<_E~#fujPX{a~S;+3O>3EZu!mSEI_WtZ*8K_4TKp^l?I!lmvFV9B(-vC$jkZQnTECoT#VxWYoy?`2>+P zN5g4QqxTa*JT>Nqh)Y8I+pvQd8Z`Q2G zgmrM)M;wH+#h%TMB6)0-bF7PdzT=G09-*5Q$LAH-G6lh-qWN zFuRF|_GMPe{R#!CEXe#SRC!qtqy`r13XznkXaEMAf2ByiJKBa3zH<5h0;o2aot%u_ z8`)nadL}-ZOA1cuDoIw(&D0s(6O(_nAok_1Ky$_LCD&N79z#Rupuv7w-L`VA=mNp1 zbF^S*&%@fVE9XAV7GwPj!DKA@t>B_*I!0 zZkJ}QTzCU8Smh20j)`Nre@wa4KhKtfs7{+8asK`I_zpwo)XUuhl_JPhk66u0)w>EM zY~gWwk3@4tEgrEvh3^%3EYHo37PNr92++Er~kDrks(CG?EjHfHp~6e9uw8k zvxX1(Z-fqxQBmZ?J&iM}*rBnDxKTL+b)66?vL`J6EEg_J^$<(^ zNh>X$E52n4-ttcgoRITCJR;231U`uog0t8BobUgGVD8I0KQEj0N1+TzJFRC*XJ>gv zAQ^>$$N*KI6v_v*k^!Tq186BPh*dYLmoYA=AO@-MiPqLZ zMq1vwFG{syjGQw=e_j&#SIiCZB)BY1(^38`n#;@!rBPnCvFGwrcpV`O8Z56!^tEtIgOL2tT;Li>1H<%`9ip zCj#l4XXqM&-F_;PmO!Kh=EnOBpmxCQIav|h#Etn6$wtQtiFktKhxn(^KjH^*IPOG~ zjNhr)qA@d(LzY2H^QtfWLtE6x64xh2`BJDJi#Lzme+eueV=)ESGW<-n!Tz^s{xZs1 zWMzZpD7hc}|Wp>Lyj7EB2N*UKWsUZ2S;Uihi%71rrJu7QyUrS;(5GUgu`; zkRjs^m7>IjCCnoZy8#wYSwtk0rE%G7J+r8FFP?etMW_o~pl*~A#^6JPdNyQP%qly? zI)arTluJB37q=Q0n`{*>QX1-!qgB$hKVr#g)=MBbu{`;vbP{Bul%+&2k1vPSHfr?J zBGpa9xyn>6BeG~r-9+E(%UV7*>P#7);>KD|B%NPW0l_e|m*vGaja^v|mZ%oV-i3Q+8{Du`A# z4u|KlZm?xF$x;x)>rT-?v#c&5)-4{PU2sv%@EVex90Tkxrk_YzQ}kcanQB^kTe=v% zwZwOfAL?iz-7-ql+G4Y07{pk|C@>YqvY^-TPlxTjI6s%``MW=%P|G-a>q?S`wR{)X z=XxT^4Ybd=4{nr()))I}Y@XH@4fsY0%pXFIZ27weNBfsF2q8rWO6M^Ns6XnNao-@y ztikDJtYDgdPB7czILafIx>!*3kcYRUjF)Kf+-8#-k*s@y&?51%?G0RP+eukoeaXaZ z(y?`svQ#IDWW;2Ja-2@Mmx`sKr5{#)U^&y1zID{CWkZU!Z&OT()Eiq4IM$7_9k2Ar zeMKm+jfHX%VB;dQwu#7!F+>9c7!Z_A1=0dU%VGMnnMekX$E5;+8f9PA4h@ozp`K7V zZ6VdDN`8a{hc$-k+*^K2|MF%0#MlX=nX0V>W{E@ept7~Cot)ez?@a6) zgo_irC~puX`60NZ8#@X2XE%t`)sc}IYN9+uJ^BeQT6U&fslNzQ#jlX3RVX7>5g8lH zGp${A6@0p?)+j&BYWdD{B&oL>SZ((dB24G;SM_;!Vbt6PJ?G)Lhcyq$D?0KPI%Ina zZXPEPBi3JjWI1idS^Zk4D_h#jmQKj0E7}g$m=Dadx5S&pCWkYT{oF?+Efg_!AUBei z@xFpr$8W$Ax0L-XzZa{WjmR8zmi>iN6^-+1dopGR2(BF`1|s_2aJWL&CYq8Q&Q2aswzkhED$S5Mx6>ayaE+?sVAPd>}XCH8P)>2q!1D20v9 zQWtzaPebHju+9yU4dXiqxB^062ceWmgwUB2ydB8w+-_GqN4ikTbqH;dw+inkm{?|_ z)2eB|L?~5+oP(uHIudkLlg(+t5O)g_W71o&$x{cxb69luSU&@V7&-#?@4nJ2EfyCx zFmhv-J_(P>TU4RuP@13j3vV8zYSg%`+slC1J@JJIV)^~fa)?llHSYioOO)3X(Xlbs zz2q@%T1<&wTaU8GL4owg$T8qiH6)hj2=>&x*ro`iBM%RH9qfq=CpP{&)B7rhIb$=8 zKh!=?vB2uV)POQOFY!TFH_86+F8drZpeP36^vLwktz$*=1BmK~!jsC!iKU4jA4+B_e54$+u==N2k9do*wOFE|qdi@^{iDBhmK9ab5b2Gsk&_Pg>P&$Zf+gT}!%>Sy z-%mZu_K1t;?S#54ym!tPd$?li^%gqE%CE**!_%<4{KWE!QAVlPDCb(?i+m(u4_hzi z2~@Hr;}u1y$n&k0I#u5QWOtB?JUd=sli6?tROXtxK(gcj(2lcOFBF(uooq-lu^+t1 zny;jMuM;Kl&m>tc27tE}CvN$<$d6(GV2n6zFBZ5iNZ?PEKU^ZRZH^=tWUQS_#h!@C z^3}vTcST($nvtoIq_mdHDH{vgNvLD)jzFxlT#-Z$B-tz{yIijn%Fvq4!QuFUUkE)` z-Pv{an2*d~+8$E3d8lhb-G~5;K%!jbADa1x+>ag?^yq4vNo{xF*h$yRHG<1WuYA`; z=%Q=I)~x2;1k0gQZkFq8`NAA~#)Bv_9>>>9y>?72wrTz42Fu&W(6d5YW!-MH;!pC{ z^5JTD53H4Lk}_pTn&=|r!zlM=X~!mKOVn}QuCa;}ymG`SQuR+9fw$T~rhN1HE#+-O ztK>n+H_MXVE|jlkj=&Z+#2q3V1QE9fFE`vzg)*Q9=8s6PxNpl{f(OR@XZz)Dk^AFg zhe(1_er5TT+%tqkL~bXrc2w!XM3KFGugF`~?8PMmc%R^tK}HX-!zjNNSv&@Ps1F?& z*|g(1cfa_H@r#%l4VK?nelsR4LXyjm{}!yaZt^(<$E;)f%2z%hdgzF-R=o;8{Gi~8 zN!o(l9Er#{T4#vz8up3T3$KIFPJ}e!?lY1I8_t8b<-?-;<;m$nRB9*mX0B^|4v5IX zUi+OOs^tZ&oopd7lhtIwtUSset4K;|+rYkhOzej-Bb>kCeg3%6PBBD-nlm@c??o~u zTVDfq&SahC2|#5;c{TT-K4aRSlyX`$r&z0v%1;TU-vb_H2s?=?Cv-s6Wc$c<;)yDj zb_F>+n8g9r&Q3|O$s+xMXCzx9j|w((DbGsu!s5{wYa3S)M8nTXm1aR2EeztE`Mgky z1@)S(mlp(fiTNd26w*A)`G_+QA<({2(3w3Jr_t_@&1bA=>NAmhQQ_lhtkuYsBHOBsz)>+-rpd&cr)Z?tiw zB}4i~R(6>v#`9T%6`Zx-$d!jYCNG?~1YgSoA4w45|pzB1GJyTU2y;9AG3S0)*^RN>a3)egIrMJlD8s|B&B(DCOs|oT4hN{Y_|z7@r77`;oOy%C8$FuSWT}YQ`-k zMYH_fDjABfm7AaK^ocb1GW%fzazcaMeZDzAl`<7S#CB%7KNGkt`cC>KX8IojCq%`R z=3=zVkp5G6&fxy0Vv+Q@#e8{=pTO4q!t$4~r!g%=9IL_omw-wuWvfUEV5W|LNw-LR z99%L&Jj?l*AXU7Hc@Xw~WxbLrBo;()249P7pH<(FC0TDE0`hhBjZ~9z zgt_L8!v3vfJH-n$?<}_v=ihMokAKOGcPfE67HQ#oy@2`NQEiQ4c_xueNtq$kF#4eO z_l5r*-`0y}inTd2NbThOT;zTpy|W1InTx$SOxS=~t@T0-H>z#qyt4^xlbahhmN3Pg zWp=Rz^3hy|QH`=ETtmZU4*!y7FsSZj|K|j8TzmjdX)AMCyf9y&b<+0CZH4!udF+)5 zD2OO)9Dpd&?&s$n`L3KjF{0j&{Gz%I4U?E0(MTT3`-Uj ztt8KB<;s=3m|%*&aXQrud~uNnV-cdEQW=R%YY9LN1w6%D>Rm(&r0$Y}#On*bm7&Gp zu(vE_^>nT;}L0MF+YEhg)INCOSeN|sajqn9wg%w%&A%ZyBTDH2wutRk{( zzR=ox%c>M>%jcKtkQa)I)uh=jHsD}C!jsi4S21?{WL^@)hZEc{Zv~RQBYa#_q%Etd znq15B0Wsx-umV_HAoIcuGvy?00I02*TX71fDrZFvJ&~32huZK4Yn1gx zQkKT6pudc=nSFDny2x^m<$0rwmgrB__>*$4uZ$7-c_6sn`I;JQ#W(YA?c%*Qr3Jy9 zRIkUtx3-WC0(Iedp_OCJz?fk;Z;HAJ)+J7p%fojoV$k6-QSiD212i-}9T_Z>1V?Op zkW<7JzJYDdQJt0b@&k+Sg0tCBq!KG~aW>0F0x1Hu~?fpC&Wu-7qOHqA)H5k(=59Jjl}NcY~TzgMT2B%V(oja>?X~%$=fQ|B+vqV z+Fhz#JG?P)22j+phv1FzfpP8kmpw&Ri;+oQpM$&nNHFgi9%tsi-V4MOhfdq*F+|qf zTaq24C5(lQ6SDf>#4md&F_lMH%4%R|}7=n13B{+4%%In=)g$q0QY z2Z-J^@>65VftEMVLk`W!WMgt2B(_6r7Hlx5ss=b%C{wq zb3iN)Mi?zi1fnTz!t+Ky;90l~Lc3nK{zYk%%TvI!wISgqg#B{a!P^RY`%ISf`ARC) z*~5LU4P|K;CQ`7}YJBznU~_iZ%3^sH7*``!Zl~Z%LF)YwuZMc+68*Fqi!ozMx8)Jb zC6Ydr9)bH~AYhrJ-@QWVwjRnSZ9YAi`ou>9503~S5fT8`cFW~Me4!ZMW*Lw;-JmdF zOXK51#L{jQwpG>#=|K@(EDqbzW5$faEmdH}So~bpWzb?uRtaU(od&K$g3HEdb(xT9 zisfr#il=IW$o?)<#nuX}Plgo9ewhYlyZ{-Bu5KcAKr(lfhP%piOS49)t*abrX_**g z^7%G;)O?r21lzK2y(D3<_(Bvnm^8K=VX+=nI{Ug5i?SMz1gt%m7os_<7|3#zgkQy6 zp@8cqY_0a}M~j{u*DTjyt3gn>4Dme`pAcIGU6Go-V{P-XJVgj4K_~>Hz#k{wjF?Kq zh9L(!UMSbU>#68bH zZ4@&`Emmfe^C8q# zh}}dd#t;m4m+LL<6Ww7(IJnCVwsv_X(!sxz=q~j8M(L8xB*byKNurPQC&T83^N4e+ z+$?@uR@U~IP~D8*Emls;6ExT#vTbvPRD)Wt?_g4V5 z7gJf`jVg)02gWkEpI5mL@k6+zX5A5lQ}0iRbt4@liznA)}ye4sb zfCEObO<$f6XSvCCcfx>bonD@_l}x`j0b|*xq(NjRmqZktzVdYb-7{3BsA6VhZGwBp zcE?X9#_Nw(L`p6p0y)D9^TE%EE>R8Hq)FvjE7pRDwL^Oj^>c!09*Tj6+FmZG=dIb1 zyN{sDESHw@f`ru}NH%hvhY`C;h^p8HZW0U}v3gKhzbNg}F*>x#Y0Tc{Pngr?AN)W@ zdQ|zdjvM3NgY9cW6s_Pb?X2 zT8~^*WK#vK-Id2@TMKR*&GLbCo$)n@5|#OXD6(LTeM@tgU}l=cm%oW#RE^%~@#Q1S z2gF$MKEejbS^pT&2T_hOOYiSe^^J`A`0|P6jbpop2>_K^I2=B;-Y-*9)g2BXpNTAx zTM9t~5jqvm{=@2jjd=}IYPs2eiaiuRf!|!Sd~W%IIHd;qeVBYwmkYi1xR#Alf7+rj?`rs@W>9fGa)mGAWd4Ms;W zuPQT9G*EQhhAqPeTlu~eYsC+ek%!@!Szzv*fk~wOnZ-K1@$C|!U)h1PO0j-5fUKt3 zET>x}Qd|}yr)^)ET{JzmeKMO)aSov?qNOP~s`ivQ0Sxo(^mBGK%3J~{`R4(MNbvAk zp`e`GstZQPO#{Qem`7ykSWiS=fFW}T<`rBhE?X?J=CieV@~mrXX`nSk3^2bW`Meuw zK^oF53yAzU+Exz-&4MEH1cF47Z~$c?k!NC}dE3R$@j(lNn${;IPw^th+f>Tj{So?c zQOldU6v60AUa~4GQMz0klLBKLQ+t+lr$;d z;T1HMOi@dVtQbGphv#j0_bekeA!kwJqOz<&N~y7G<;q+x+wtti4HUV*eD(5xBdJ?d zg3P$OURIDW`8C3(v&&W#$Y4ttK%r~WT4g1{Gz7F0x<@Kd6HPr%2%=fbs|aNP_lRWJ zH{&W6)vBUt97r599)xf^tBIvqB_b7e!|DQQv4~eAENEFnWXYH(f@va^NAO7E1<{;y z=oDhFC9+LS9G?}Q)N2c+!2$x}-m;G6j9qVtIbKHVf|z*DeNCE!vYur$=`LT5nacWB z$p^ty)?W_cD8bB3!Ob>UMq5s=Cm!$YlraK}#?)|6Gk;?RuCG=V?>BgZaYDHec)S@@ zaJw=%>a>x>vRjjoJ{=hJPo%5F(-xdP;X2nz?&osMLkjn z@XrOgb=LD7>rf+Ewh_1_YN3|Ez|C@%oovKUZacADuTzaf$s}(tlnIiGVZLzX*a4_E zf3gbXX&Nj$N;7v1UWax&!(}H)O3DMV8cSBXmQBUmly|+nEFv|*3=J{4ACdVkmj4!G zJh{afoVyBSj6Rqw3?@m7AhdPRXvjHKb`w}T0PYny``raTjUj<~fftf9+e2{k=qAJK zWw@uvCi!Fi$}fH-ka7>?M1;*) z6Q&b12 z-I`%2k#w63wINMLn;|nTO?Q{cLTg4#>{3!F_LO!j?wcY#ISkJA4yoRYex(M?h21Im zb#OoV>Pv>Y%j!?(YY@j5rz8fuTk_QXIIc`Pr>@w_RTJJdhTJCDF@MS{Yp!#Z!veMX6ggNTaBDPCaP{PhlrgL7{;p^NT7&47oVlx4NFD{ zn}Fu+mJNZM)dX}qlrl}| z*TMG78o&w3M6h^<{X>PkJ4NTyWLPJ#mZJskj1Pyq zGZS7pM(D_@B5_7y9FG-D*DTI<_ys=kII)%(NOCA4{*?!Eo^{+?}lsn`fTL(`DI<-`9R;WW6@anZH-6QSLrUtxj-w^z;;o0JFa zz#syH^8`}ZRfg(XNSE`4rbI`3Q3bL#e=0I9`VdFK1(q{FwDHB_?aEkQD4g;wQ>ZRnp}k+CF#<@JhuF?Mf zLNIemBc1n1CdOB9`K9m|Rg0J;vRAGW+Bq8JjA5^pt3@&nSV*g3_O201XE)M>z)M~$ zaA<7v)cJ(-Ip@oD{vrLH;PB}m$x(&wiw?qMYK_dK-XPc>0}4n4M@&Id`w*$XT{KohK zYx(h(_yJga@> zZcv{>vKmdrP23H5u1fpW$U%wpF#ClaoPWrxJf7Fy1ow(nXD=#jCFA!ArN;s;F!G4M z7RjJoe354L<$fSzFbCrWmx>Xb2(MfhP!|)V{LOk9#1NZhWh-734~SkK-^>-Ky0knf zH22=~QI$!r7?QaCX84zxW03jFWF{jI{fETU;eDu2Bh6-cSm?;;5v(EahDQW)%1!F$ z#lYwNPITwkN39W1g)TiRHYvK!<3~pPF_F8XlSqhJL4)OSppjjJe66#4#%<;IlBLpp zfag_t!g88Yqfzj4H8pusG!v5c4srXIrv#pj-$QciAU`egP$CXqqx?anif4yNBQvV} zQSj5;W_*n9J*54l`P*>twa6j6P^<|G@9>6KF-Q}-fE-r1ZGJo`+Gs6 z^MVLw%jNkeiAc+A+cv~@FE2`UMl3Imx?%R%0O@sL;a~C(3&!~ObsJEN>6_ZnqC*m#Y;Gn z;IrQl8j}OW_2V`2rqH<9JCWL;9=Fk~x<>Na|EqsU3uZ;rgn$#sjBXKh3FC6=zi+dIBanAP z|4-I4IMfd$P2P`qGw9+W{7}M&QkoKiEP@FHU;HoyT}%S;11|! zo&#hgC=se{SlVWpQ>x?-x$_6TTX1U?%TLaDKt4j0>kg4YEl zN__5LH7E-K)=DK$WC@pr1@K9C?P8G~kJm-4d0w0~|MkJDmqmrsNYLm9tgc2`Of18i zho9wOeBa_W%J;ed;10TZU)ReLg41)aqipJR^qG_;ZDGwk0cbIz0MyG;q8G>1_aVtz z+Pc3<+4V?+7{H0%SZxZ#A%69;R!p0aibpzovSTxchoW&1B=8DGD;nK4WZEVw2B&LB5eCtMncT|hIh3TVjWn=56YJ_(( zuggsYHmn*$8_-fV6{)y#(o46L&1`7LTrkc40YlSlE_7L{@sM$~%QbCby%dvo`-Iq1 znkDo1v6{|%YAeCYOGfJoURfz4+uGVGE%|P?$~IDSz$ykb2wK@zs(DgeOXs()*>;lsKcJxL97{A?=ZZ&49kvUsYo=#09P18>7}`of2abfWN28x8lciB zne8|-Vla1>biFuth){)bN@_NC5&kxM1&>eJmrtyVbS~2G}RImb9@W_7Gnr2q#X^kbF;p9b;U&k)Zv^maxQ>O)-#W=C3b% z2``>MFyPpfy+!WH?}8J>8o--&AJH3AAJC8Ft-b6E!U-GVSkHm|q#&1>x2I_s8KV6q z$s`4FK6&^bAhvpp8aF=s!^8hT!HlXzyt8tUO<`u~*$a=^?*DSIG?f`mFVeFv-oPzl zse~UNX%brnGI|5&GdvUCP9XWBqmmz37uh6+xf{;czBhz&4NaOb0k1uZX@J1+vVC>0 ztP{rq`0N=8$d<$X)hRGwXQ!umRj+Lm3a&4Ow8xxkJy>v@(T(!M|DeDn= zDtp9*COh71txNN<5_6mx4*R4mF)-LF43Qjr7~@Mwv5a=K20O3|a6|_L$LDktWsg-D z77&M6|Ljid1$?usD#~Q@Q+n)wLV4lYns&E);vd+YBmaSk6eR zJq@yqo@u#CjDZH9C{%srESnn20~`DP&T_UyYsE)&p%u^|`<#Rv6#Q~YAoCL|RV)wF zK-@?^?Ods@iHg0$-HjdsE}SQnDi{ou^u9k|B&DDRAL7#gscn6p2NNN48RBw*(7bt9 zxw|kiDHmFC_Gq1BpKi63i?S^>fy5FjKeL#Y`3PYNCiioJD`MP8F~oIRE*8n?RlTTj zE}>YPFINCUQY;F|cq(>rb>bR`uUsawOHMX-x!%r-VlKC>wPHOJH{Ae)$|$c8oh6QS z=DS>JU8KGa9kD;!d&(~)I5q&44jtu}lDw8r+Zan$%~cXz6GuiDX4xDL!{ut}i20+Z z6NdvQbH3uPk#?K-%D4~v%C%B*Y53x+=nyx_U|lEe^q?Ig)(VQQ>qUlgSee64rsxK% zW7pwT^qqer)^Jk(J%0YbORiaN5}qU09O6`*Pp$oEvL4J+H(vd>NRo5zs~;}lR*6o} zXBZ};zAj3TC{<3`1M)0;&Be z`$1x$DTGD5TcWf>#_q2jr}OsmE6I3N2AjZplrXVuq(Ts7b)JJ?!5j%e9ru>cCGW-wdIetnCkQaoZK1IXC&J$w+gGt zJj)y`3P+xmcE0Erab3xE6D!xn@tl9j$R^l!88VU1J};O7hmf6ejJ_a{=8!GTu%-W# z$gU|H9f?M4S6>v*>1js1oWb&v&?<3?C@TFk#oFlHkun;3i!iS*OOy z({gK`j@V7`(0$9c4vgmUiR0DYUfz~y!&KP2MO_eok!;V{%h*Y@5mupv$gb~5N%(k8 zje3WJMN3BLUCFNxoOut6Cge;+niEfUk;l*!Zj1LsQi4eAaN}T=_l2&BZG{98i%dK9 zf#6axq}RwAu0I|k@LSLStAF&g;ZV~ zXCc!0Dx32_LDCQoZeI)K(*=nW+x!0nR*UA*d~31rjmQ!?Ztyc5Y?kt^*l*(()I-9= z%K9|Rf5b<{Mi-fDZy_Wh|OyCV|vL!y4;g+h4vfmRYz}EEp<=Nu3$AHcyI6 zyuQdd@4^ zszJsoVwub*km3dM9Fj?67~NlInO`_pn+D_ySj-&0?)U{QE*nip9P-ecEhLzZw!Ltm zSX|)$hX;R8SvVVu#|iwvPU`i!GXwDLGaf!v?7vF3VVT zt31HqSrKNIWu<&8FDn>SYQvN+Ctc<7$)+mHTV6FL2$2rKjLQll`6TM^=;igfqClF$ z6JCc%n#6xu2~7J;hlJoogVW`bSC;Us*wWZpx0O{a4@TRq{a7`(msPFyOxhDq95u15 zCdG>}ARCMxT~@bvZG1#T@yFR_4Qq@TUiKqgTvM7fizl%h!d`V6h^v zYYXia3(XwpMy2<$v5xTg=w+OF>stOnEO=B8#?Mg(znJMswUMT1g)mCw z-KYm^+tv|T$I58Yx$~w~w+AmLKQ;!qwsnU0=Cqfd;Z z*}}imaEupTF-Bdp$H3f|&ri>6YHuavGts@*7>9WfPHgW9B=C zA3lvB2%Cze0+wea4h>~9kt&-ab{U;zbAfr|x4K(kN8Cka3&BkTRMDm9Bi^ZkQ{s`1 zs9-BfiX0W%_!MJ*Z!J^_e$fLG{l8we5!)omxI~TgzOC)d9mCn%IgHO6AG4j<(=n}{ zscrp8_Hj!UO}{XC3qoRZG4CKa;_=C|5Gi9{*%7cdapdw>@3WI+PsAB-k?<|BS=gu7 z#8Vi=e&tDr^WM&42gL+T=CW;;T?7se0L3Eg#;yRhO{$lWGC$h}Gk5 z7!cG)sMX8vB1gxUB9z0+p9Q>!*du{4sjj@ivL{$={@mBtmbMMS6qX-Jm?}vYC){>R z*-N_a>;)Ip6z;&Xw-~ZN=b^Q0#+_J{?IUz>Lgv0>YW5XcJ6V6)LcULYIIxQ4#B0#- zmivoLitR`5Tgm~}nk`4w95Q|7Kq-1-RDEWcR?E3B2Z>*m3kI$V;U%MZuwcq58&LBF zw)brIqP@j%u^7@x^!qqMIOhne-B;R#KF_JcJQ7K)#`J`Sv-)#6Oj#W^upx2UqxWG| zSSCw^v1dp+c%Q(JmUd}o#F&#EMf1kt(jm5X^cY1|ozRj<+&ZniRDQ5AJBLe`WNGlo zna8`MTOb)26n89*(j&4+9H+fag27o#rBLQf(w4LIiKaO^M>!LxonJp-ZMpoQsl>YC zbRig=lqk=UOfhiT!MI2v4f|9)s9Lhzz%F0EIyiMJDRex zhxj}!5t0zS zJ?=TqVLq~_94YuzJ|SRW_-W>`9A)K=Vy#4Ph&WH?5p3kdkBdneGrF}LV{xfGV&Nt` z%dr9<#4pegZ%UTpabhj8B;X?mI^c91FW87Z!A(A`{Mhn`(eU{38EzQWRTjXDd!nIv9+8c#bS9c`XoBl@(yvxj%zKaSvoLE<6Fz= zmNt&k(3o-trP>$CrgZl|d>P8;>5?Uj-1KUgS(Am~}sX7egOgV_o zku0AV*vv_Wp_|yKxDHW>8`5mh`8rp)D~6nTU`CNwxB|`-UnssEO;0(WVr{OJO>y}q z$5$^u6`m;>OkV2wD>ROf7>w?6na!oG zXBeCXzi_$WZOOzix9DIstGGgR?Wj!%CN_CXxl-tySO*AQltukQ^TsPzi7pVU*6(VRs|Dtd89^Y_M)E%F`C7^~!WnsiD3cA+)Yi+jVrgJNwiEU4 z*MZd5&uhV?qCAAIm*~};G6VrPSghw662TM^tqI)_T#Nx(f9q0wNu zUvw~e5Pq^7>#E6omd8EG^jvN zdDNEHs@4xN9=LQKlO~6P%TONhafx=BB}NCg7-Js(UZUx_6X`*D!g7Y8z%7xK%CHg5 z@}%fmITY~A+H2IyQ-b^D0YHwa0ho>Qv{=P0hk*4D0JZCrpT;({rTkHfucHfiotSIz z8Ii?e-wYGBxe4#&LHMk2@&G+uoJ1%UTFP^R?YRnw*JZ@4=Yo$opZX6HP7G2~2Ec8nBm}5xGl$WiB zWs2KNyQuPtB=1F;^ex@xRSAx+d`fKNH3?Fy+Dov>^19`fViCe03}b?A3avLpQzpX$ zE=T!IvD6Leui~nCOX!lA4dW%nbFaJ&_+8XMWmjkwFl>`_nfRUW!bxD;COSDT3FT}! zy3V*-QO>*KsmJ5dHwCk;zuM}Pc~5*N)5o?=7_GB{2-bsEge-{nt)8aKXx_40ABbhz z%U*<}AsPEnEOSXCX5s`ce-l|Jnj^)%Vg|OsM}P(eQSQQB#@QSq=#QlxigTB(%R&5i zfy`~gsX~f84_-F@C*n&*^)OyRSIs5=spyNbYKg1RZt#@ynb=3UlBW_MPV66IJH$#u zQsuE-{t0A`4X-?&-33wiaQR%i4Cg{8Vdc^#`U~NeE7C!YBFK6wHX(mT={YaD@-N#& zBWRlgF#2J!_HRL?rHVJ%X-*M8&j^3zA6Cg8AjVFw!mkB)O^yM_3YHrwP{jtSi=6Ow z$d6!FzX7ehjS?3L=i6-3Whf~V zU%>%3%Iso!X$E1V%wgRZbMSZ|a6mJ`b4qqibPK!YdYQ}eLvf9c-C$gq+hWdt8{tu4 zFL6h;ojtN0OhR${=WLi)aPK_Ck!EFn&Pq? zWhr6ULO%sRpl(d|`pVKax^PS-tENGcmSsc+bHbG_*_&m>ew7Cuk^^HFvlf=K!4uN5 z3zo76%d4`y*sj&?B9i)`FNhVao&sV*4s&1g-7AXi6BF9bBW@*&xy?yFYgE-HgTJ!q z-PO`=>Erc^ox&=D8|G3Y7D>J#Ru#<9Bb-JinPdD{6I?0ApD2*XmRAR;EuNdq)jS!Z zH6+S7!^BW%mNhLOA0xsj^`S^#OXPwW5u=ucC&=1jr$r}1g~oy>H>zM7gc9t5w$~L% zH`4AwLg!9vDeDO>5EILIGm*`*zEEbaQx=a~XBj1QcXWbiZDtf6Ei!+6OS4a3xG@4L z?!$v_u#Bawsk6Kl@87U?9w$vIOa|SRjWS+j-+XWwA-} z<0eXfP$>Wzh-Ps4zohWVDtCf2IQ5Og6$9xR&*z|^&8+tK ze6nGj+{BmNwd+}?+T`&jkAZxr;*}L?_GC5e%bTMG# zRq5PIi-cqH?r-bI_<}K_Z-Q0HQ--%&(#yZQ%%Jo;;%&>CGva?ksggRC5M15$=v(* zbZa2B4ayjnC_mH`o+J8zdAt%!ZmZ10IOv})i(i6iv3o{h87@QO+Xv28jzNxJm?C~b zNSmIzrA(z%`$sM&7J@6Z%KJD?x;10gQKz@|PaDROR&3E+=V6u9DAR?OiRSt`%AuAr zfmgNj%V9!K<^j<|y47+xKy6g&>Z4^uQb$OXu8`;mP)@_yA1RhUR&}5pB~;0Jsmq?{|x+TP)464SGCtmwS4&+ur9sE7)*j}y-DhmE1gLXJS794~rt zo}{ctWF%~{9|P7_$jh9`;m7cwmGJVBkv4LOE3jEk6wlYUufI5iP7*sfmNbagUnh&~ z5k2MlB-2&M*iR8XAUG8h!Jld|bEW9T=`nJe&@Ryub|pAZmD5F5irFDPPY|6UG&Y9; zri>k6)iXsiNzZ?eOfp0W9~s2F7_>mqN%L&cl$1x0%Q*sF(KTH2%TFlQ_D+-TUV(E3 z7D%4flT%#|ub}g+c7C)Tr&gMAo-cZ1EbRZHbd#a}sef8MZ;{S$_-&L6#CFVs61!mD zzbsi2M+kQYX?_qdl#9f21&mB8ls^-FCmP7JQ(sMD*a_za>AAuRM0#?u;EDfbx16tX ziQwD`dfySVzo%R(xJs}VgAT!Emh17Yxf}?3LWWn->U6|z%2VbFpxVMS#R96J~t0?Kuw83L(~P_qnKPq|(!)deQC^-OGK)7&6DIfjSF z=TMJ{@5_yXllESa6VxE0Iq=b68oJ3p&L16#d`XVqaJgBu5i<&FO{Q#^jF)tTAalfS^A9WL0qqmJ`U5|EyMIa3D8vXFap8>4x85QCOng9f zU$K+#6wH8d;cQ0zyMStQR1vmRM5-GrcT2c`bQ@=7oO1G3{$6m8SodVNR-+m7`-F8LNUpyXT>(4o zNukw84EpkRMI2O~vW3xmFF>zDTL~}9rN-u=&eQ%andi6$RCfG9Y@7Icl8CdSR6Q`> zf3*D#s{>J?OonECM);iX$2gKnf%_#5{$TN*wWTLw(mk&+0F<^f*HB#3-g3`Nm2sQ# z79uHyL@&&goQfL6{OYi<{gbqhMBflT^~Wjcne?LgN-+zaeI59rvzp3Ff`82q;psdQ zNu&H(eCr@?A#*y^jPuKanRp9lT3^xS6`{pq88-=FZp7nPh4zZu3NKkd>NSzsW6vt4 z;_Is!dfh+d!Hp!cr-4iz@;8#)hvsD8kL-jug*J|TrOH3lm2ZiqsV*iL!*FCAN^c8p z9{ui(a3mgTe*qlvaAWi|LU~81lE$d&!Wd0wzIUyDZ|v2GK9Yv2e-*tkP*WU)l|A_? zL{Er5#aAhHecxtTU&^UQc;I^ZK+2V4kWIwEgY^HYIu9_*ilPlGNX|&kIftFuOwK{L zWRNJ_nR_SfMEcI`>?|NTNzSM!ARr<^FaRPdu%Lj7h+rUy2#5-TBA{UU-?!?_;{QB^ zr@yJw_nZ#Z)fIDhy)N}tsUdEg)Hc1mA>r<^kWrZCEr}KQXW_haVvJ&=HOreqS);ds zmrDw5&hlISAyepMBeVD%Ob6xsU&J$QjjPf={wj29Oq7QT%j#{Bj+jki(nguQ@;9NU zWA4IKZDF6_b?^9xS@HQCHE=an)4O7MrpOYgChewp4|Ku^h;4;C7kuLHf?c`HrDbci z%0GO5Jo=2ZXO%U4 z3MHJL_oR555*I?(<~hd;j!YDc|F3uzVpA>qR{2Pw!%S_QW$AD%6w3H)(vhGJ<v!1s5zUwoXdOswL2TinM3v4o+Df zV4`q1VOCuF$;l@+I~RW(fb*Bc3O;^f2xnMahRTYzd*cTzPKa4%C6QDa`>wEzR#{o> z$V#LjrG+P1h^4Fehd;;LWIEkd1y;`;GtLp&EUSs63m4W!LpxU&c`%qoEG$2aP+!sg zlTRYzh0;@K)6`I66kE&YxhcH0hVuFeLt9(8@}=k3JLF{2P1U?_Az$+yn@XQ$^fVQqYeFr!nc&{>lDaP;nxeef z+#VLJ6pi}D;iR;Mgqgm!yKA^?X)|kYVlEuzlu?Y{N_3a}WzDlyir=l1SRG2H*oycM z#EnV*A)^}cAL{NcZ30tFI3*BIw>wzK_cd?LYu4km%YU=yW}m@4;m zTw`{Sc8grdqo@brQacKzfgVK#EML3EPJ-9wuX_pkP|32he@Tmp+$Yq)yNHd2I1_pq z)E8vZh#-nxlU!-H1p`p$Rx!-o{L59bdeF{B%A5YOyWr1b&w4*=l|2N~R$Ylx?)g1M zQ{Sdd2ooRszU(EM#u5#`MBEm4+}^^A#0Yb9(|C~Txlf2+mRnXQbd_i<*L{Q+j8BIg zO?BQy_|<*=OIr+HB}$f>P^zxxzh2oddx$-xbO-yD+3YX8e6W`4Ad+(*AUYvkqc4hu zb)euEVr=Nv0`lyvg9HzX@4x~`g%{ZzH?V`jYky5Gde1mkNR%2ZfkT9ewvO8jay+W2 zv2v(=BpSjCfjokmo}h=eIruTH7KO zVgK(YUXIOv{#SZymE!~#o?!a2(YnY6F}PaUQq$5QnBsMvumC)TnXyj6)Eeskis%?o z;k*Pjviv%YxAWgY0hWk`30oH9f+~~G=n_juSTsVJ+li^8z&ZE|xgNZj=ONW2I%{I; zaoBY(dj*e=4Ti%qB4JbAU+Au8`KL@MfP0vUo%=+Nj%CVj#!FzK$mSU5 zc!n+`O*)526dj9{l*EEc@Adu;IR{=Ucz_msLJ^5b}V)TjRt=j)cd#B7^c`XLLQ<#{#c zv(MydGjRc#BWe0*4Z;=hx(IP#T=>P5E{MG-b8V-)q#qH!A}5Hg5MMvk!dr^faw1Ue zn#%ZO;;H^}l2my`!sCXVD&^B6%Z3c{KR?L{ak78N3sxtY0^BR72xT^ko}sP*%DA!8 z%Be}{Q9@i0zgtcNnJ6vKneFZ1bcs@>m2!gpoguhcurZcmr9P%$ZqmltG(^?LRyj-L z?HK$@&5oRWHel`Oyo%y511IHestVNS_(0~|r&5&;SuXK&MQ=#4id6jQMFnQZppmdS zSk-w#nXi)*G$P#27fR>EzWS_kfz2!)!xJnH_Witj2g-%wnX%KbX~y9qk*kx9p_Ca? zO1oGruT)W{fIH?TLTRAFOfhkDxKuQ=)(?zNfR_nw9xMSVb(G@umy2Woap%w&Z!=!5 z5K5&sj;Lg=94l7}EfgyV-98SMwyVgQ|FN}k>|E_%s>(aMyu~K|tl*jP_+Tdv)t|GS z0ni??6cqftNGesb0wiisp%r6g{lC+wd?9INcBtw}kLxP>qF}mfAwKcD1f5Y2O91bh(=!$t{gbL!p5&xEpTc)q|aP8oZ%iIbKbbMN$_t0yL+V?3uZY^ zA;WLm+&%~hW`nbp`$Tdz_mb_D2*UCmpkpK?ukz~y1Y)F#p7ZA{)hQv&(NBMarUR!b76DrXqcn z!ER-qV2TYWs;P#cPshW8>4ecoTupf-`%^8-jFcbP%=j{awKR!sTLb!kaTCz_BnbC!$X?<2ClV9r^QJ%A%VPxohFrbFwa7mg0}n2a14zZZKn zhJd|fh0WJQvS1hoB?l&Z`ww86(lR$liW?Z zS0Ul{l{f6^)_jRdWWY^QqMrvFBBwEDF|SeH6ud6qmVD`+q2(=~zBYM7i!|n}*S|=X z0;S$_)VCpL`CkQJh}Ru6J$QLrpz>TMYqI`Y>+FqGIqs+U74f`+YGKSMk12{uUvSD&zG|VH-q4FPT(gVa2 z01n!Jh0^JY>YDh?waQ0YJc!ps+~LTJjnom&nI8q;=j*}htd_cfWFO6|7nPQ}wF~fO z3kvU7*%45eD1ichO!)EK72GPv+?Na4VaDE2l&~PCEi96O4&*egf|(Z)ygWvr0k4jv zhr}I=E*ooyO~^^%ax>sp#sy+|fs8}$96G*y zJe%R?uQP0KS6M-5<>-X4QnRJ32r`lCj$h*by^=Ilox~>9-1^GOBB_@{N+GzoURDvx z0mbW(+eBGaWSI|dvaFuC5fEtXU+#q8pUmKuDrJT5TH2(0 zCAX0&ROG+yVi)IeJ|dT+DC13 zPm`E{T93`q_O>!zvNfVP+*L0#Y|ab5*EVUAE{@WZNG#BTZ_n$6nape!pH_LNn-b2cZ>n2vHFC6UaMQcJ%37 z7UsnurQuE@N5m`68nRCH&H~HEbTIB1SRT2)>>^e%f3`rclIX5t`^6f^DUOQ3WjB$` zE!aKOKe%N}Cih#zG3Eq^PJ8xkEUiht5SE+0S6 zo*?}3aQitw=Uu})pVBBtNL6L`9KbXj1%8f{@)vnH5!O!e=iog@Nqb1h67|73m8I)w z!QEn2RG-}{$B6Bpg!=E&ErmP;Gvf(jjYhI#K_>DoAfK899IcyVLorKM-qe@8E_79V z2|_FTy+a_qMD>uv6avrc6g(}~KRyrxoG=>48lsuS5y7}RikgB~#Ejy3g70eS68UZH zK3!MBgBhDw=@wr;)Mx)Q^fA6Y{wee5a)<4+@R`o@fSFTp06sK}X6;8gb?|4{YiQHC zt@KHljs!%~;23~(uBp9WJmc93!r-$81on*2aye?sL-RE#dP9tQ$ZtBF4~Z=lqs|pL zUEK+I;te*+^-Ki|5BB4w%SBI4J7eaH$ad9yu?URyD=oqG;_%ZeVhHoO23(fih<{15 zHr^?te0Q#oQSswr>ab1Y&Q4Vip?l-)8Kg>sUdBMpJMA{^%-nZ#ButwO8Y6BM;{sJm zK8!(tbMd8~E4q6;NcJl89h@MNY6Ik`!E&PQzsF)BewkGA zIdJesKs#A5)j|y_Lz}qv6rnFfM=cg&qns)*FFubd#5`0lr{!aQ2N_JQ7;-v@*;a-bg|Gsbk_{(($4wdO4*Oa?7Qn z^MYvd|g*x&*m-Ej`w^#fG4oA2=aK4bc?{mVr6IjBywX0D6ypMk- z1FrNzp*BG#rM|{LERc~w*)P;zu#3lX-4I~WEMFAZGhULK+v+{9^|@c<<)RNI7M$if zi4Kpk^1XYxB0+e)Xoi`kLSm?VNhob7YPpDYDmMsaSgn4wd^F&Vg0tgSvFf<*ZxYF9 zKSNpcM??PkvS`+rhqtJ?x*4RlX^JAUN0Qv=Y>k_tf7q-N97a3%d0z1r!AUtd!@Y5j zVZqSxSM4~1nKDGqm36CN#u~XC8$)yG;x@s&8RELq)PJy5ZWl~d9SRnXmOBJe>of>6 z;)}i}vP!H#j_SzOeP=?Ub;3de!!w)0U80qx!%)FF9<8*jio|Ccz*9bfZA#)hSeL<&v&FbCiVwGJRD&#;QPfs8Ek=7YM3(n>bruON(!4a z@AN%^qoenM(FXBG-v_X`l>CK2Mn3rgN$!o#@t5i6o5#z8VvC2gQ5o!GK3nA>|B!|* zzAx|6WuASG=9<9y7?F&t;=@wzAKe-ffe%8xJR;%V>Ai>^m6V+G|MUaNzZ84XON^Uc z(d381)8YVPj7dr}|A9yS%e*+P&4`6sY;LHKAM-cJHRlJil32@+i!je3I%kiUANlMy z@p%zCi3T>;>yQ0IR_%z`FL^>KKd}RrxB3W53S$-KTb>X+G9^=L(z>vJ>eFk*{_RAb zj$=EE5izJhKz$YJT)((M(s%LaLWn zXxF}$A2o*=gzvnXo%vc(S{s4t_d-X;<|ISBx2)Gh=ETGk9!TscOz96|8|Kj)24Q_B z${$73fW)P3r~wn^#Qc-!<*}+moj`gM?*y+4XYzQ1s!14B-Vo{tN-UV3=waRbv+%|- z3fO5z#wa-drcfm%#TEH205eT`{Um+4n=Rs9{vu&cHu)1%uCA{WOX&zL!*ZEAU2 zV8PH5^q2BCTZhD-bt)|79RQhy3m@+WkfE{iuHeHNUlpdlF(g79{e;nBD)dB-?7!RF zaEvDBR-Keu{}B09P+%5nmiKLEd0lknFdhppl@CPIE;JU_O;*Q0#b)MW?!-M`#cBDM zV1IxHVrX;6w@+~E7%=j^M2G(oIxQgmbvYc%e}z5>Xn=Agy|^}iWCSQHA$C)e-8{fV zFaugr#{r<6xtANFn5Eo1K7;h5&9b2F8>;^CgvX=wV?tGV68JKEXd#hwC&P6Cxn*I2 z&qdD!VC2s&0#^G??iKZo`fe^NMi`hIEs|{@b_|roM9)nfq2aLzZJhdLabZFQUDdJh zQEDwAMyR+L&i*)8*UOS%SgP&QaOy@}la>;EKBk}V$9;ckft;@viJZzZwo^=i4eIW@ ztjOgt$Lzj3tY|rrOkql`b}V-0nOk0P!yq$ylmq7DA}N%%*zHWo3L;sYr;u)n(^9c( zMbO$iDOt#>F~50B8ZRsPha+-kFhDgL_>z>B?c>Dw0wlb-sPhB{|96nFBV@m#%JNfN|Y+e1jRp{>&%-BVo}-LhY!o8SLa^KM%Y5=wY(6_ z(d95Mnp=u)o2NOV0v>|QKI>#F@uOnpkjKFr*w!M;$I>;#nPmq!N$~s%wDy&q!sQgXVwz+- zNWAwOi9m-p|yl>!Z4c?|V!tLz9+J1KVzt1P|3c9JSp z$pd78+F6<%@=`()Tub}xB2-;wJ4P{X>?%OAQ+c8{GuA|->}Ee1{YN?*uA;k3wP;?8 zFa@JZC->hTQoWq)f-z(@>?x8dT=-lBTfw~qvjTbH94>p?J}OoblN1H-J|T2;u9rG@ zr$Iy)FN6Dt=U`zVX^fP81y+uitX! z7T>_u;f%xqpizzlHDilEiN>M}FQisEO45vtY()G^xZ@rz`n%{AA8OuBRopQ?zf%fR zq&`re^eO2!ju9Ydg}Eb+6}c+r43U(K6{Q>}ltKNaX{eW5pRR6Ao`L2@`)KKqY&<>< z_5+*hlxU5VER5DD4S`ki;s)=T?Nd#k>WDYh5QYGRhNVj|^Itc0VPwyB3!NBmirU+X zSv?{r1%ind!!2hY{WCzGnB$&AOu#Iu(%-b9XsBam=@ZOLE5`$=MY-gae!(~6{RirZ z8)d-m_Q~-k!;CfkD8?&QmPJ>`&+($8{E%p7RvB)Mqli)K0mB)#i*s_7;F@E~@n$(* z;>+WQW=?8vn^cNGM|_FCgzTr5$mX$45Q`Bht7;%4;u&kwoYToQkWYl$jtV~ztE`8s zXPHgAc2BiYi14A>loYAQpd`8~g*hVY#A(1J!?eh5gHdYSM_)=)AKWHR&beZUh^or4 zJGD@-oglPXx^dvrqBB1$^hEnyA-)W2GS{V(1kzY-HG8h}#1e}=9*bKwjm5wCgp=(M zcR=S3{eI*-IYkU9P5~L=95(|jLCoo?_VB}4Gbk6?%l`Ihf_VkxrHOVA+30l9Z7Mdx z4=HV&A@;fWr2(|fe0e!jD3cRYhLt%uOCSqHU_xTWm$OA~jCTnQ3}y4Yxt}9EE53#| zFGO=r+E{-ckxk5N&bj{yuEPY?O z60r7zJXo7^Tw|4%;wt}u)F_7==**1V{Jda)bVrrBkysJeh~>3DqPZQ#@&&Oyh2d`DWB%B;3MXwtGYMqt-jVm@BmwBR#8>PG? zI&Em2aD;D?c+<*ZmeYwWJaCvVi{74Hz?(gWoam8qvt3MzwyYVwWp zty=_BFE_hMDi}0>BI%*Y)sD0n5rNcMZWW&qk7FGe>2*nz+XTNKQ$x))x9064$0g%J z1|tf(5eAn#zDoFL_;MMBTRula|uy3MQya*kfCF1__U8(QMU@i+ZqAV0CxiXMvx$J5~ z{Ju}V8^0dDiD3qOK=7N@G~lisU%{S!P<&c&H;#cSCl+c$;VWVhVZCdWdA4tg31_X7 zd%ip@vQvC{WPoC{SO$-X9yKxB$bNjO_z$u__qVxKNU+ymekk^IOr>`)$LLX^%%4rh zF1BuY3}nJ_k5gRVT7-nm=KOYXztiBDX}g?N0^sVcy2#=TC~<7axt#r9H`O!O!gSx2Yv%5Pc&ybm-Hc z@_|3ZH+r>jD1I)KM@~-@TV8ouAoE%10l=Zm;5;LkvKMPQ%FF*k=;y&3ILbL57_eW8 zosc}zpy^immB>+tFCWX*^DAsYaG~(~__cq{O23R5H{@ppUXPQT7QPzK0n|>)8-;mB zStHL&lg>J0gw62{FNl1qn*1!B&QJeF^edI|k=i@t{BRhcf6>1z8N*N=+~v1IS$t97 zUvs9obzTCt-jkv}rQ;FLekbAE0id~!?UWtoLdHoY z%MkrZ%1vUk;15SZ5s98iBBUSOdl;NIB+4Wn69+b%@Xw<6M0a=%l28vD-J4=>$ECNk zv#Y#iGn0!2t1?kk`HSF|@tn%^5QP3JR#}wj2iIxV@Y{g3>+_yKRvzN9qUihIge$g) zM<}6dLza{6*ScN9%bbp zB19`H#Z@O%?+BiN@7vqtAXIVOUp^4nEP(cQ{c8RxkZXfWfC~61*JSH}k0(eIj?Os&$hrv-X9J5Qzx6Pm}CjLSUZt@z20{MJ#;hj_dBOXpB zlz&*lKdc+QM`&Q8ONwp~Tb8gjP9JI}CFfeozbqSH#~v$7+q^&eoygI}GQcLgjDJ`? z-op?x&6~c*ve~g*mc_w$%ifn0Oh4RNqjUHeb4PWT<%KuT!v$SGqw#T&+7h`A9e-Wi zczy*5GZXv7^Pnq=o}SEz?T1)srz?q`mK>cOLdXv{)0G9YI_hwfn9;I|z}>O3dk8`8 zhhwcOG&csEEs(+L9;>T?*QPBHUy8&ZiCN_St4sgmWbr7?jayzLdkupo<`RNr$OBr| zw1Z0RuZA%~S&$djlKQ3i{E^W)_)L_wMe=gc8fT$%Sa+6n1Rsp$H)-mmNo8HznNdM? zCpsIH&+7qd`3g-*?925fyD%P$#Pu84-Z9z~vmGiM`UH0^%>ZR+)==3uvYF@;F>Y|aPUPGWiZ{2D{qrD3 zVhg)?t85{0p6qZL?Dn3JTMDM*8OMiS=O`M*vR*X;0hu#gH(T51LD^@A1@85KDU&2U zyjlt*M8M;%S=t0Mhj~8F5Vwn^6i^>DdyY|9lLf2zN3QqQrJo{{iT=aE2HAD0&~8<7 zJ?>pN4RP8`3p9Qi?JtYatc%kHub9~U0~ts&Lomahh9e}26*p7t#9%^Z?BTsT%Qj-S z1r|Zee#*9BwQExSA)zC&opc$QjN%4H&@9_awnut54h~H&J4mu|ER}kHXaD4~qd;!Y z%+{2FOgjl@2(Y!z5n@_pXZu<*R}IN9W|mzf+BytVBW-0@TSo`;m`Q2%-E3wSVR$aW zELXJM?ctGp>3RqItb^!Z>F$kAnzPHEww{P_3ie6X`&QY@$2LhJ4;DUvx@K?bGO`cG z==+f`QEZJ^#8M&g?<11M<5Zk#wO?1SI{Epp1S+SM9gL+$JK`p7zQcDTT_2ZWEqEb%R4!Xhcx z9Jg(s{ZNg>GqUOjv|rNqVuRQF`#7ap%>!cpP7azs*gwv<3<_`ezc6Yjk{{adwV8!! z(xmn>EZLlx6Vp+{oBX=tMbinmN|6Yo726;VdDHP=QY4wXe5~akCK3ZTy?Ty_bmghX zVlfT(sL)YykhD$afSOI)9JG2<;|f^D{QIY(*@p+k9Gi>AhnkOS(9E;rK0?+*PfiXr z)PC{vb0s}71}bOL%vvW1PNX43Xk+Y76zYlriD)viWvOaDNjP)8Ol+6(X|Z+U{nZ$o zL-%B%jRNA{!huAIVWCs=Y}EDURNA$vsU$VElPl*mX|jk_>;YsAU+?tn&5J_!&?x3! zx;sNG^;g6yjH9w6a91on^tEQ;3X;d;S>pS|ND#Q9waNu{wrDCuumm_{=ZIuIANW?M z(78ahxp{F7`DLhlMyf?(cc9ntwa*jzW{g!NahQ$wDT2oNK1&{a`Cd?#3q%%9p98Xz zU1)Q1ZlFlJU`{f=?IQbIHHM1)JW?)}jt!~e=fji~$V-<7=iluw8u?sP?f`M)&oiNydEkIWaP2`;&vZK*7O2FNV*JikpaBoe0E6 z=WvbPCZ9KJ8zO^W^aatg;*H??ICo&+Y?UvHw#6Pm{5H0}QLYtBKk39YwqGZ>aS+05 zvpm!FV(H?Z?^?bDQrjahdk9K(qKVwSHwbT^O5sqD5dfQSb)#Kmo_#(;M+g)ju-Kc# zlR1nqpv=p7`LexyDxGAzjOn~tqP23jF)##uh0FL?gflh~6Bfe%EdrTvf@>QE$YVgh zYIj|^)k$7x*$0o)TP4m!vKZlHe)*=iiKidiFd6AWC0%Z}kCiJ|KgC6a$a0629Wh-| zo6Dl$ z^7KvH>3Gi?Cih0jx8D+7DwYW6F`wewhF67Ut-AKAnz{6rP~_hXvM-Y2`^YRpaFm zp%lHyf+bV?fk@^pGU(Ew!X;6#3Ma-Pu{>&fuh@#Lx=I2lkBN>X%b1WBTIF%k_Fz_X zNnL1bO0^4>yI{6I2D1!LrQmkA>@Dc3ENqS>WTaDJ+wI#gFOQ0#i5Y@ zJSn(yaHy{OQ2Ck7Nzt4%X=-`OW-DIt!xdG2F1k|A1$Ly!zVNhIX4AmLS)Q?(cR=IU$ormD}tqzm#HLEW7aQ!U@~=`IYcS@si=>jgt%YR0KB((4=)~k9t;cpA-~l zmFH~D$~}nl4~J=aUTFR5Cm%j_u)H9Ubz0{3%)4%|{6-)dNAG}f3Y|bM73>y+j zS$->ceT<0))0b%0`qEa*`s@!^t=~!W={W8BhQ|E$mqnJ0cOJI7NypGwe|beP5B$FR z@HltS@~Y5gF=_47Vbs5;T{|%k{7!@?MW5HC$?I^7+$H_x4-!39-8#wbh?L1%{G()B zMpu1g7b$Ys+fZWuxP*A-o zn2OxCnQidCw*(fCaUsg5{KaNo?xs%n?|&7@4>2%Q0rYL5Q*$|UZ89-d`P+xxV3aTK z*i5I+9z5k=ZogjWvp=2nNTG3Z#1#r&Ead3joz_ z&9}mxY}jJtWx=FV($%j2F=-CSINLUg)-7b42(kzU8zuB9q-q6@g?%vXP@&RPp|pt9 zXXaIA7~?lAY*C@BbIiN&YgGr_DvOC8mXZlU@p=rG#l_xCN}NBrKIovc1Sls|74l+y z+LF>;o2S8at;I~0E>_x-~!4<)3m*y!!`D2_nFrcj@ z;n!j*67GZ??~AM~I2KPwHfK%UtN8RI`Se82*|MsH^XvR@81;v^w3=|{wd9V@t&`_h z7yDlHNyh8UDzJuF)ggiPKxbFm@@CUi4QNI`;CX;tuf}CN}9RS zjPUm9&4ezCz12Qra@pMG2RWyRAyHyu3p-maZ3g`o)F@ku{4wW=@KuaYz+FN^iL0Kdk?`( zEr$3`J-D)`$eS^6+VM3_aYmr{6W=pFm0HKFioFHWp~W~NCa!z}$UGz-O%z!{kK>T< zBjL(1z@*=2$zq8myPvf1WUqDn&@98{Yf@IL7$KTrF8c{>5?O@SdQmN`kVmm}^=lB(~ zHN_!ts92`eAQ5$yLUIFs4gV=@5K7&(#kX zi@q?O{Dn(kN(Ir2J|_*)ws>W&E4U}-dd}VxL2!Yk>rCYSp(NhQ+ z9@Z*7VkMRqp9n54WfEO(jhnR6j2;ept7cwV6R85h_(UXnG$4I84l*=1;|5HHaP z3gi_LQzUcHSxywnR5j#2KyE%spcy^uQ`jt@2B`fo`2Z}a*A)0Ciw)+O;GKug6n~~u zeDcWTk<(DCo@)D&7!D6YtshldIa~OV@Jxy~z=^O5MBtfo{NpMyV(G=lh@C68VrUDnD-xm0 z99Aaq&-kZplf7cF>@VjDtQ?=)QRkj}zU|I z(@AE=i^L`daN6{8vF&T)C-tMCbh5x<@e`y&=!XIGKaDY$@`u`3YFO%xS^luDJeNs- zar}s$wVA8r@RqTA=O1V;t*gWvxqHS{v@%TP zYQYKiHatpvWOV&m;i*BJ>UFpI=L9DOr?JX7FZ+3s;aDylOWnOFfUgnSFWx`HS(&yk zh@}NVpCf}L<5#{YzHNR0GZ!{A4#8`MPmf*^CHnQEyH4ni;9aaqo{pRR^`go8hMJ?Z z;ZR=^nH4?4AL@t(9w_Ao;MyY#*EjEa-^xxxJfK8NI3i;r<3bX zD6Osa{t<7D@ROSbbL{F-S;=6h{_+*!H0;( z7g0eH^drwkTSsh>^DKw6~&pSc+cWw z+P)>cNy=#Yv%^X6_Sx0rw<&&FMjJX=^4s@_XI*tt<72qF*Jp1_UH=%&fd%kwY4%GE z3D)!bq*%RD_ONVmJCqL}aZ zDcW$xW_f^i?SdR*bkT9ZKPXMEID#{cMR-UgL%+$}hu3nw%=1B&Dt-9%JaejXomvWqD~ufOG}@K#06Cp^X?E?jI#U36-DEKb7YP*S%JGRN%4v8B>p> z?DUvu>fk&v_0sPyj|(muq+F!Rcn684DXI)wo03y!U`8ieK7Q!O5@$w7^ko1)5%^my z1T88YUcKcBu{2o5g*4Q#KefZ<@+c>RzX=YIexDS*BejITJLQYzXFi%ywk=YQ43(z@ za=LwAat;1mB+VGCDDu7xm8XTW*v|+$8^kCMoo56y=SJJ)nUl*eY;O_!94^W5lKmsT z>6iW?%a^oGp4?V`WqaS)8rUQCN-Dn=S}M=Nwwcq*v$iv1TgUiZKU$Xe9BA#xeAzIN z5^pTwLD5%pHt8~Y$IA;sOJ-k_r_Lz9v7LG{tKBF;z9_Uo%5Apm<+mbf(i>zD$nsb( zFNsyT!wJKHcY3M*ooH63vY3fgc~slJES%Ouq6HthmfT6Nb;6Ne6}&T6 zQaEIl-wWh7Y2`#m_?k#6R|ZUiPQ)=t?YPtlM;;9C32M6jC~4M!9mEHKVj}|SkYp$Y zk;Ve;F&cw)9F*R$odJa8FNxd6pMh#imS>Atv=CMQYJXVtLIN}s5qVt7+Y+u9yI}qow94N^X9i`Xj(-ek!OA;gUx^K9 z__=OBlu)+Mg)=t`?!jod>*YNOAB>@FP*=XU{9WL=_*TYtZuy4~eLP=8?Rq3kd|#ry z;wL%IOq@W(vDh!;Yl)Ew*Rp>K-5q^#<)Ma%eKjUzOA9ZkP;r0%Tgvx>wW{jY2TDiS z@}GDjl@aKSVNU-Qc{FvHlTFvA4|-bk)bWIs8+ z7W9$x(-AeT628XAL|dtl?WuA_FXXeC{L?J6X5m^`D0y{89aB2QC;yXHFY}b6t{Ewd zN|%Ce3+Z6IEGBSaoC4D)Q8C1aZmaHpZuD46OGuPeS=bsFLpW)d6k8&`h)X}${H1(! z-<%e`@QcN4mzHYvn055xEJD9&8NprS+gZ&@*UO5G1%e{a3-xj$7v0h=B z4u-05xNMV8ht0YRi~Y8?PmYhlA*2r`yB&y5crqXJ8IPCkMLv=jB~}@U94Tmz5>Oat zHv8%ZD?8fPdeK*C5AN-?IEy5Zu>D4KcM{cp>>0#0T(NK*-pK=DaXs+w)0+Q z&^X2ehT#)}X?oJ&U-qG0`&{;GMj%%CzC!!v^?}V1T&Lz^Im!6dp|WEU?I#_6$Eg$y zu%?L$czCGfIECy%JDuXmv zCB5I7kt4+44xI2kRNbbmLM%U0yq+%<79$+}?E2N*Csum4uFBCLl8su-f!%bBWEB5# zO8GR>1xmAc>;iZv8I3wR%CU(#D4u>~V|V`^=c9L3@yqz|d;LUms!QA-V}-$@bV#*K zatSW}T!Y|tozfgwy)Ty_UZf$kSqwa%<$XbQU(=^?xOO(tp+ZT7vDm`Z;xO!T%hK(` z83Q&`OJpY>)+dTTwcm^8Jo4Q#`2F^` zN}x!ghJU%<1|(i|fmC_0w&Eqj2sJ4Ex_MlUvo|a>%JBwR<#y&)=$>hmVfz@)uY@@o zZCQ>NTRhp3r*53ZMQ~;{92{1fE?Q#8Ru)b=^I#eQt32nqjdC~e{xd4LcDzq(bcADp zDspAEPh&)s0kO-5`pcMPDd3KcyT;~7!aQqwBs+}u>~W!Et4TFEfLZkB`ruG3P8P9? z)z&xEHn8`6hgg`=y z={^%&YpM&v)e49zmZ9*Wda-|atGWYcIUMi6=h(-}ndr?l9+d&FQO=eA zkXT`ESx+F|?=zwg#D?O|TF&!ncC41_1|M|3f8ITnJ?fsTsD|-!fq%F<*FW0%a-r>Y zgOH06!9^2_!;AdG+wn;_>Yyp5jIq#}u~x`cPwX$lS}qY>J|;MJvhU|uU78(-T>_P& z{*TRa8K62KkJEu6?9-G>D3?q5N_=2_E)D@9t&}T7GdcdOCV^Y6a-|Os<-SBBV}YsL zyGpw8`0#1dXO^pNrb|o*Yq@;Zb_P`OeM$42yT*Q(&T+VFE}sWEW)c@R@Z=; zcid5Jn>n?7!FGEt`hlS_B&PC3AKNkI1MTgcUgcV`EJH#PsHlft%0@StEg_M!dt#X5eQ$n(U#fAwg!lOpYjs9ib=(IKOUd$N*0tV}jy;I8FlkX0x-{dH)m%Bu>!X*AuD4f17kU6@z9I=nTAuuyu z1%1YN`KImd;@i+QD|UQKB#WnJgA134Red#h$Nnf4w>jBBG$}@dnoEzYS5~Qw_kOH%3KO~Z-0a9yp zm3cmb&xsO;b{ymiM0FO)!xC;8>j^nG#Q8^rQoC#bUuK_h5B8VX*cgJe!E>B2wR}AIY&>)F~ewt5t#FI%7p#&kAf6zm8vA2=31bWe!YV5mmzT zA}i#FX?1qGUJ%RZGvshJe#qIs$=>AJnSBpw;zhB_{1veaDDQ;Mitn3u_vG@D&2?jo z4#0>En?T_DooG6Gab+AXFWbKP!<|8)V368%Ih{RZ-C=RODm0Lcm&<`N)9-~g$uY+_ zc0lp{HL;O=lGWPBrIhoa#w1!gcmrxZwX_Sb*VN;s)3O67a+Vp zJt#S#*!1dG{wkPB+6RUr@%Y;!)8au)8=S`FZ}!EGj>AHy4L068Qe~d6j#0?a$Gt1r z-YFVPpE|9)CrLAAX(|C;f47;%X%+3wr}Yn^O_E~zr1HKU^yb&H+y=`B{(UI^K5g2} z@=u$Y6$<}xPO?_{m(cOC9~BG3hW7%5y^{fBU?d`#-}V(mkO zLA)soN&4Azf=3lOQWloxzT8p7?Twd31X6vbrh1?(DzHqvFmgpm`0(q+M4K_2_#JRh zbX_hESeuh#k1rCJ!zHAg852qk0#C0cMN&HDV{ep zZ0AKzG5j&=Y$fWn`AEA zgvyE_6SX3-88;cCm4sGG0S!MGIKA<;EBol_@e3$$G9T0`Qes!KKc|4nT2*Mx{3v`| zxaO_qgSqDwU|I63i)2k1a?;cd|64;SgX2erMsWc4(y^xC{uA6UF3D>N)#EKVvN{Oz zp{j@2FLP|!*QBTEE9;1@71$tKDxO_eY~z?yxGQ#VA6`%J+29x9-O*~oRbiLtz}ELq zSp!;E_1Ksjh;3i(naO2Cn^_#GMID2|vXMYKR1$Z|3foxV-WZ`-k+86ABJ%N=_4a9# zIU6<=NWRoQQ;WrB0_mQLZ*1Az=1n>B^=_h|IaIe08_QMOk6kGXdTuFtO9*86U*dFS z#G_}_R{r7h@fJj3s94-uByBch&2jI2lSCd5X4p1m^3>91`_PH@jM8p<-Ixt7Mravv z&J#)l9rId=1XBbn{f1gclBb4=dn$Ns*W5jfL=+A#(mitHWlt>ox)+X-D1KY%|;DxkL) zTQr!A!O;^*4|fnw&vX)v$Kd0lCzyFLS-iO5>?H8<=n$(XN>xPOoyC@jDZ)#Y^QBL5 za~IJSWA;hxhkkQcfmPyOkm;6ibG6TbvYUUYs?Ue88Iz2sp7?j;6Ac&OJl+GOc17B_ zIO+YwJtev$7Y(s@xHwYjL+qLu3AD!C7n)^np|pKk>4W|V?)Ze@a`EQmL>Q8VvmN#k zeK(%wVjC)peSvDPrjgX0ou_h5!j*!MnjpCSqPUZ=(j}TUjk9HcAuikUj!w>QHqQY* zxNfXCsqv!a99k% z9wl^2@ECj}kl?)z9W9vrj(Z#5PtHG~dc4p;bAZ95lCIDW)wGVZQ0W~jk{K(S^IE$4@kiJekz7nFvcX*zERWoVN$+cknuiQ zaHDv!4rIO_7M2eFrwFG9j+aPoW93w#!-JAb4lk#!11%h|h1C?+*(xd|28qHxUFyr@ z%i5+)nN-fOozYr$h}o!F&JLP!J$#YqrLm;Y$|H+#qLqsQYt1wWqYdE#j4*wP;9}{TiT-}ffP!+V zkEd0B7=62Xlgos*iEmH8|8lucj_2@BoS7&Ju8?r&7=qy{E9I3!`EeW)<`2F~Bs1z) zKB8)ruNGZAMze)hrhL}+-Z4u07E-}OAhQ|bm`L*9O!)J8;qQgG;S8oPxQe1{{KIGB zrO6p-3g9n@WaZYuIv2Vyv3^l-tso;8iE8|7MZO&$p&^1^%XLCm<^bps*(leG)MAj$ z6qw1`za)59Jjp>3>Z%)rvU&@=iL$}!&~6k=3mhZBN?~O*%T1!+tJdb^>E+9|GtsLx z26#K|DL0E|7JNkDEz4JI&x;pfl}C4I*#t8gQx94@uC(Q=LfgkaA(#}$Ja46_*@RQ# zK-V!!($XID0pBKE1&8UD!)Mid z%C~%W*@+|Eay8{{p-ZZB61N(@v|jG<$-LG@G~#d=RPPndT}8D6e9JhLzb&>&F5-N; z+$WSi5CfeUg-tl~9kFxcottx9cCG=GY{DnTp2Uhhaqa)E=w7j!G0Sm+d{1DH_z-NZ zcp8-Niwwuu;m+4857>SsUZXTK*zG}~`Svi*fe5O4NHo=sc;}n7d!ESS(K&Jlsa4Cv zBG1PvVLi{z2OkmqP5ffdD8Kjv+f(8t$&ZE{`@;m}Ud_%>>35b##l9G?1%e`?ULF(r zQ#@y$1R`PuI-}!RSS8AjXxF+@6r${4z5G~$<8zQWIyiRamOl~A=nt5nZW@@Co)FwQ zhPjG7kF(~d!uy8gG=zocNt+Kx6Th7DGn%!Y>P|>dHWW`uF*!us7NOf+q!P~ZH|6L4 zW$Ac!6g}Y6HlK^H>7qFHV0lI$uhJZwWafq&|3Yk+9EETyZkAsP9T^HvB^e#9!}R*Y5h_r%*F51V16yeO1+oDqWq+54^XTfwy4qg_DgehI*!Ur$XH5%}>bCjU;l zCF0XSd(myDUFK!+ycC+*GR%svh`k(hkHp_sUbV|JQtQ$=N`wpB`1jJRn(LFA+OX5t zM6Q@vRTzLv`Ge4eo5K7|T7R^=dUluJPZ?b)Cq(o*X-}{lDUZA^zDynshOJCw5G-%l z$&tw*NZvdWRh9oNb*j5eFKeLdo6^0QY6G-YMti;`RVs|IXyD+6znsu`d<{%)c$ktL zA{~JslA1c>ZF|BcOxcJVqCPr*6Z&C(38xe4yHtfUJNHPV|?RwAq1&P59UR+lN1hZ|dtME)xGZk(Wc<=^Pqm8evBN727tJ z)QGOt8PN2RanK9^!4}ckL^y1fj|yg;3EbW4TvpMCE+9A%tPAxh-Z-9>3j)@T$xGk- z>bK=%qPOOdA~nH4ddfmRo^BIOYb7l#4QGuizYwLF=S8GBI6nko31m@`gW^L*hv9SN z{Vj|6tB_GJ731Hz?&-j)+fr%M!G$tji>TR4_KYO29T zqi$ttX6fVn!4;z^vW`3A3bv`{Sbm6eNVDnzj z){`kkrN$T;dws#I!a+bUu0BaCT7fy^$!B}fIyG$s)=ub=mPGkxVR<@i8GPw~6kQLIh_( zmSAfaOlL0wMDQZVHBM;5m{EfI)1!6@m|9w|c_e2su8a%FR4J#$gsDO%6^)YBG|`I3 z!lcI0Mot$xCKnraGdREuksk!oMdfEU*-VitdM2tfG|DzYna5t!vhf6-XWI(z81KTh z6s3lV$F~#A3LFN#)mc6Dvc2HKvFNx%47(F{5L!1LMr%^#Q{GW9(@>DNoBHwtdc$K>#021stBM~*;8=KbOHyYac3W9kM0jr zdp`NO^a(5z7N5aDduZgGeizDxoBlAf>J)GTuXzo=B94=kY#AmoR zju6Re^DRr&mLmo7E{S59D&Q355ZW$YRsjj8If4D+=eoxU2y7X9a13DW^Eqb*oeuYy zXtGg0CGn&f;T#gMW5rI0K_MqPLEa;yjNoyi8Q{zLf(rxnc7>Ar4x_Ac_X)q1G>!@+3Y1 zd_fry`DAZR$BGC_Yn5@4AH?r**&mf?uFz=}XV4Xy-#bAplew|{6=_ZsDRB_6m73)w z+lR!dgf$f7QZw%>pBB#o6aAw`0myt#1~iJ=tDq)me67&NNqK6Rt#nVZ?EQqt)~Ws} z6W&Fbriv6M>NMfZixN)!PTuKueMefFAS-9s{$oxI+0GE$%b7m*e#M15BcH-qLYu_< z7^)sC{%o;#V@Z-a4c<`B5xFaca`SM4h*Gf; zL;YE4Gm_?if11pA{$Y(^3UD!;A*z=m*ww$J`!GIzeH^dl8llr-p0lVlv93Zt4+x9Y zyjx(6Ulhu?t_TxF<6o{7%g7B3Sm>yA>Ap_z!1!*0GrLe$uvxAL)DbB@KxRQ&0S5m| z(&h*JzxOOR_=m+}301GzDmRMd$=BIW-ZTd5CZSb>45bB%B( z{I7&>8azvL+%1Narx@}WX;0AP+2Nw`;+kON6e#x!W+(w6e4`!Z+djEiN>wc^NIm5~ zk;f8YgLA+Bjt`}l6SHPRsi531_G0`XTPNx=epe_@s@c70{}5EaC$v?(Lqc+v?+YFr zAYMQ*?x^tuvy=laP~2@E6zB?0fwF*Df9zHv#XRI6=EZVBqLr)61F5Y%kvEP}<^~u) z|FEQ~k47@k3jT;lcZ{-5z1ZSadZN=4f1x^NG^72{KFRFk94T1zk8{jED%FOeWJ`vY z*RaQgGs+V?F?v1Q8MxD9U0L&K6ZR^aD`9M?zl){cSAHzETO2mHkfGY6UArh(5Yb^> z0J;XatlBekQVXe3e<+TIDH#3A?^7 zKg4jh%FhKWr3;SN8jzm$!IAjQ9+xez|BTR1(fcqtqew#V3y}lkdOUT;r1DF<**n+Z zfI)FMLj6jTKjg{a9Ja>7bX0yV{?%YE*n0R!b9#B!9+uA`(tyGYq1}@-3xl(1Q89#P z-Sd*(m+Xls6r$RY+;F9nc!hXLG=pB^e*QlLexbVDZjPP z&g_#+FIB~`@{+{E(I?qYm4<&OlENjL21P-#;)#7D5BW6Upb*M@ey{ka{`^>Y50?N# zOI{VtvO$z?u(t85n2u#7s;kN7|ok zz8D03Dw0Zh9i(S#l6>x*PU zS{xR_&#qNA0IaQ(Dk$&bI?JHKlXPl)HJuS5*IhOenwt_LzF_$B>pr@%=#oJ=+@A}0 z6QSec*yI~bb`wlzQ{kn93F!z`HlwW&qYkcZ2Du+M7q~Ys066;Kx{C9p;Ch2 zw#a=2X>Lo=+Y>d=YFP2MY$bYEehlvQ+`GKDZw-pGV(7!h(d?tAG{=! z)FymZEGd?lffT7DX&2ur-gMp_?7hjfYggpl&BDzE9y&#mjpH|T56A0xs>mBLUT8E( z1;C}IQKpGL72~D(9f_h$7fOeFeKJ4?%M7ubbFh(XUEWN=OwqA;n9pi@$J$0{O6;lO z@qx0f&17)6_&ZSBfmm)xJ({{Ns#!?0b^vUJu2$JWlIQX$=S8Ck(2f$Nrx%kxR6k=a_i(SRC_$}5L7`<`{L?-rcsgqDtH zu>hfmEuRqSj7NJB61(T!Vl=}(qRYk(LLSO|0cBso0s46xr(E-#QC zESNFyBZ!2()>J=4Y{9reasgLF=WZX9a;SgliXmjWiD{>Y!^E=W9P2$q63|bIz7`+d zJvx}hQ_A6hwbjzPXU%s6%Oiwv9CiaCSn4%+q>pYH2qp}@`;QXI#5VZb;#ucI>!qrW z_d^{KI@5BDbU%tGXEXM!jZcZR#cPaEAum&r9_!;f<(fnr%BCGD$4U6T*q)<<#cN0mOX z+THoV$^oIllde5p(5pwBWCLQ|(IY-!3>RCjQ3gd*u{Da}meoHb@=QEy?o*!U`Xg3p z&K*LbtoR~UkMwu&B z#$B~doiwwYVEdTr?^CCi6K&@~g^xpj69+DKI31eGkVeA;$B76|Ge>@($L5OZLL z#Q`73v2uzunTWb=>Xez~RNL1~{LQH_o|JX(YdxS%#}gu zydE<|qr(%;*!Q-nliSOAwmagd(99Cl$J#qz?2N#0_aPSxJNyE%|5m-@bAF-iOnQd; zA9D@?PE7qp!kOZzf!bAb{l!9+(uX=!Q4;VHu-aEseThWW9LJ+hvMff8$ProTL{b~f zt4^Y1#fJdPoCD_yfnBSYnliauX?q|h0Jjys2XPM%j;n<8V2N*JZ(c2wwaKakep$Wd zv*Nc*^f;}2&UW73Sbf;olyA%DMKf?7*;aE+xke~c4hQ??rYYa~f^Zgf)1S7x^7s3q z@C7l#VZ+ysbFJ8E!NMo@Qe{@Uj=xN3j5xM1VzPO!m;CLCH=RQ=c0P{&e_2)q$gTYgn&wRBbKNqZ;$Q{`44zc^mIG0yEXHch!rGz}56V4Z{I zc7Zf#XyY31!UTGUSXyMwdCbp#O(c^Os>4+zb^h-ZUO%o8IQ4S)sI~Jo@A3~z#wQWk zKH85|X1ar~3#Yh_{LVL(Z-CTZpOBgmf66zd*)PQ?GqIL$38bQClq|Y>Fy1Y6Ys|7T zDdXEH_lWI0F#%J`y|zoxaE;4^8s8RsH3l!Xf2-UFQk#_qC`@E6(yQ~7&?`CX|`jS~vxE7mE>-U^)?KSWw4g3inLMN;=FTf`Cd0sH$? z9z^JCImL)%mFlo$Etvi&&?MJ-NHi@&c(C@AdD-?T2{kEhVGQoWqMOFRHTy}%R~`YV zEthMhHB4A^v;07sw7KdDr8V@2LRp}_t-XC(dDM1Wj$`|j_VSqR)TNP>ZBlvM_Kxvs z9YiUygnlG4J4U*L)k0zBp7LX{k7qAaNJaV++v)#^VhYC*=6<|90cu3Fo|n3)6H^-_ z`qRKCm?_C?p7ilA#n49uBQ9xZ9vbCm;tR)q;=bP5YZv7y!K3518T^j&bK9dS_o!7S zBCl1R7R*%gT>jx7tlDS9DkoLFYEftl{{mR)+dan#X9?S1N|}|R90Io6c=?ss!ZH3q zRemk7S^RDX-W5cM!p@$xvtz4Mwv9yA&q=jctRDD1!dtUEFLY=?jZu8|C>8sH(C*P! zlm?F(|BYZ@{31LV*7c%5hKQoBp5qBa7LebHruY6pectW;qx9jyHt!9zgDa zIE?=+v_r0oI&wj9t2YI|62F2}s=riuOK6!`x@bkcH`dEv#L`K^1DO6A<*#C=#|ltZ z8XYWei>y;^lbO@X-)!%j?a7lSmv?NhU$v*Tmv^(R(-SJy@}AArsy`E%`ghw$RBg1r z|FC^r#aS_`&W{#*-#@GwgxGLMG)H@)o@9d*J1|2|;eSe%E)Kk}8jgR7RH+9sz?m@x z+2`M)X-YD@$m}rx5z17}6s=$_i7D^MEMQ*%&b;H9##z{RoDE}E@eoR#lKgdM(f0za$znKZpDV|&dU3$j*X9V^QU zEg9cgy#i6JVhdM~wYQh$ZSPXG;d>vqJ(x!hxvby~xL9-bUqL+G@Y|-$XfG?;o)DlX zwUw1@ZyUem7&p+wm6gG2FQpNL3#Ug*Sw*_O_%iATo1be{sb0w(gJH@ktBDY}7Wq#` zJ1x!2l3Lv-bLBAE_yG=iTrcTB-P|Y><}e#Q1-4RmIVnaT9j~N8FyrV zxXuZrL#6=d6}_!1m^ZLUIYY4tkrX8rK)3}A^C9btW(mhcshJMz*&rYH?!kSF^}eA% z-cOK?T~Ql}+#Q2LqBJw=Z!EHAG9Gh0RZDLZ;Z)QRl%wWvQ<2nwjrEfGkQx&r_s2po zaiyQNxzMZCBu{NGTiDJ7cgDWsPB31!6wC4HK(#<1bgOJ7mQDwhc4wXQgIj~uPR&W> z?SuJE5?g)Y*b)<5jf+N`kH3{Xk+tM)vsKy!cZ+Yuvs{ziWRYs;OrAQaOtGDE6gvhP ziSd{!mP#v+KQzT>S^UwArR1ZTXNc94e> z1tyGTE!#-BZzd9&Pw7{0EA2utf(QZxv)bN1KMj2@3xz4)UU0&64p&iSwu9Kx@ze8< zjH_uoh|xDS22? zyNT@+n02}ps>|+RwP}?Kl{(nirV;h_5Ir-6Lf%)Iy6h>obq*Mh6IO@MGX8URnnEfJ zo-3yL9QGE>>?{O<`}8M7zE>>fu zlwk%C+tKkN#*{;{C)bPyPp%ZqXE{`K*U*O`!j;2lnxG{wM_pZr44;%DS4!IybQXu( z-YFP2_e(wAk!w9ZZ>8jGp3f=KJ)A9x2Ct1G24R^?P+C>?Tm|Vn@;lSaogWb&W8mC zX3Yf66|5==OmAx|C)mC;c4Iv*xjhWpB=0WHO= z(i2U>sGI#{2_LQAjCi+Gq**O*sNBb`OBK43a;k(?zU&#SsnaC9Kkdn_p|Nthe?KCI ziC{%Tan2B_5{vZ=;c$nxzMLs|MY1u?EUNp?65BB(6mki6l4Z+m2c6|?@r`oi*~VNp z&k^}TAl2>dT#*}dHA0|lz$|`7bg!U0eiXSEM>vu7W0WHEJ&Y1BIKjM!8rq8H-~y4} zYB)$AexdC%qI=Um(|;(^L^sKA%^Z;zi}XeJs%p^AvYIXdG)1RcL3m56Tq@OYd_0UJ z`?^eQZp@OUM?42EMUE&Lt22dTp^s92Qj0t@UIj|CkoSn!Ry5(`={nI=70
zug+@-d5=aUUlU0l!in{O{kl*Zr=U~lpr79mNe;)Tko8a=-y_%+o#$}w#G9K%b+6#Y z@lu}cBUwYU+$Xl_IH8zUzG*qdQ*DOdZI$~)GKRUzD3?=tKx}fXr4W&fl?O#qTdKz$ zd>ZPx@-5Ni$Rj5w@-qc!Dd%~dDuD`rbPZlW%?sR)2dD(R)5s;{Z)DLgz|06 z8RLVvGIsJYku{@3T)}a6E02p*5|Ck(L*)s9yp|As5hseiGFK?Ax=64C;f#&)9njhX zDG7zoV9=km-c_+2^~y6jI)OXNcZENS#n55c2PWewp(n?CKC?V+`NFuYW1hu|GY6rz z56}3+%2h=)3E#8)(D;Kh%J(hb5(^dKD?zm2+1$m?il-w3{+W2%LTG;=_POYXbW#Pt z4}nZzt@w;23T*8z45?b>IjeppU<4TM`7nffUijLW6jFPWp5z6e$J@>`r5*lUTKgj_ z-Byt~GH$8Wd{Hc=hD4+aQOrvT`DQJEMqpmGLw#8|b$=-eEk6dSJyLP|1~FESgaFNo z*Cj>6`U~%ZR{5#exiO5HOGJ8zPO1FNA5yZWKU=H(T;R{K5a^!_*()L$Nv>6e!Tg2L zY4LG`MBCNRV^r7#*S zDCt>ie*jbKXJ^~VxQ5|ov;5JD>8n!aKFra?HhNoZxvHLN#1I0!BQ~SL2&vMEpzcp% zo5ULLsFMx%UCSlrDk5$YCQjtB7+QyibC2cy7eJ-!k_;@HxB~xGWU;Dem@IOw=q-Qq z*(-AmN6OUqto7vlN3OtgL&OZinF1o(H#WX@{_X=Q-!HIS?Stw@-WNhtd9*U=kP{6Y8C6d`tPz7QUWZ6i5jz zlz&@six@5p-i+Re5u8{$gQ3(!2cS>&e|+}najl3k#Qtlw_hT^=`hazdCEUqWsxI9uthG*V=stSp;lH4@M&bpyY;$s83@4Nh;N7s2 z!N!z@1v4&bJI0)t!r9o8`AYm~LT0q6l~Npq{b65O%sQ>Sn6=kO(0i7}g}#)BWgir- zEFpktzhb7$Qy??2q%ED72MOtfhRae`L*OCXQN~7k$41K1*6E31#RC>YRu<1PVwqo| z-iI@&dcbAH^3pU~@2!vF<64#zOGjYD_{@sie0jm{ctt!sSXK~8y-d57rkIU!P_GDD zn~^!A;I%LsmAGL9Ctk&9$CF48u(Gn)C(@3Jz@x(&Iha^-mK{32(g{Znj$O4k$}#S4xvcn zezcbGjxp;kv#MY~xVBJ69_t_MWg)XU*AZJhHUsjhChM=jysRslDy{Yr%}&dDB561R z7cq;_`wR>B^!3Hl18bN=m0KRpX&VTpN<+4rn>CAiL&5axf|{xy-w4D*&O^$x)kA7y zYi(SeWJrC>CRReLBK06_DTH}bk?pFp5gTS~+$1(-GapT5DZE~L<#n{V==Jdq&d@S8 zFuQCav`4mxaX7xM0_o>80^#Huj&+<^ik0DbxnWjk&(`1yz9b*BNX&}L&sDjN)pKSs zG6ZzBO%R+J@6MBEtV|SIHfZSBAhwZ{Y;Mu~yoeQBCW{bb*4?73q^{VFGR5asstAm+ z2;pC*ilr@E3trDnHBIR6(K#rU%SOw(>7p5CXBdh@&t`~R8_TFMi1#2)t|IAMMi>{^ z5)OfF#nQ$V`<0Tx16iEgi9Z!@!G^_XNlN9m7flWUTB#;(2aycASvM>e^lwL@)abO0 zK~YdB?j$rEpXQs3zV17VWh!*!UqfXV%C(b|Ho#5kO1!Jk;dzLVq%5yAyZPKYv2DhW z*En`}7thRAlQ4SN!)GTYMM9a;*JrfSvZs|YOe2nscvQ)-?Pb+d^0A4VL!&_&d61)81iX=`yZM7YlRJ7LNq39iMYqwb?31S@-08Pt|5QT5PjmB*SKpWyijx1IPHo z%&6Rf-xl|4M0vJ~ka>Pa@`+o^aTYn3RMgF!G_f4-Bi%8Dku5Daw-W@D$3Z~TDkoY_ z>uqmOTv9Rix1krR%+c~VrOjG7liZxhPHHOC(k_~TSJ3o&k8Jql)4AL6Yv?CUgb0CA z-0i&3)z3ww!zU}YSck9DDR4rHLkV}(W%2IVzC+!l(ji5J?T~2C!?Ohk3q9-+Ix3sS z#1`j4$#AdeaoL5@?oPxXeKxjo?3q3-Ajk9I^^2cd8P{kT3Dr&}cEC2?%;{3&sD(}$ zwE9NT0qmOm+98pHg4Us47%C@OPPQpe?ove3YX%OJF@kv(s-mNpF}{5mK+%_9)~P@3 zKpDw8B9ORQ#3Ps`Qjb?5%D^_xhkiSLMtCZ=NGwW52OU!wCGmVIVN>HMIbN!5Em)S zXGE%0j*w8|K;ZeBSlB-*bb=n7CbU!RA_RDy`VpNjltWD=)FR~!kp;qDj!vMIR9MHX zK&;R7r<8BBGK$PuA{WGxYw94SWUrhpm@J{YLB49ZoFn*hEW06;G3QdOU7J(kJ%w5S ztTpb9?}XQfbvRET4abnBm;}3=FO*V*9u7yij?anQ5@Z0kL_8Z{oXIO&T!BK{7485OIS{JAc8)Bcr8Y57WSo(pYnO1 z-+6%`36RxGEiRfmHh3urVRyOAr_!@tjU7Bux!h`f6-f?^Z@9vGr{*_kFBbhRRM^%{}0;vtwVg6Qy$a;;zn z&73p=t@0NwXZ~BXY7v>WRjw0EQ{|7(F{00b)^4m!X3<23An40hy(m5+!^Y>KcfIg} zv7D5aq;G9nX5QdW7bj1H7nrp7MxopRo%p{ih-B7p63tj_lMMuXGv(T7E*_ZyJcDns z$`4}e@RW{)(BN{b=$^5pVilCz1g?o8C2kNah1PEun-rr%4-q=Ke(n%FF8Zc_xwQID zpxV3nR>JhSiSM#jMwCZcr&y+5?iSl9mocXt0zQFl13>-D!T(i(G$iJBL2g-|`kL6$ zRmWn1A>b2BCIU{fiV*${z}j9Zyuz9ZZEjz=$BKtXXNk8I0@-_oGO8U?jVe7?d$~_I zQ?n5ViZA%4z}ne4oQ(U*{Q$K~7l@5I1rx;wtng5DjG!S1hD!+cGq;Kg6Wt!N;t3Y`mj#nGt)J3qa}FJG8~s*XE4rC0F;+}@bmziv&YHk%Yv)K6nL8}a2F6+mB2stm%*6CoR@Gt z{E6t&K|Hv4a;CRXoGCm&4(Lzmt{UP{>X)B^)wWNKRTEj~&#m+IILezn-0fenoF0@t z@Wa2bm^%pzYAzam<(ER6#3F79`ryKRlZ!D*83N{{4 z^xpy)@L9!>4V6~~?nqu~(u66r{F=|CXqik+NZ?)aOt+GI} zfH%vZ#ZsAKxY_h@_={lLLtq?=UY29)uVA%R(v`1=8xZk8%ipY*rWyKAa`MO>z9*VN zP}rI9p???HFjg&h*E+`F<$a<52IXj%9e3YGCiRM31k*J1D3tf<_)p3FhA7JuIR6N6OES^v3AZo z@lRpBadQ>gyCTWvPDgamUl#M}kJ8cuBBj&M;#NE)W`!+SB39@UV!LGDafy(AE-935 zV%%=AS`FH?l<1Q|;uWSs6qXiAZ!2UB`ty;@RV>ZPxn6lcT^2;qyYnfRpyX^hYvrxe zYm=#w5b+7-T@0~}p%+v=uONCxY;CNr$meQv+$y3uMJ#OFm8|nfK)rQ5jyb(n7Rrnu zGtfJ)Vlgw5Pn^^$t6JP3Sh(qpvYMq;;&G|D#`UWUy_gKG_m8o%21sq{_{k8#wh-Y7 zu9i#+XR={i*7C{J;El4i;0p1ww(ePjBV6FN z5lYW^MP`K1L~V(~l><1Y#=WgF zQ!MRah;E@>$+jY=$EL`J#pcVUA@y*JNO@Guz+1E-*7)je5mU8 z*_z;*Nv*l6s|N_ea)5XWf*OP#pynq*v}bdT^s^ws?esvar6U+b4{F(64iY*gh65T1 z86dpya5-3X#TeO1TmlcVvEL^xgWF^_TIEoy>=Et5-Z9Ng(P3gc#VG1iJ};=&;Wp5f zd`?@_gZBulW-@Tbn#DtAS1Y};XnY-q8kv6eyDpHKrM|b(s?&BxMfLjl@S(R6X+ zNa1sQ^jqVsH{vA-X&!GK{=$7TB{-;92tL#4(|c6J1QpzH>9W>qSqpVha~5o4x3$uz zTn}L))CoM5kJU*N(<;3_wqFhk_Z_X#`mD5C@VlSLMYox$0H zc}a-lIfg&&4=Hb%IC;kOa*E~5uCA#VyZbXDY15`cp1)H?J{K=E95};#nn))3O+#*- zQ%@J{j4v1(L3=~wWQg_|qUklPbB=m^Hq)7+mGi(fd=SpEoPMh9cs6#EC6dmbEt+Ae zHEbp#Vl{K;_``w0{7jsN$>O<|uZ$V~pP59MC%$9g-kX>SM1wSZp7=V^RU!&$DDJ*L zUo^%0IG+X=_&K4pV^1L@4__cQA=a2-24GgX2VE$*LDi#~Q_4k_&xkkR{-KpA8p3k1 z=ylPbdONzm@maY_jp8Le>ez3{);?>Xo*&Qr<`5W>E6C%2n3O1WHKG zASzeSdyvLV!qr`_Nz7dXs~NT=_TyUNpT#GKFH903EcnDf=EAjfxDKTDgCx5~)o}q4 zug-ec#7>d9B37NiXOkZBrQW=*_eu2eZXR{H&CwXF8?3oXQVw!uM>qtQ^Nqr1=fFA% z!wRo%61+OP8DVM1X~fOqKa95-`<9s~w+Lm#Mrc+rO>Wg&g%61Vk9~BTomHZUMF`gJR9mS+cHJEYgG@(t@{Vp|!> zbVF#BdxWoxx6&9FD=jYSyxthyvGRoIdNFyO3`4qw&lTJ*K-dpG2XVIhj$oQD)lIwLG&~7bdnva! z98-8)f7g0X#A@qo?>ebGWqHr&3%X+tL+IJlV(aG%;+C$&>KVagYY98=9DPsZ-eA5a z&X`iZPqB7O4i&-;(qNWnt+8q>AmpU5xj(SZt+`cEakDsFwLi3427JP2QI7pNk)5KK z4dYcm?{jPC65+hW2B)vQV4a0xW{5OI=&AA}kzWR)y#TxOMUk|xL=k7Klb1vuh?YkP zWmI0ayg+?Rr781-%sKN&XWn9~V;(JK$JppvA!+OGmPbeK8TlI$K z=D)U~r}I?|XZejaGQ0LnE*ihJn1<3AUADSA%Bv#ZkGEhX)?Z$;oVg>BX2GqL@;XrM z#teOikO~Rw8&+B=_aZ$rlJ}cdLSP#Q2Rto9S$=1=bt^&x!5u*PQGPF&GAj5LHv3yX z35V_3p;tSv#6Ztl8^sU}AnxMJ{wR{?C$`AL3farsV#~#9;`~Cw_>MqQO1MUilggij z4$lk0M%lo1krP_Rwjq-s&nl0e}V^Cc3M~EGh-viVv z{}f0k5$q>vyk7p5kR-U1P$z@sLxEI+Vq(R`yI%e+v}=qg)6jrY*ULv@(_^A>6znbk zv7A!#C%@F3MbfqMU!lD1cVVtJ=H-08Q@|>};BKQGusc5?mRY`g;l!v~<`-Ht1mT#( zx;SCHf($O;FDb>HhR5)N7O#i_o;GtvS;*p{xyXk&`WLpG(VmBpON2mg5wO}3Nh0v> zP*nv-`Oa4J_`HlhV3`FT(I3FGfpPFP-GD)!b5`q$YW>Y_B++Fxk-Wtdm+LS#_nfk)#W^{U-E)`{2XZgL z6>^a>Pna+6Es_EcOsiR7`y>zwS7M!+*`mAbE4Y1(Z)u`^AUOzK-A{CtXsuV{!+P0Y zWRpbjretZ>M3Pe?@0k~$14JffAGnDi=lUdwuDV{sj9x;txA1p5(3;!ETkH6aavo^n zbdcz7@jRz9cZG7W$Yog%3qBPeTmTOd9an;5f5)MHs8DL;Noq5Qrw{Ttu?+ke(h4ZZ z;X+&Hf*&-)T4y;z=*V~}`D*$4a%3WMAu8yMY;+V*?Z=hPH6i}W(E@+X3uFHXQ8LEL zF+P?y4hSY;OOLe5KC!pf4v7a0#}<8 z#Wsq?$7*D*nA18~?U2mxkuqBZZ`Ru))(^?27{zvhG(u(!F#>LrL2EM?3SzC+l8C#57@%=sEdxH#9u2qQ z?XCWLP$+#3$KP)V-yz}E^00&J@gq3vx0tc%Wy2n%dMs zpJR}d@wIlg)stMr)X}GNgtm%LwWB%r!HAvfFU#aFgaNf@aMrSDpY@j|W4;lHV)Bpq z;P{$3&)*hJ(Lcw;yybYlKTM52aZ4Nj0(@}AlXuD4akXnkbb&u))XdlgP-!QQb#bA; zyc5)<3%(i==S3if1N4irQK-Ix#d@(-^GNpW?+VwQO9V5pR6qL7@_EZ+u~UcwX@bLY zsZhp=#~Fv@;3RV+#+~RQvA)a=gA75>gv&)Y3zQqT>Oa@$6{53qvIqOd;GbrfFNkFV zSa^Q~r<^-fy;3;Esp>n(Yo}KblXI0nY!WSx&mr2pt3_9imb=K>i?A(2Dd#&6op0`n{ zbgSGVkfwtFcRe8D^QV_$R}K@hs@z6dYs*k5L$xr=iOd z2Fksn2OPN^+oF$%KiSZaD3^UF5;@?bXP+d10)KX3n5{^;Aah5Ojg=OOVVAphr~@~}Uw6_jQCtypz&rF+C5 zl2D+SsD{CLvdI6Bxbf}Z_Ln8%Ou(8!cIxAY9-G%3{4?b3<6j>4m$Zh$v4{;^ zt%@h+J;9zraQg8RbMqJ1AsIcI;}3jCIP)6vf~NE$PuwT-2kT>4&^=!NyTa+Cr3=N! z%|9i+(*ND01AN`n;tP&1;Ezc+zdYkFNo^5yZ=UMR-X0#91yKwugmmi3wiFB`q#2+{E!+DKB;d&#&ws~%!1Fs!Ae@v@^W#-Mp z^Vz%$gwVNNAGh?vyq0j3oA-tvi7yd*ez0dA{GxDWVN8mLf!=vkB>m_9 zl->gE8mmN0uLvF(Cq61RC9a%`zYt6kMg%!x_HYa#%>*?tyjzVk2-gL^1urz{4NS|g zd}fg&m*>YgudBq8)tdXYzov_Rk9SI3ltn7q|M5D9a{X4ka#gId5vgE#RrrvgpJYJe z^n5L!_fC&D77k9hx4fR1BMO_MBdAV>Z-`C^!i~s@z<-vL^YxQ8Oztng6TBymd-RN@ zdv^IfNbRvSi~G17zXQBVamN)>Pmg)i&Jt8_8zzLF%G zD}Yqd_d}M%a-xk&+1LmrcC#$+^BLJ` z4*RF9U^#{Q=44*cXC~xQ!#G$Ax|OU^Ss}3J2>bz`w{n7V6=-|L;C+YY-r`GF@rTM7 zNuGlJxvEfxaMpsWg-l^Jp-MB*YV{!OTU{i>Ecyj%_3C8}!88i)Y}B7Tll0wd3Y`|? zYL*IF$+d)1Vm(4E7%pDTvbI>N*Oe5&MwE4gQqM_8S@&gKk@O>BPqiD;4HNhEM7Ij5 z6x*__Z?O@}!^D17(!LEuGdd^6B#o9U+<<%qz;)iMr@}5St?Y0o+FLq1=haNX_sJ6GT%kuFB8U z+-0KJ+}JamdPbY$jGH7lA=KnUlgeaE-^^pM-XHNXN|_?KcF+(qt$a*=rV6hTW6;$g zfrrIh`iM;NDNu$u9Z=7Dg;5b11v5wMZ5TXAFM`|9WQL`}On3oIXPwUB^dR=ban;t(5> z!!EcAgn;{6D~Q5 zh}J71{>16!lRh>#UW(!Zg;%2-D3m!mxRshxlXo8EbH`REFmguIQ66l?lnkQe^Jc6H z{t(e53LJ0*O~BqUE6Us${ef#xcR5UKvlsxAbFcso7fH?h*kJEqcR4~JEw~#K%aN8c z`XNShs18QTQ9_r*B=vXGvZjbfgVi?rL{N3(j!3+8xa15v#_C(dx3-}YQ>A^ZwYSZM zZJv6z{BhQr5F3$&i&`Nw@QUsmgGpQv6f|0ToFF(Q_5ccJcwUnMX&iH+&90GGJLJNg zU$WxXPM-=0C7vQ})~cc>AOuHU*lv{!#;GBaR;~7;ZQXCjd^GSrK?TqwvTLqc zgyOKN0vpGR$Ni>oP!>$f52JHvr`am~f;p8~;$aFhAkZDH_jAi9I`*K*w48s^IbnG@ zB$6Zn6DrIB%Sj-$;S4O$a>!}PN||$wC>iY4mOw2gl{3NoYGv5RZcOnyOtXUB5o@LI z8eeNevqX|{W9{~8+CC~YDP}%IO>n3%3bRE|iD4jHArh@IfZAVEt%ifQlQhRV=?)4p zR}71I;ZuUiaDTjzTIFQX%-Ex;38&hpZSR^iQg2}~fh_J6Dm2-eDK7D+TVfnKhy;%TqpeO(wHj_yNJ%fX zN?J3FbZ`y3%<|63!9Yh;u+Y%uqF+wgcOR?w3fnn7RY4tfB3ggJ3hPzWX1o*SN~>*L zP48^3d0}vHm1tk02QIJkE$a#OB1R8KVv{ zIPMgg7!#gfe3w8*b$#-JIoj*pEs`cj!>y6dk^b)T6`{L|ts^-jQB5;XR_6xpJ_7pqmt7h2Cf_Jy##%ENGQEUJ*a|7cvx(YXx>OqES*P0GLyOD1xWa#BCkaq)`uM3 zw?+1kPNLu`k6BC!xKz2jJT8!?4ZR~hPu|I-c9$mvtE&gbr!L#MLJvkegd-^5p=kb7 zKlaHBcyo7o(i&-Ij~S0@c}!xyE4WWo!w*6e&Zn}PDs(IvIb)u-DT3+AN-6F~%*-M8 zjMdVxwI@Pfbe8W4?Vlf4Cq!0v`M$`q<14Z`z#@HCD0ze4K|W^e$vevr#4>bvxbbRr zOQ1o~)SZL{zC0|3h@uBXXK+I$h=7dD^MYwuG5q8OoNq4(q;bw0H{JTX+rL$QB$6t3 z4^!6fiz3P7vM&$|K(SsDOY@fw*Z9lx+F|p0#rv^H#Tk!AY=a$cjtw-bVH?Ih!jMP;WJN6f1=?=^VjzRpT zK!&1Xksv_(6+rF$q^!dZ>#y?>r~l2HE_~zS3(9Xq@-~1lwI#v$ZC28$81YGWdDZft zV!BGRC!*lKCe$9^o)|FSoCA`G%{G;6j>}jvbWBAerGv(KjPjY z^!dF&`uRbr<}hV%iDd6&86B!W2z@fPA|exF_pm1ZD3;-(Two0I+ahb^hK095mN`=1 z5laCcR8>5LiBHbs*!$MuBtTpMp7d?BO_g{w0*h2g)cEk}!B5idFFk2YXp+ z|4zV*3Dd^uG=`a?Sf&UW9%S?X$MV`qALsz{|6h?bPvR;5y32g00#)l1JHNs534vs| z#@t5pTi!axnTrw&eF1@~@f~Aav1LlT%YuRjM=e$b>t-Q=<>FdD++G&8lspF^_`1s? zmhX(NS*D3aMe@Gfi}DQ4wk#&JV35Vv&UmOSPO)}XUgWx}7cXIz_2WDrYK@`st(3+~ zT6df3cErVvS1x7MOi4}dMM=%lB1guDa0`^qB3fHUaJe|)dPZgwe6EU0T$c5Rv*Ls! zKp*F7xM?mYnl7a%$h?$el_-{B1KDKg^jUN(h^5UuiKIvt&KIsImXWYSYKDqAwDK#7 zXW)T0?$X_5Wr5tbOaU{yioim_1S4Mj*k^QA;Mxu2)E;dKJV~>xX63!AW6=Zw$kbOC zyCOaYAtCYRG|($+`22_YJhnXCR6S_dwC;LIMld7f1J|nKd7|fSUz=ggVPp$J@NS#jY$~g65ok2&QMw3$1}JPive|R*+AsI z=mg%}b)xHSC~`(Thz|}I#KDf?vXS6{$)B(l3B`ec!jIV4A9jxCv4}&IS~d|`Jf4q4 z7D2Z*6+AYmXpRY@HK5w;4EF{1yt&0Gc^DDAQ+tFheCVHXZ`aeDP^4xR>gTJs^p{QJ z9VmKOFt~t~tpx805V2@CL0~cD+FEd#oFoL-V{Hg`wh>!DR~!T`7%eOnMNf||b`PZU z?L?tGm;2iZm#IL6buqd74HKC z4BLriKy}6q#>I=z_JZjo*Xrd=*&)mF==$9_t2+uE9-RqO1aoi!?^v#3riRFE#Ou_A$F{aCSMs2LD*) zPf>%xD*U8%(&P=#0iJD@1BLF-`!@8za8zmy4-($K+9+Jr8{Oq#p?%{^353#J4xwDz zsiN1^P?vY8*kJB#gu7nU5A(6#$76Hqy}jjd%S#057#%Zw`w;?5#?~DeQ376$6uB%O z8RQC4j*->JX)4gzk@q2$8Lz<5-Z|pVK;n>vBjMldd1< zFWV<6`UDG;w9;gi%C>;V{jecQ*PGFVNDRO%> zV+haQ(q%K3C6|eLBCc=(Mhz;Ao zK}u6SmUa=H5lb5hKb(hwVL1v~;u(gs6IsQu#SGPfWRvqz3(+znn)+zIo?&q1RqH03LV0)W{yZ#3d4t*CTSqP zpBSD+5)o9O?;EHFB4IbV#sk~9`cuR?3S`*WhJru48Kfp46ZnC6X@3-|?* z%|cX%3*^pxp+G7dRmVF!7YW@QA6Ei#M-P#=2@YpnoIjvJ z;qiX0@anPCblJwlFG9|hFM`)zuTG(^VPa_z7tp#%pZms$6w@eQ64@XrU2j5P7TPE} ziYYCLAk^PpFStm6K?kCnHwb2Ow)~_(ZxsD%(lage%1r`Qq_=RkhIwz5n?*DFcY|*n zE4KjDwo0whz)+*yYK7j|I1oKjv!P;Xl-oqt3FxjBx}0isfXaF@`E%wOEUO zjI`Ry*DT%G@n1GdbXs@zM=f3xMFP>4Z(Dpb z78WL+N~+6aLV0gQ(E|amm&b)t%fX%}Y$8z(GE(fu--@PL*f65} z@~Y*u--XGh!fOJn#w@@Jn#O~3=ykyqz(XDl2k-_+ZMh5}k{V&IizCX{-n8yv|J#>V z`JGrgK6xtQE-cU+v>lyS$b;?OTf!O7&8z45O8Eoucw{@YTw@NxAFcX$P=kR%gQ~x6 zrC(P}5IS>n0hM>G^%f!GTvc>E&{p}Ab+I~H7}To-!j*TexoX%H(;qMGv3|qO>d*eR zNGv(j@gzDTiLNaSW($Z>9Fo6Ut2#&UvF;_^QltD$@C)%G#1oF@dm_ul`4t442}8To zD1W!brIM%65J*A7`_@gnD$33(m+he(F8)8q;bs0Nz<6kRojICuwc z75K51e+lP=leU9P&W8y|2N3Du+ra7fZ!n|9F9F!X!=uFwlO0)qX6C zS}DD)hj7Dpe=a7JiFDW(h#SEc_tB;DFyZ1)HiIRsm9nGQ@!a1>p+QRu9}`3~wykRc zlR43hf1PxSCBL*-o@z0jWf_6%<6{Y{Z9Jc4MXt%ofV>%S!OgOqaB39WiLT1MXL*s4 z_%M@&y8%`ZS}%r^6M{%yth5!yCdG)rJTa{+32YqCq2vL=N)D*DL9PH39^kU9KSx=` zs(CdS(yKEps5?BxX0t8~&-A^>e_c|3x-qyUjU5=9L=H}j_l;}k&sT*~H_^912ugpF@# zm9`LlAl5~?>!5#Q%C{8Gc;pe-iT1V<+BMcx?;sLzgnA-XSnWyu{bd`=$#7Mli#Sg# zbz+cCvw=YxCJNq{T~jzdiSoEHpNa=ogKKuO)ozM;MQVhk)a^4xFs<0IfodTSVb-P! z=CQ2U!g|welUP@tf_)>fbA_M z(m_Pw#!22zFvS~4=3{AZFSL1Vl{S=Lh(w!Z2eDMYgpM|1Q|&02-b0XnW}MS!C$XJl z3qgtC>l$Tep-ffZ$IXxMfB?#{7w5Br3riR9U9FcSWZpF5ge<&vREDG)R^Hh5yNhlW zoviwea8IlX!-+8^Ls<3{N&#B?AQ|9bcJ>lVhpQn49%XNVAH}#Jj7N+hQQ0Tk@-)a} zkn?3e=673QiT`$KACimL~KbXH9H&JIeursj=zl?m$od zNr75?4<`03{(4tAP^|Kn#m=#-93+tZ9l7!_q$&rCOo$#qag7vr2uQ6vO=cKI%#@L) zmP19!D;1~P*ckTakm198xF;Vb9U8qjTqIRpoEx(=uRB8MsCY0_Nq`+Gc2*Do5@)k9 zj}kZ}S~6P}+V7)9GDb{KcUw8eVyf!7U-x58bF4_J9}|IG94D6SRX1jEG<>|sl6gcS z8?Zws2qllF2?3YXu5zMS5^f*-Pib1tL57jlU!g-Jon^U0u&khponn(?8R5%{6xQ2H7of5scQ77{ znEhJo)%c)Zd0@th3@S8VB6SJNg>DSZ}`8K9N1G1ENti%riNZ9`M( zj1Gtm1l9oo#u|=De`04x4<=3|t^APXO{+t$VPds%5>Txt2cf^--!}rwRjhV*J~kCw z&X(o0`XQz9v@&e@@|g00dgwMsMAppXne6eJG8+Da&b^$NHiN{pDmJ_*~1o z#Lot}{j9|d?4SyuUd|Ipg}EkaEbQ|^YX44Rg$HgOOX<&9DP^!zrcEsuSbRR(oWe1D zp~X|8IGHeb7g_vCQbqJ-_;fQ%7Yj~_@f$^AUM`_rJ18kR#>i+XLlX3PtK~i>)+Z@g z%cUaE$IR%M(kz$xBpJDb`GlmyT$jtOltO{jy_YLQ(hvv!EEJ$$@IivK`5@NfBXj0- zmn*H7@x`jp!i3@z`)<-G%+KoOYJo>80It1UBaoSO8pMsc*5dlnZZM!Qd0!N|Dc1OK zeYB(dq;j1|Y9vEa7?FFwB-oP+zlyGEVz4g@r#y`04Jab62heCpBHT7OW}eknxxrc~ z{>0oKHT{hOzleTnGlv*WAPIV|Ly6nXwnY?c2@A1XuwJv)+R=UDijv4;xZG-;rK>R} zy0a!2w^{A3cx*P=w94(4Q;`i}q2W6OK8$5BecJSLr)}Jv;-Kj>CX~A@V?5{{BY-pl zpSyivtI&asAuaRwk=${Hz5lAeZXV5zq0#-C#a&`m#p~!M@-o5n{y=LO0ZPj^#1@X% zpcjCXz9%cmGsKomP1?Pnwa?}!8ZeOqq1;^+*L2v=WfiyIy%ZX{Uy^L!?3^% zz-h9s8|8j~NHd{Uy@zf;Adoj*=m;tz^5hDACT6*VFGril5#K7`65cQdw7t#%JY+fN zVGarq;~hLK^m=@>*?YT*2!Rw$Fy)yoR6UPc+&b!TJLV>A=+*%SOdI zL{_a!qdYG7V2l=Yse80MA+Tet+%c@H8Tq*)2gfvFo%tP0=R~jTU4%n=(sHW!mFabN zj?BHjd{^-Ln7i3L^OVK3^Q_)1seD>=d_s8-bY(X@za`}PK63O_XNK$u$*x-kvDP1EJmBJjea6TuxS*}`= z-9K-!S#>G~NsIayL^li+3Z$mR5BL$Nq1{|rNE9&|40+v)*@XLxRH?(|CCeEhl?fb3 z|2lYp4^Ftq)%Z{di3< zEg~}gF_aF$ndn}zK(UuWe*Z>3D-}b{J0gO`#}u%3U><%Uo*}@V^;XLjFC+H0<@B1HJZ)xq$Ku^FS|n{5!9%W5 z{v`HVjvz7Ax^)42H|yDNJ`BHyM)|YQxzRF|slWV%a_v(oQAU~y$2c;({MAa!XQeLk z*!<1%d$H({hv85sIV$goX5foDsVxnM{dZg2J3mD&_h_TMZ>_X2ChC`IEI$z0JX(Xz zLFEt{tbd4}8}o?C&yaR7|FpGblYArV=7atvLO^R5Fxq9r5q$ZFKDk(sP_(dvdbXw* zu>9L!Zi?FID*I!-d}I>@x%6J-1r7E8f2=mSsuq!O$I5@jl9yM{hi5^V?{uIP`m^Wz zBX`^<#8R<~9E8T`&-`Guk!ldIj6ur2fYmY#dz=T@6E@3&g6U(2b%+iY3yJi_xFZv6 zm4z*TGS&|jxS%Z}kd~!!S89|+MXEerC>t@28ZL{89Tr~*(eMCXTqHvyQDN@&4J`ha z5Zfwhbs2CPhtWi&E#}4=AZIYMuoS35W5*mP-BvgE!m_kgzg2DQ$aA@j)g~mX!(h{s zfwHW%Qq*2IE!c9F-;SrSx;Gf?@;=20?GiQHkk();SSx**aJfqv;fi7@c7dMZ9iXfi z!4cbMC4YJ|y2k_~apfAZvdt2BHaPT<^R8m8yjy$M(V}Tpp+)12WFbjV2xx!^O!!OD zNl!#L*40HSAIEs*8UVF5b73NMK-RvdRZ`K@hAEWfYb`4+SSAtnniJlJ$4eq~+p9ikhg^&P}@c0G}`V&8N?<`B;Ln)O9f2#T>4h}~q6Xu|Jh zbIzi{7VBkefwVcoj1gB+%d5ouID-*>Sx!+hgOMtmiDEyB6~-MeuiyzI2;5F$d*oj0Rr3l#-C1m##MnK|$Z*+3?3v`&aqbu@y8_@c zCIP6PYn9!^E)A?Q$j2*GY%spM$BW+{mX`@Gu6KIbGfPe;q1f0BdkL(bgTnA?LAW?e}qnueEcJU~U#v#fWJsL7qBCQ^_2 z)wQ#)93b$QYL_<&_fS45l2P{{BK=U714Uk~W)`D!J>?GqtDTy=nuvSStAnkUB7NNA zl=mGn59vvV{X<1EVHR@1hSDLn)nTIP&eCRdI-tXarUq9vSlY@F6m{p7CU=<(5fL`8 zJknYzF6U}%u;HUbM&kpcUO8GI&DryrV+7Voa>pHv9)z>PvB2sKQknj^HTM9pCRy^A zRq{-T^PrV)j2EC2A=*|M%GR7ulmt+M5D=dvdT~5l*~aj25xgRnpVSp@4a+pK)Ziog z!zCFXPocxYWP~$i+yPy;`!eEBm&f9PBN|uC&Jw*oz7Z)um&&m+DwN^I@YqkK(QL6R zVziK!a~mHMcsM%ArEoZvYjXs*4@(vfW~fKzAIC(DquvcZD|BhBbl945p2d}87Bm{N#`!{92ZWJS1Oxn> z(9G(gQZAsV&w8AQ_!l(Gg;vNHp${P(dZSzN_ z!a(a#S)pr%SIWV9=9=Ej5EPaSJf1wcaz{dFlHu{0luyzb>L8~Rl)n|=Z;=pS>pmGaJypE_*hR|GOmt)cxqcfRU# ztK`(H(~Mi@*Roz-8&LB_YNzsb(X(?sAUNaUZ;0gWre~yQq}*e9=~!A=BhfLOIfe4p z)!pDW%JAPOloo9|UwqTzXpBtK8>IH^`}>8{xfTmlH4YDmd^zSal7>cBf(HR>J5(eH zdrj`iDq6lJJYN!T$Oc2+#VP)fEeyo$5!rg~?d4&CR7RjfRZ>zO5jv^b`M4j>DUXWm zTy@Y8ji^^3i{BRBAi9J6Q;U4WF^>t(ji&bpxOx zu8ULTY2lp7j=qs0*1d4BysXuo(XUu*COeXq+8g)@8(QGrHS+0ThoYnBk!h&{^lLL0@|hjaxVLwBtV z&iaBsjm6kToE8kuKx%8GIZGNUIWaF zr{VHrk>mx?sw0L$>JR(<6XA@?+)fr1?uTCPe=0f@9l`{|82>*LNv$H`s?fqA==(XC zu}Y+)W+sNgdBtj#9-UeoYic)sA)0YR2~fa(4TZxmMSEh+;+o8+`<1}LG0(G9JrO*q z{8}u%-GjQoL=)bov;0Q<q#RWCMa z_Ui&|xxlzH(wD*VhS+_%Hw;vV9L~%0o5HC->Z{{^@jJ@3;S5}Yn3hT9GMTs7-&-~9 z8Wl{=f9SvM~+qsrQc9#@BKIVJ~K~%jgC6I?%9oy^PdRbcJv>5(G7|^neVBRUY z92nz7c6wRSV`7F?T`p(w`B($p101?+h2@26@jio^78(}sp(|SH=6It* z4Om2u=asDZm2~m>*u9AcRu-wW2Y} zAE7OK%Q|9dgA|FInq^&)9b%Xy*~)s>6Z&k<7Rgod;fQyxpY6$kHU_CpNyc^vZhjNXGt=m;2m8gcsgE>c`;RuY zAuO9&Wx+JtYrv|+%G%s&v$Ok{P%0|l!g@E2Pb!9nU|WiDB6~^wIGJDB%7=d%3m(T+ z4KXC>TZ^UwErhLx(?{SYx?8NS)?iziU@<+T^n)D3IEK%kD4JKBwn7hi^CY3n|A=;I ztglQK*fDyH4T;%5$`qhlU&TTY;Ej)+YOOrIdPo5wqgtkkWfUlGn^c-EkZ$SbA!iTI zuq9GIEX8+vHw<5sklfDnm+mB4SXd257?Odqtxcr2X*dzGyjo>D!Awt&e4eZNSlM3a zlIV4$IAcV15X#6s2%5TvvFdCqI|A0W%G*^0A7Ti0603F@{IAgw%FaGqg$@|$Kvqj5Q&Z0+x}8^yMYj5>}P!&nne*PY5XgAH?l;3H8N#nkMu zs$f}s(v~qNh&_mbW3wD+#Z}`H)asu)y&PmYjYsOeo#kMQzB7o+H<&7hoTS68{>9_K$_~!LbinAnLv(`<~q%n&i0Ur>
c{vdRlZF=d=|p3a8sp+Vr|t*SYSNOUVqQxel;gEJ# zvWwuyV=UCr4rB5boUp|8gRhYH}O#TuF;wruVuqd(hIAD`|y1e^?w1V6{ch%Ne4Zhvx_96%5<}R~h*%KIlw;TOw8n zhj}^6;vb_$$SKauXA7(sv%(~~K+h35BSy-LxuTA9g=WV{Yq;z&OYRE6Ml^-s2@UOe z0yE+xYzn)AIFHX4ej*-5{f4Ad|BTNGriCoxaQbn9z`@ZESd(sC9WN9~&aY!6x^a<6 zW=t66daRRjXSrA~1BWS@877L(B|;@fX{;X+6d#Hgspw-d8(4sGS>wYl70Y0JP@97I z*CsC$9f}h(xZys|eq9`3mPeB zMIWzDHoiKH`mXco*W+nbG^*FWB=lH3ti!^vbi907a3IL##0e87mg_D5E-H-@+!xa+ zp1whF%culFL)J&R_KC{1L1Q^?9dK`?o3-LL@ihL@@OZAqn+5OA_j0`oN>^?XOfxxT zLEYi2QEp9eem<{%xZFm`bm>Y0ur=VEEVo!F8GEPbpQ9ey zCatu0a^rY0)H{%PeMKm>Z;UM@nQJ-2Pr^(vRNt|o=W|z3 zSWXN#x%+)rC>d{~LNYn!DWN?7`Mi{mK@*=AUMsqQFLsMaT;&;|j70&>!W^o6Pb5PD zaxO3s-xv5W$O#T&10$O5J}Z_VSnqS!w=jkiOLaG)uR@ReL!q5xOe1*;H+2WLJSRRQ zKD@t<{pj5FIBhYnfIm&JCCuP`ca+zWmzmV5`Yv^sP76Olur7Q!+77ud=_6-#+-NH)gG&qR*M z)kC5@rsd}%FUJRP(}BFTH|^>x!Yf42u&-rMegWWa2s4+sl48jChIqcHh=cb{(aJ>~o`pLn>iFLY zekHyW{z(g)--~3p17xduotL+S@<5S~HG=&gfW{4wyT*oy`UKndN9(1MVtAy3OWNB4 z?*?_%8Zrm_9lWPOihkeiDsnI^MMVKQ9$lt{>C?dY;+QPjrvVPP; z{8f*m_yaKQ0p-HG>WCrnqi4qckyV5BlhMXPt5N+wAKA7mFer12P?S67-&Kyw;hQ1HrNOvqNi z`WgRWA%92%d{w>BtA$0nf~av7hrHCwB0y$XTi!Euo)tA*awz;3^@-);i844F3zTMA zOz7a~u!3UDXSqWxZZr6{DUu?fB6l6Gol96V?{}n}Koz&7z+y2@qu9+L$P>uxB;sUl z*U*Qh#XbsxH$+Qi8OvM6LzwMz{46Vw`44b~{V`UYAOcz|| zt5>y{3T%S0menj)s;cTuWp%LHM)`WhNF*BPlh?53v>3c@t`fl^uW8K-svXJNWBAsx zTD2qLqk~CVTWosnTcakm$~q$J#gq-UWdNFWg_7GwsHy=c!teD2*Nl2B8YE|!$_bqp zJ6Ay$7Z@lZ{o6o1ucv5a)kAJ5k`_;u45U>y5<5J`4EvyNw6_QzHWr*3W2QY`ciAML zRBwcU2baX|vZ+wYqlpIE8iCwxCX^QY)QGsAnzEN+6Sa{HuPpnOrR+&@~z5t*2w@k6DLobP`0;R zi>8ML#|BVH?I4oka^$;>&N#u#jp%T!`*Yp!r&|C{iI;#OJb0C zlI|QRmLWr?Po7Z@ve*+F6Zi6vRUa&rT6Dch;hPT;xhbZ6;-u+Q%b}K!kB2bI<&M}a zhY6it4UxBr!v+48Q{ElU21kfw1Pgd(w(F4ssk(&fVPRXoc@fB zLw15_y4>ntojR}+1=C_f77x)}0``&YE4-SoX-jNDFm-ID-Ev9~bo>WtfM{~%V}_0k zyZxrsc8Gx^Tss5MAuuZkS00%MJALqrxp-m5NQME}Wxd;?9*H|htOFSo8jAfIauaOE z`%8~t8deXp^_s184(Jum3(IIB(IR)fKA{vqvnMgscD?iqX1G&K{!kyV9|puG#&lp7 zs4I-U928wDJ2av*^jH}ZN`}1CxP7Ef5ZN!fn3k%Nlp?rQuCFP0inT1KCpaFtvu%7> zC~b|yvu(t3CSk|?KYBV#Xw5W!>n8n3Ke=*{(I7kYhqR$&9!BZKY>{#S=T+<&*?G-TS@k z_c;uo5nLmlB#6GAwB$|@`yjh86(63{ET37m-tP)(mea*jtPQ}~bp}A~fK*~L+b)bV zt&?{C6Q@p`QO>fQ6b(5InK0NCXNygZw&90+xeWJ}bHs9$x7&0%SK!QQOeRezpSAqS z7=a-usJj01g!1jpPLB2Aa=yq1F>t6lTFu$zb0D>A@_@i-Hxz>xh{XufCko#4v znLgXZh1POVcM!Enl+yT=ardh`^y((h22i<5ZGHJP6omU0;b?0BSd-+H~T?3De81 z)|ixyOq?{c+-7;Z=wWBK{PteDrBMb%(&i0iZYLaJ^F?{jVoZn>@ALW%=gl zzt(&~>h2a>JdaxA#$);Crum9+#f?m#I<vUaTu*q?z4PYe*HAO;lF7)?ebwO2g?1H zPp*ESFta>h`TAIVWN_>wAn1c48KeyROsvE5RQi_iV$sDa%ujg;sCIFlbEDXoN&g?V z+UIhh+@J<2enjm3cn7gY6qY?IvSzY+Iz3Txsi_tlvugUb3xj?GdUCt;x<35Zi&5Ccu=g;EN@}%VhqWS7UBxzz3 z0`nF#q#*Yxv81#0IjG0V(*o%yj{O$u{AUDmd(0I}enWI( z5|Iwdvz9a2SRcLTj3@f^4+K9Sy~vP%eC7|uz8jxO;2q<6m*<2sPB30py;u^$?mjO# zGrZzPxe~>?%vN9Em)dH1NyFfT5tSbQNc3-&9*wt`7X{!Q9K61I+n7p_uJV%TSk5;W zcQ}Anc^PcKtBBX-tq0mgB(t&dW5HD2j|_CkeKpEY#L||tquEw|YH{Cqszn`r;(jKS zS~RF_o8q~F@^it*bEP0)u$+nojUrgHBsK-Bt(?rg0&TkWE1_fa z62dme?)BF`n47F)q%#r)mETwkO@klA^+E@W@>}brm#_&USP-v@qz#x|sF&9S(hequ z8tPeI7t3sRO=KlT*rR7}h;9VLMA&$%63*{lvIbt-s z@|H-d?uLmtSjry+(wSGaf1gT%KZ@l=g>OO2^fo|k|D0KRU65td);m_qY$r@BH+Qr( ze-i5pny3j&y}awA)iseQ_)RA1&(=vr4c96JCcWh^LYGw3Zbtd5#TiGc*XWpB{$}aC z*tytDNqOHB8BYMt9TJ-1$o*Y-sn{ZY@bl$;%c-*t`U^LQTIU1Nbk}2$>fGP{A@Z3R zIi)UU0s5!VLrLs$na7b-APvIWNwtY{TC030mhmEpBiktdrmR{u?(z`)&XKP2k#*7l zyMIJkShM^`XxlgfxEFDTr7ZNnK8=jUr-!sCrp5WrqUuLc73m1-6K=sUqn{A&ixFuw zN0gAxFS1iqY(sa2a134ka9Ke3te^*Y++(cQm|YeW%LK028o`b6_(Eby5D*Mia^r;s zmx{NjiQu$dL?mY%>d3X7HNB|V7P;5d;Bg*|mBj>44iM9Wc8q3VDHa#JyQ0ADy;!m@ z0V0c~SfQaqYojbFgw@`HKzM;567#8a^fppT$PktmOGzF(o&`{r5lOGNK3vkF9~cTR zE0`&oy~}XVifH-E38zUTkzmX67LSdg!z~)xJqOxNNHyV%2}LeO94?d&t|*u{4W`nM zCH<&ajwfOZIDbTPD~n~KmJTD4uVOi~5n!dxnY60F?lIS$ND+KyHK7gS!+BkAS)KBD z5*{3(3sR;vtkQ@oov0PdnwC?26U-OTT0+A)qOg=8Yl|cq!ZOh*TSw&dm>q_^vNc>+ zaI4hk;;duR1YJgvi}^#EY?029uQqyFSzojkTqE|17}bVv=mw$(#^Hsd({P7*Cv9Ux z@id)8ae2P7};)WO-%6R zkcRu`l+CQNXY5$?-n?^jfh02>8kMlPwh&r0x>sPAkksUI-BNsN^ur$GQL+_CZO1(F zIuO_+s>5V=%*+#f8zZwyEHXI8|REXzOJR zCRu5RNd1eP2rkzoyIhT9A5Hehyi&$(Zi+3;%@*``2pf;7f_OYS5<{dqnP!>zr0yy? z5yoP=?X+TY5j<-Q3#V=rxf%Yje5^z6)0mfzm6<+%d}WwYMPwc;+gkDEyPVmyU4GR`~LAOXqc3p!D}W>AtHt$29O1@ZLsrAFq_C_9Nyhhw7PKWG1hEmMq zzU>x;IMBablpoVwpLCKjxg;w(spfa*6Vx9$$r z9d|TN5ZXWA0XG;pvJ(Yv$Tg8M!c@jiJPFWr({d4`r^U(kIWYThXL3UhqRf1oV2Myj zxduGODMCwfVstQ$rtM0GHqh=JFnLS#h!tB3OB=m3js5VzEi}M@By094b`7p0^CR^M zZJiSUO+)zvxmzH%Za&D5@lw$*QVtZz@LVx5AhKNcK^Sm`21Sho5NihQw_3hY+1#z0VC$+YZ3vE>nB#ZhM!bMK_+#0!g z*i1^27;S=03n~}H*`mkiJCF35@|!Jnj@XRCNGFg+&~w2WGmDOr_&#kC zeQ};B5q2txDQE}BlpgEvbbu3c0KV6#Y~0wyj>@klkdkX4F7V+Mi?PpuUtFs@aiRSl z&IwCzV5a9?LdE%E$Q(}H_C;cqRf+La!AW8^M6vst`|5o`|xq?-l;p| z2B9^RRB}PzNUL#p*IZ_DB`kn9*`xLoCLZ!S;(Bwl*mC(4sXIREQ{SlEXya24#mD^X zV6M^vT%YKFi%4l=xrOu%xwQ~Q9y-ADpj8vvGG7(J~>! zXTT!0;!z+=b!gf_g8-T02L7~QH-l&IB-xc7^TBm;ju7NfrPKUlQD~yN68xjysyr%DLYVsnq5?A#!qlFhm$3fbI1au{u!G z=ggTEPueb3;c$D274$msl-L@{nr2jEI>B)YzA9d)jrBkt`Y{) z9?~H{Berdw7~TM_nLxSWK|}Cn`mR9b#8{YSlV<@M50xtlOdB`Bb0WJG-NqRhZa2Q? zQ(NZ(sn*BJ$_qU&cxJw0j@^mxi};pIizNL@HPg$KABZat=Qfy(4FV zWkfQjc!AJ1`91t1EBj-CvIBNV`Gh_%P<#6rQ?&GX5p_ z*ncZ0C4*eN*1!Ez#Z6#~7?Vr*k5DD`#WvqWh54%UK`Qja>SOV0+Ko=#Eii2p3t}02 zyrpEbS`n5P&oki_bGM)u>xpH35E(q}V12F1X%frXtLg)=Au;czyuQ4B-%`;r3FA;p z+-j^~?@AofVj()zNQxEh`;l56vNKHLIvFe3@3(nA5OdiMD+^QtUIH&;6`Liq5e?a- zOo2el%xR;C@gBh>0pi|s^J5#Eb)_{~ zTwFaTVq3AAx4z+_0o<%(JE0=)9kKx7QYKIZVX&?>V+Y%1PDW-yS!TPW_+C^5T$DSB zl&xx#k_R}G36u+3W|n8i?jlr)W10j!GKo~y*;TN(c5hO*VGQdeFJ7}AZFTg^PD_FDDYE?S@s(5D$U8Uh!1JZ7Mt1S zG!!c5_*jYSFh?=hW|i(vjR{uLm?u^*-OnoGgg#%SBvWiPq-5K@0BN)882zvJ5GpD_ z`D4?yW>&d1E@Gh#2ArZkkYvQfCWprL!)XSdYY z;SPsw5Vd})n)dMz2Nc^-onv32QfSYdKQs2T`KcUEH65m!PV6tXUCtaTt0v3zMv)tH zoNli;0I0EjiIS`WoCAkvyB~~(?W41;b3+_zyTUP1k77xi9Erok z>J(DAI}W#5rBum6$=!N{K-ncQ6n4floB5G~GnP(+x%H0{c_u%OvXw&y_Q`fNrnyS@t4Oc{s;V(Zqu(BjTyr|T!#FZ{*iwfhbFK^2KIVJrr~ zbzfAeJ!{t77_?tqD_DN5zMHA77YbLH2L?z?$tuocNOaTg{^9+GZC6Yj4w`I2vnY%R zo}QhCKYupioVII|$vqmr9__-G<0TfL*hlvzFqJb(?mOQU`gW>dWvpFd4S>-Ik-Cx0 zAy7eh9l*vRb?+}_VVr_-J0G6&%ug~^69N@0f%`M_lupr$e0-U%+zSmKh{YoBt`(=s z+$5LbX+C;zZb1m&q^(aLkPYi68o^X+*Y1|}F`G|mvYv=As9oA&J@ zrH`ku6xZfE1gdz$yy^4fOq++~T0;sX!05TeifO@Clk0i5(4X>EG6i0oBQPz0i8|S4 z4Lnz5&0LV_GYPFb&-M}B_S~8APTO;Gh=IX{%_VWZK>1e?Ak6PxAW$yc((I{^x8g#f zim*cr=AfvDdlz71^Df6gwaZGDb&*|H&GC)*BfXlyth~WFJg8q%iT57S?(sDHbzCg) z$K2WYMcD_{E`>gYm#+=4(5ejyTJm1t#*TGkQT2p7q80D6>t4C57EExX=ka^L;6^z? z1pJMVaPm@-uD2aAUih7k#s|bI^>p7ty$&uDsL+3^QDE@X;&-`VdCHSWL&prVt%*I9 zUx!u*fjO0WSBS1(I-LdaAzF<;cL{h~{}c$#m3Ap|gi&j>lina#3078Zn54{YeYH^8 zme|)B)OC%}n)#tUd=ma47>hqFSXqQPnU*MtYlX^k3s>Hk2^k;`AE^;lb@q)Ku$TAK zb)r|~y1_T|wbuhQdP*COk1~-0H`ryX{9TftjuJ!%zj>ozO^OaL1LRqao5aeE8VLv0 z#?6j}Tdpi<5Bd(SmezQD)NXY`E6Rx*i6m^I6#Ha&I3k;j#hpTx&rttvv^8k`KQ7qKRKm^7 z?A=v}TrHRBaNKRXR7mK~)bZRSvT7bQX?lEucH`12r<<{1EQ{Vzaj$<^Tzi)g>L!`j z<31lgDIXqaqx8Dp_T_cuTX)kN?UOz?yGU1sr#xV<%Dgv1&Xosko|v~VZk1|C;!{Gk zk5Q9hM^eUpNU%zn4PhMMd*flDO6j66np6IW&?rs)db9@zj%Fv$%Qg80O zz|RiHWA@o1pIStPcKp0PW0$o{dPc2mp5D*e>9!mQH<0wv_?*yg`5X*BggvH2s%Ro2 zH`fMiCjMT%@p=DnV2R5_*Xw=Hc70rQ#k^Mkr@JKN3;t#Kyc`Xc?`A(nB?jKuxCp;n z237u-gzheqHb#Z8@~;1~D0xkm=Oa-GETRy|6GBUQvee`v)_nz#+-F|4^XAQrCvBdb z&H2-3##1)O>vo?xExzgqzwau&XU~kU**?CG2)ZOlg4gTUedwdP4-lLB@JDXNH^lbH zx54chmyGzP&z@Oh89MPT+kdKrbY{u0h}qL(r(X#3?{nCb9HKcU&!vi57+2*QY; z+M^0@;5kIBgh%UVf|dPjg!(-3bK7NM#Av4N@FkJ^bKqvD6))RtC582OJMjyF1^KqJ zzs%q-MM}U(m(a2JmB=Y|sUc#TPO%fe7F@0_9YS@;PUv3wjpzfcKI4u_f(<6z~?DRxeS?DEMNy`6b zw+i+maXE#8{$9ZHya#qGjGOTfkt$_^m@f7Dr^s448EDk-*8CShV~r{nn9E=*0 zq)&W}KvCA7iT-|f&ay%kdXkoBWr|o%uzWeO+GX;f<%PDcv7$X|TC5<@Wv&-a-v6H?XqEq1h2VKHev=i!9Z0ocZ%iwqHh0#HSjT>&`DQa`&5CtxR{AXDO&s;yQ?Z`tKyIlfHF9Eo z+ojZ-hfDSbHk)ORg{yB$io#W7)z# zy;N_E3&KRueT?5w8IRka)K zEOdDlHB}L-^&@uixwCR|$x#N^w5z~MIqodX2qbtA8oHs9~`{#4> zWi1?20Zuan-Te_SFCKM@KT5isD^OFWGZL-r&3ZFT*T_n0co66 zSt#^QqigXObM1O!{xpGUq>I2f$)&f-JR`a%{+ z=`#?A2>-YwM6?mcO!{z9Qj}Buo})JlE%i-C0S|+L$*mz;T6xTUecZH%I@rF&*YPO& zDf=B}zsfO{0n*+3;Beu;=Su5@4$8(oLU3-rIYCr|#27^!S`UKvbQv=a$p>c@?K#gx!++_Mxo3^LlekBnO z5nxURaqI_TRf(*p-9zSwe%$Y3P_)b{Gv`oj(`McO3)@&uhiq?`L}?Dj`(c|E>o`Wf z1D+oNX?&|2jg6oUr4X0yU;jpj-({g?pM1>9?3lh1#MFeyi1^>DC`s$*?uyoo0;L_d$&N@lBQ3eJuBX0 zyK0wCpHA4@#kNn)cO1nYiKA6qBJ}nA7UV66HP^#?!5YK$Hs}Cg9eKs~33h##(T)sr zlHTvLRjvaTpTjRhf2rX9IiP9jQfT>rSWzRsnCd8)^ez*-BKtvzdhlEyj?2Z4uak?* z%W!;9pi&_60dwOD+Xv-tz|u1rAENEm=JiAQG^2@Hai!q9x|>c<7~U9a9E}f+jH0a;px-4GOx8=@jFm4g8$q1M;ufK!a|R)`m5KRQvGZ#k zu*VL^Z30CvDN4vmzr6rCyeuzaXl~pgxK<8@ajSoTLUnPcSou_8HXkNZG~(l6jVG5< z*3Q6UdFH$9SaPK)9r`kf&E0}!{Nny(c}#vces%B&Xv2icYXQf5SxH9!q~Q9g@F7Pj63r_~FdpzP>(=U^D}*Mx)gBZr z&6LSXSe#FRG~T~VscC!TA)A|&nupV`mg8ZeAJ*5i@>)W?6G)UsGW1Fk11W_3qs`(2(255FWUZN zuEM-Iv*SxPi~Qgm0l&03zARK~L*xX)6i8JjRJGB{wwkKAuZULNLZk_kyNxhyPl{Gp zeSecw-tc%&33WvyqT_RKeO0Ui3|o^B(y!6hOGh=8dR3^h9O>8X_J{8NWq4d};~RFx zxn?c8{_h+Y1OH8*cyG=D`&B_Xz9lr7kcD=QE_vE9jw^yWcUgNMn^!!6YBiB$WxiV|Fafo&kw))GvyZ)d&dzR{SRd+tnPfKwPw% zOnxf5O)e7~v4YQk24)cd3M>;pOW*PMx&3~fA7(%*YLWJWcu8H4%;CEsb(_oUI&y2+tl4cfH_ zq>~DoHT&UtDMsG_LGlewH89hkb*v z2Nrx4!AjZUm!qYm=c<59O%Mo4MoO<{zsdpxlLte`3#=|yPGmAjJt#RwV~qlpKJn{; zRK=Pil@s0jklH@zJ=YT4C%*>&iL_3x4b)hzxDPB>L}}XR+U}+@p)We-b?mf3DT-#I zqgvPY`%5HbtK$g>SI)Gq=d+ciZioZ9FxD4XIp;-XGBM#3IwSG58#n|9U#YSb##OF( zL!a2Ov?yfT=NxThPl8-lq^Dl;s>5PqyB%Na(wA;zv58POD?^(!QqZAIg(_w!&oX3w zGokhJYWwk7_r~TlRe8CQNS{wS7icDxKkZdIj_y?-TL`^Ak1{c?IGNe5s(CXprEg{P zGf82+RVQO>fX2=xbIss(-p2Os^%)!hoswFytxtWeHXS3=+BVSZkXm?q zk(+9=tbM`7XU83c*U!mP?Sg;Mjv{wwMW2|+|_QCKLAk)?w`-zO>F;sV{TxW%G|rtL`$P@y0FY~G+nGqEhZ4ejmw)M zwtH;A6KV#2vB3iWs}>=&>QaeZjcpw z=1o3Op-zYrNbpe6H~R#&%hM5vJ%pxCWY>z3fzQpl(uewFGe3#b5r^5lt4qHYA*oRy zRA`eN2A5M_`3QmEW*;<&ElK8)LZ#m5q|5zL0#D^89*5yT$u^0)>1fdsmM|j2n;j!i zfuO7eV;>8!G@*b+mpWKQ-cnB`OUfG|?X;m!$B9;46dnnzxXQh^3f^CYth`!UalBYr z3VU%hB_HVtBDd!UluD@+Cjwb`U2Yw##oq%SrJ=PE4QJ;rSfbldgjcL_SgP#f0PdH98dig7@a5yut`Xs1pNXm()QuVWCys8H8kYVOQg(Y9UjHY51pjoI8h=dn3w#@sm7cHP9}X`LJH zsH}U(_UZXSmS^c<^-wyDih8>#7-o)A&w1mL|X$?Bci1x9{4oaLzoAwcrB5 zM%R*pAW1-`&;Bj9D;e1sE?w<-w`1K@ngKlIj4OMO zeJToXnD|V7@M4jLIlMuOnU3%hv1z#z77>~R&9=hLdqqnzZC>5P-X~Txft_kp_4`FO z&WY-!(D$&WjJQ;A^BfQ>1l(25=?6fKX{@C7%iO_-#^v@qtoreA zimLHJ`;~_TN+9WHTp_edZVFgx$_dymC3QbCQXac2#qLQW40D2q)KvndK-HU>B*F%Q zUoBc3n%*CJ>Rbb)&ybW2rGNS^eAsSP7KW7cL{uwMUMqM@&Hxoa#))8tHT;NR)tu?= zU{<=$c9roWpECT$^#Dt&#N)P)LgWUKu91W?7U;-s^r2mAzmdR=rN2pJEN74~4tO%u z6E}+;m7mz(^oV^_pwc1g5e4TWRsNXh&9x?$ZzTybXZse>3Iwr?NZd->GT`X~hx(*R zY0HVY&0fVEkzHXCHBsYsp(@*fQWotr>S*FMMOUmh#&w*DxYGf*E;bgvXmsj&+$D(E zwBtS5v8TPHgVF6Sks>@wNLab!ZlQVE$?VKfi+e=2@2aQZRYx;{3k*qo!oO6Zt%c-; z)X)E3p-q#PxF7H(NY?Z|;nQj&Sgff#@oXcS6ST2u_m0O9Y#p&r+H;$n3sk}E0gb5- z*m3LbF@`5hUg$x4mbrwKH1R2$6$FLLOr9QA;33fxNG<270rX*^il^i4#;0yYZzptD zE+cJ}$Wfs?I972-d`_%t7x(u<-==Jr8L+p_jEu+UMY_9<9-VkxU{-1;cj=8U z*jh8+9tobC>x%*v8QfmLue9PzA{9e#OmOE@LQyI*6PQ%v3Hy~`zM#+gnf%yS z#OjZfb72c4vbuzv# zQc=m%=ggQ!eF1^l`Bci25XWxJFtCFO}~Imzyu^3hVJ*f!%Y*LY=aV4Bzss=$W|zQV=1{J{3X* z=jEbW5EmLnbpf%Xb4?(fNKelTygScTiyMY@|Gvmdc@OsD6E{(5s$h^`@DG*in#yqq z$&B~|vGU=q%t4*_p-?5L>m!M`(e{)F1=N70>`#P(73+Uo{VblL@Pm_q76bHj;w9?0 z7O>7gvE9|%QM#}%e(G2klxN4h>9gZ!w(*LTxs{ABcC&Zl=RQ|i58!Mm3KuWg@t7jx z!)$*O^}cMc*XD$fBb7by3xTzAD*1Avli8Q?OTkA=Xqh`Ver5A*MX@ME$~693TG2Si7-GG}LH3jThB1hWIh+F!L-LToaD%gsg+`roE zefc1jHetJ3@qhOE@-j(jK`J{F*CJo^H+zrduTwq`K@=FJoap^IDk^tl!~WqAt)l4U z$w!czjDLzPS4W`7EQ$Z}vGwx{;cC!#Rh5H(3s<@c1g_y0l#q~4!3r(I^*&zpE}E~) z^=YDgd9}?|k`DFm63f_{mVcZ#V`jX@W>KxVv!@{zFDpaM^q7*-zAw6a|*;ue1c zq%Ey0tJt%fIT7JL)#$6*@w(h!1Y~3FTTP(S+K>tjc2$zLy5Nnuc&MncwhqS{LVryn zkhVaD&o#l6KZ^L^$-9=F?#WK(gHGzPw%7r+`ts} z^SGR{jKlB5dLobIGwN$)o7WdwEjJ8z63!l(zH$T6V*KY}NZ!!q8MzUp4Cv*V+D>dF zyj{B8{m%(N%O-wA{xFIpHIkc%?3~|&2Sw&5j!nf%S3@ir!l}ys%>;Y%b%c*tFe5u88bVvz0Ha$#k6jEksU;; z1l8yY27gTl7$DSP!Q?gl2SK3X4tT#!I(@H7^AAArU{F+iQ6Ne#dI+UIrI zN1vR&*iWFQ#E^ykePp}hLCBxiR(XQScV_MY>iovxb~&-cLPkdE z!&W`QK3n7)k6Tubp^miQ6KmwME*xLn8%GJ8SDu#BXLaIepDD%{oehZ$FgYC~R_1Z1 z68Ew=R;Wz8xPi3eEw*2u1O}4tLFtd<#44FF!S`yS+woShHEXt6HWUxy$BUL^G}Pp< zPsRx%wY)CUWSl6lZSJC8vf;5FC)Go4(0&|g;$+)p?3h1oPQ1-#PfpMrc%oBmmQ2O9 zZpwxxNMo(Kf5<;iZj&V_dhE7(F2?8Xjb2;*ImT=Z>Mfg}%9pRAGhO~!Scm(ZhP_E4@O(0 ztcBx*m`p60h%up!^PAf&<*7Ee$o(?jdHnVW+vOKQtQb|nxU@TBC3xuls4;k4X!$zR zO=2rz0ze|;a$&enb0+9=HD~^&F-zs99xC=!e&ktn=^=m{u2G%&Y zZUO>QT5*w`O82KT92@D~HJD6q3TtF4^Px+MUFHYj3_5YK*y&v*GCV%cY(7`E*RZH5 z7Z$ViUeTIu#2Pj55%2R^q&v+9sA~Al_uK2#+z!LuhL_r|i(?6@c)#WYLfhuSf^$QL z5xmTij;N8mU^;QR-Dc-UQ}rg5jPXISqI|7MycSTOUm?_0`=$ipXde>nDi3&jzaXv@ zdn|uev!V+6PFy8e%o0g)kV%x`t`^)ge_1jquOHWlEv`@q1URA}F;T%ke^|Uyk1UuN znwW&P#lH()Zzx zF&H=6EdC((|Zgvyv!^U37hEOvT+ET>{%aDe&<@lnBYcgq>bAl8owmf&rEqJg*t zz+BjF8y+K8BW|@%6$~a{9y=nPc5f5iH2Yz1ZenD;U8D#`dyFV(UgQp;FVv>zj^Qot z6e&Zb!+0^o$Hl73TDN49a{XPPjdzs+5HCKjEz;`VZQn|QgbAbxi*S#~E0L5MUwD^K z2=?V78deBT-idp~*2@*h(onq3eL__)h=WSzT@Gq9?iVd*aqB@D=-dr>f z2vvZ0s}F;ACms|zv^GDp6rZyF$NKnzK8y1`Byw=RL5K5gO1y`KDwvC;&iXz)BJ!T> zWDZq1k4J?n$FZ5__^nTiY?zcH{r8$|7j$8ujiYMuJa3Hl89T0>LIw$UbOg^Twx1O) zWl{1i3T15e&pE)$%jSi~DVeg@+IBPy>vyz#PwTGr|<$%OfV2zt9PGj!08Sz#7j3&*RK5Gs<^w$K|&Sjf7pZ3>n z-lkL$V!!f=s zR9+cyr4Z3)eC+V9bzLuUs3bYg>~=@KgjHpk^zVw4iY^NU$Fl-uuc1r>$Bn3kcuw$? ze2#_Dkn%l{#swwiaizrb_IRK!*5(on`QNw0-qoSi-y1L3p=yPUPN0hWf$h2ZK!3E! z9Qs2a*t4q+Mnjs1>qmk;b+;&Pv?fq}`DBF-CnfER7e)5TW7+M5;!Es>d}X){6X5>T zu^z0_E~M17_6Jd&f|u3aUSI%X#LtDg_Zgx~610~btyY_BK3=x@T>jvKi6u+4RmCsF z%0B{Q0UHIm=$B%<=MIFsz}#)!?_UW%Uz3Rv8tV9Kkq2@^r#_50o!C_$Kv+_>*sId)7Qc%k6ZX31UJmxMZVjy z_#^GcVXscU5VD|vP9A%E{>h$Qsj)R9{%o_-Y$14(lZ*fVB3Ah?;YR-IP%OAi+YtJI z_&@)Acel;9{hJ*K{P7NuD4|08yIqRK(b)`Dm%tbEOrX0P(Z!CN_n)FC<+tIG377CM zfuaBlEI-Aa`EQ{Mb4mCLDcorMN325HF@)gq7O%R9cj$(8BV~9ozgnnKWWwE(+TK`3 zl!@_W+249dy#|P5w-SieNQ(tr)_!wp*Afw``!V`2d-mtE6Qfx?YI%{$I

VAe|*w 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

9bq@fDA+%J*18BXW`TRZ+7`4{Ik{ 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


A|8zO20! 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�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

{}#$}zjfnw~glC%3}FlgcG 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 z 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

V*ysB5Pl? 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

    &zg-Z-xeOU%Or5h9KD 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ⅇ= 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 Oy0%+HHvYr!4j>O_vb4C#Z%*&V45KC`|kp0()! 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�l7?jxRUa)7m#Aet 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

      pcuHIJ*N9$~L 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

      oAZ`2Iy7;B>rS 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≧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

      kS26{%=m15 zQYaf!(FP~@r-C?Ovvb&y)J6xGjBU2|1Ze76{A>_VFk1$ts&n&;$N8@5h5B^Y(pdis z^%;Sjq+2JJ*`}Wj;Eo(a7+ar9*$&2Lx7X+QEl$-JEM}1zy{IW_9RDw-T07@f#;}TP zF*d#w)G2jEjP>+=I4@lYa;GH-%sPAM%Ys*Hbb!Nk+fnrufoucJT)BY31l3p5-=%2! zh1b;AEX7TO{R@jkak}PG_a}>Kh`_(=GSr$lBV~APFOv&-#`~p2e=8b=OVT zw*}+5w?gor@1*DlLWB+Js;TXF)6%u$F~U^U_k?oEM*M=r80)e6zF_Eq>y?)E1EJ6Z z(zf@xGGGz-!!))(#K_ZVx9Uei2Q?u8!Ci>7fk2~voc^3NV$Mv~Pg1tsS`Te7oB5~d z$|_u@5vrx^z`&6&Y<#rN7l~9z3sDsx7X)&Dpdy-XwC6&xTquqCib`<0E(+F&CAZjs zKNn0WpP4nR`R1(o3&F4ogr!QwUy4O7F<61Y{8h@XcQp%0)dVtS>t3dQV|iqtfFwdz z`nQ3kYE7byrJEH($2Xa2@%WKl>54k?~cTJ!uRh=Y!O8-dy^kCdMT047jdD)^~$xF!&( zt?L63vkT+zB5`IUkuwYJA6*p!^dj}Be~M%|A)3?`ss6Q3rG<^t8N`1F@k_Y2cuAz? ze*(Ht&?cd-pQ--_x|mDTwQr*SCz{34V;-eumsn{~RuD-yXX}z8AzfpHBwbmrONoTM z7&E$Gmkuy$L}=5xj7TQ4j}A%+%4O3}TTa+Nllca_iOUH_jfuq%QH}5oyu4W63V+!J zB|ZCf5Q>r$ab~Xlg>p9b$CuPkTp^Wwi+R#9!J!=x#FdU>XLiLvL59TgvMQLZWKj7&m(eI;wW?3>Dbx8Uv|ACt61YYaiNEeo|LSGm#ZzO0CpYgS1V~ z)!bxdb+uqVv4@!$t~UfMySiWq?2ycGNCjYSjugz2ULYFVN?k+XhE0%xRT@4^22iSN zrmc@fTE0l2n`?U{Tl@E>6{%VZM>mK%cPoizvWO1atTb^7(6f$3%Q^lFqUzfKT z))uj>K^@Tum^E2jQ?K<;w(eZDwh8VvJK|#)n(abaabvi3uA2{WhgirJzI2eHqXaUf zSohC!`qj}wk)$9po;(=~J(2Dd&|w-w)=TyhoJYk*%J@Z$ zAX#O1Ni`S7%-jED|JU^^}_ zj}yz{O`_(ee0+RrdeU#%vU#kY(6z+RpDP**=80lC46(_8@;*r*ms?!%(BJh^qb(^^ zGV3%NOGiosVXt|qX~UbaNyodo1LW(v+fN9^JRG&+D(T_c1D#5wSyG@D;%X{gIz~i5 zVIx7mrh~b1_2Zi%S5j*$G1_|cjxoZA&x%ApNfAHM)bNw1Ckfp+zfXA#V!B{C!9)01 zIOz#{=?C>eV>1LSsDZ#J_K-=H*{hh%E~YadPb(zOwG_m|fKa*mpL?0ynbv+HvCg<= zFw&^kN;q*ek!^JNFx4f#>`smQ(P0vmV!4*{i`^qcAa++XNnH`m0?+`zsm*qYg@ql} zL}HhE+M(!N#H&zs!l>fR+3qxGLLUo@47N>B_ep+jHzs&-e&Y`xon}L7SoVOzk{{=qXFjK%mfsw2u2*#N zbb&C73mAQQTYE<8xFE)-erCKDIZc+>{N82W6}+U!E#M##F8%>fCeGSb2|)^C|l0d^TZP3d!a|*FQDhAH&^1A z@sM6%Iig%xMN`;J)(gcR)`k`vO9LpJATp904G?!t){8_kG|b!r*XVk&P$rx7^TuPD zt(S=9phBSxJ$-2^Il(Pu16MM3Kq-!W+d#TL->|@t|NRnH5s1e&i%IZ=j+1Ds?MsDQn5W&2R5sn z++hfHmUbC;=j~#bZAl%uhRhp16KiEh>K&==NMSaHrO-PCax$T-TC7u2p^-T%)Vosl z-MEdhr!c?7p){yp#)e!bvJph=-Ca`@2Y8gGtd;_PAKAx*0Y--_y`A+Qe~LM$K1;g^ z??*7^darOSXh`|UeW2ba5;qGzfY{abevyQ$Sf3@z(g!S$r12QtVOu#}r;BCAI9?YG zvh+cr9Cn03iD6%RHA-3{Wvm2BH6sTKGIbf_6RX zm9j&!GKl~7be$d0PG@EpF}D7wK;8^x2J*Ir`dHV{%Qdn#_U1VOUE|f;v3dJUeO%xY#2rXJ?`-$Zn3r7xr&`RDL|v)-~pyN*Wc(fi52ik<>3c@>K9~ zCiMzi|Ndo5|76TpTJ#z4RW|?q^PAok`nkLM_vF-TZ2tRr$d>{2J~q=*um7`zjJ}-4 zR}oWhu=Q_j`KJ1`)SGPl`NA8cMo;~FioR6y_}?}~>W8f8f2O9TKKZwmKJ14k@saiE zza8E>{6JH_2UeepK4bUaKMW{VYts?D{_v`Y)Y&YLxm_`0u|Um)9@jtC0E)8*WH>{Z`Eiso(Wz%!_F9DG&71CZpJL5x8Z0u(p$_ZXyi0Xm@P8uvzKDP8-d|t^e`vu zOU%YJGpGJAE3$dPyu%+$jao*yvDmcdVWM%*Y^{aqE-8#QMtS3kX~nZ2P#2TxW(7jn z0wvfTj_F+^*oZYA8mo-CW;KqE0b6lMF)txYx0S7p%W^PglqnqhT z;5tBU0{aV$UB)-_7hA{K%7>w!QOC@pPp8d}3Ssm&3lLTe zQ%A;na}Z1i1IILi=5Qjm#346ENvuw=s;gqmSDemf?Pe~ z9*rhOJu@p$;ZXH3_L}psY7Vqj`DP^oIYPn#v!3i#$t$Rc$tE?&%ty%4JXR&hHPfHn z_H6XWr<~4>KV}Xh#R!Z5vmuAxs>R?{6f z>yqoSc^w}YW@NJY9!ZA~x*Hn{&97{}#&_h`?UX?|9IV}s#q79(mPewVZ|8ku)k=fbljN2_=|0p%33*5n`$2V+@< zvx;UYK0yLOn=1gdiyl~4J+%rw>^)Y;Ljfms=bBo?pdq}`!& zb>3jHWCDK_P7{ARg1avS@P;xW&4ZLiywG%62l9^DLBmDe1 zcOYRYj^>*;FzdpuEvqcRWFFtBQsb(5lvpq6pgjzqaqiAuRg8WR^C|pJ02xsyfanE) zSnSr}7K9Sz@z~Dl0IQ=^xe^mw_VNIWh&P?pVkI(48x4#-=26{t(~tSJpwf><1>?K9 z3d`k)J_K?t;q^`m7$?o&>~>(c2}bu=UE|#3U<}N9u?m94Z8Y>Y2Wf32m~Dz`s~NV} zINSldUeGy266g5U*7eJggoE9QaeRC{F zHdIsD9L(Vbf>>c&Se%XbrUMZST;e&3Lf$%B8QaavtoxGC8@Ni5(-^Sk=16@IGC%qV zO2B#$TzoK^N@!mkXQO5xa#q3d0;~4WdBy4ZLV|%D+LnbRkysQWaV*e}#}U%N%)?^_U^8IHkbQtmQxY#z6yu;d5%W4E-pfal zO=b})K8V9YcF%EcK<7Dhyl|}v_;PxUQy*eZ0SxvQLvH~P1iiID6AD~yt`ljathtxg zOxC`UX67PvZ>R-O_}5~B7+#R^Kq_SHodubRUzu3;@OVe20hF-F{0NCQMFaymS^+z| zban-`nn9Bva4-u|N>W)09;4XXfQ&cDT#$o|&@KnP-Q;UUl>NY5qI}TGur*t8)CejM z@gBvh17(cm@hEY+5obB(E6o>dG$Lae9Nz;6DbAJRropy4r>EfK&cO}#ym7k=IHX5} z#btCliSZp0Oomi2Zu8iC%jz-*aS$m%RcATKPNEmAp5bv-2S#f%fQV<j=M z06lxmy27FmT5JIZVriwo#so7MBWE@W0e@146#KRXD%IRq0`E$Yi2zoO; zDDg%DHh4H;e3q;IhEP*E2qW7$vK=FeGka~2um**d#4Q!K&gj^T$IV23%!iWZX!D-O zU+KfiY7UV*5NZLTz7VPmZnGfn#fx<(QdHsb1hq}Wq$kD^Bsz+38$yl4?h>bkIM|Iz z6mC0ttVW`qJYIw8b?o*)qaSb)F}|6pFoq$9hgLbNZKlUSoBby*N&b6Y4M?j^bbpHJh;ZfSxZfNajXyvj~Ie zVm`$$8#%X=Jrl*3B}C?DB_5mdQsj3HdcOYeh z+vU=NR;-4T)SiPoJQl)kKLG+rK87JXMc(}69RkuzIwq}%G8B^)?DfOf8ZHmLK<8}sl=HOeHM|T2z z#-lj(Rwhb*4%)ESkzzU$J{wH!IEX@$c%VIf@+OfrZiV1{7X4b`RvP0xgdc}EjWE7K z-ZA)Y1R9XzA#R(n>&81Wx}@MHk8=pRoOq6y93ozSLS^Nk69JY}*0E-SPw*SVV>>h$ z1FPxKIKyK$m0;8~^*4E4DWEPj&1UzDxe8L>F{=rm1_)G%w2e8KK#*+Y?m-hS@d17` zAyOfA4>*p=QhaTo*Q&H2BlK!PD&AhumQGy8xGO>55dJDAUaaoG<`k!Q@u}h@jU9dXWQbe6PW(0Wco75LR93V?9SfRZJ`uz_@O1#PI9vP_R4N(>_>TOhu(aLO4M(d@tGZ%6Mij8sG90REjq?p7i z2X%W;_jRIgRx)F(8BJZ*BnjcZPvyKjnX==!8=unf=nUi{@f#mGJ}|RV<9U2~L;E(4 zE8GMw5WC3ZAoNY6+M7JOz~U_Vx-(YU+55yQ6Jhg1>Im@`@wk-7xp+JQ5{VKGuV>7! z2dCo+)eJ#w*c*`EVfGqgXAnM_*6p$vG~u8OOfT}mWgxv8i+VO@AiD!-KqEqoD=m0S z;aQkH3n(4u;54hRienTueIO7`?uW=e1&%?K`-zOzs49u*!^||vWfmh`2F~*`{6!&n znCR=A1f2=yM2JB+KE^H|B0PljV@e;uUQVm z2|oyr#`L)l^@kB}6R-qAjY(ddL^IhN#pmLV1h8XtKM?e_G&Xja$5?lx=H19~nsYD0 z9)MhL#xImOC7c8;$Xo>Na^ThpyVBVGW^XmC^W=L3O;1F5XeTJbs;a->E++Gx1rbF4 zO60Y?#RgMxac=ipa$F!@_ws@)uxd=PuQ>P$zvD>u9|v{WyMnY^fEkp%Q^}11W+sRv z;OIw|;Y@LM&aV6)+-}Ha zgwlK_`iJT_lFbt`GX68|$=Ct^L)hLVV-z(^#h$% zQg5?biQ5&T0E5Vpf7=MttkAmw?tbJSNG`7-i-S)OrIOX=Mb(@a|9gp6nGN z-%NW!Hy&RhWf7EpNJFM`ItJs-tQKNd7L)(TQi9>DfgTq4)}WjY81JHDFUYNCFA3vj zDASeXOWE7PHIE|b1$4VdZ@UocDCPXb!-r56ps@|Rz3icd1an#y z0U|h9P536P9$|ci*?mc<$8myV9IT-A^+}!+x<8>Chejj)ku@|9G#vRi~ zS&YVJcgmRVAm|O{b==Md&^rl>YiRR|w3l(6<|SxHo&n71UME3WD0g9Xmcqkm@N$9i z%8Vy$Rhm7NES0Ds6MRczRGx^1N&3Y@kmxF?PKexGwihsW;Pf?bh{5EWNSS>&s6$W> zGS5JSK-`KlWUW{Y#UqWX*CGA^dgj7`B?0VUkb~-?F*%H4{RvtLk}F_UjK_T8f=C!- z;h>d#_=n>&4s0yq6yvANcs^Vy~8s-H^bqsQ~pxK$WA0^9F%=4i_Ls<8O%}P#3 zbJ~-6-OApw(hBy*yiP&Q3E@myXHUUCD7S^43kLyY@n!ELkHuUB<=M*$<*AI19|zm1 z>OQF|lRg@O?qZV4UJl>}L08f5bwH@Iz>c=|#rG!U-XLT@jNd`%E#)J1&<#Q zyb9I5WK70m?7@L8;b(AKio6|Ab98!lpgWTZ*udD01}c+iA9gVWSW1os9K}d2Bheho;VjB+ zMY4m0n}Y-yXzLjs7eRgox+Xy29z>gwA`O#@(DP zA7*o4_8(=2v)7wf_+Dbyhpjy(QAo3!``-eSRK#q+X*37ty#>}J@*&g+Jhl^WE*;9{ z&k9-IGIPV~2%IpUiKy|WB_Voo=NjTT#6jReCG!IWc9h;(LvN-r5%ZB~A|A__p%)Z( z5VuY|2GXA|?A;^Eb?U4H&HSW4gQ$tz$cya+#dwwMrJOC8#6c;UUVOsXiBKI0`iq*n zV7C>!6>ymagGY3JBTCoC*U43oo2GxJ1;;qeM}P!sE6YJ6qEy893CRzoM?vYuaNY`M zUka>9^3JH0iSV!SU4fk)C6r+TMl&3nk_E9Soq=B8B5x?GAE*|F@jUE4!(||L{Lck5 zoV~$>|BOi(2bY+R4^q;oV(d1L63H4}n<$)7$!tJ{%VFt;b45m>7ZEPfmFc9rnm*B( z6yX)J5ZQV-3R;lUmKj+<4O@}JkpMX;&IO5PqQoiWJ&4;O(vM~}5sxDf>B=nGVpj$^ z4%!JmaoQR}bI9A6($CT0au_e+bQ;raL-O|6tzp%Rf-jP7HVjVSwh9;-ESN{BxoM^c zWwqhJle{0u`-fsi@c5eY#}jW>x}MC1FDc(4s;7L7b!I#rufs-79NUxGirRm$%7OVC zR-v$Iugpe>`J36;hy=|zdWWtBDB~L;u0Zb>8RLBgRdj09FrTn4L=R5^?;st3on>KW1+qi1q?4dHt`7Es)W(7q zPz_-cU4W#Tg3-{+1N{_|m7}{M5rQr3)x~2mM4egfA!Rj8eo(75iAK=z3LGpVs6Bgk z>EsG(&Q4WJ2(_N@zO=-f;U5Om2R4GX$g+z7CmaO>cq23n5ctBrI*A6-hBB;{uxIBX z$Xi~}wUS^M{5HD^3iBAj8@U2=T@@O4(Ru+426NgIU1~Bi`{4J3ls{q6i;lG;$_JXz zhnujB0GX-ic^Sbg`eX&a>BM`4bWPEvCtWN;sM5N>hP!zh4wVS8f(A9U6Lc#rXbbXV)2pNQzj)k*=~9v(;I8J!_XMq)!0A%rwZOO(s_w(L zLAtM(R_o}=eA6J&&LU6g(S=XV4!U$WNEbL8vgpl8iW2fo23fiR_k?P?`XJSlxzD26AjC z@)|=B58aWton+Map~iSTq8Z_(aCysVTRh$qU@LUb(XDt+r*rTpN#M)lYPxFWCfG>j zA!vFSLPPxoUvYC|1U@41RHkwbgm#mB2JJ3SwqMk{5XBwfavGCN%*HR07l89zOdb*b zG;=kD4%YM*Y)6uo)cXw$a#2S;9xD@mE~gY|+J5&+mp!^6)XRI-Mph5Ki^UCfa#b>!&}4o6(t7p80;$Wpw4g} zZxLz)wYMeZXzY4b5u{R4E=t&i@DHH-h|Wcjs4>*)VKNu??d=6?Sy{p*lA<^1)M#j0 zL--0D8jx=jAqJxG`AC5$38s)aKpivAm{aioYbPk{C`e{%Mlyw+uQ?r9Q^hYL{%27fyOfU-6K?MxbRyh%=y6P0O{7!oWMQK?ks3Tf+RYy&QZ{st~^Ec zThtVVWc*J>vjM>(RfMtMbb>&AB%K?sjXCBCs&;1J@&eaTEC;TA#ltvc{^2|qRWu;e zZbW|too___35B=xsuvXOn3zB0tk3&>9VSbl8iI#6<@JZaN)*k8-4uLXVE#5q@PoeG z;3A);hDbE4iPUK*wHaB@Leq(@1lY$x9rkXx3iJa7H0nG~X8gyq%7$BAs&j$R zF!t;j<}{fYoz1F^*bNdymKQuif?M>mFpm5_1oK^-zzf!e2|E{ZUD_JZ7`>_Ze^0<5KkC4{%4-sg1W zDd87VOhXE>lc@l$^&EG7u~TLYd)G zi7uQ$>_V9MVZ4t<9U|yqOnTGg8XPns#{*O=kK0NP7IA6p!UV2Wftj6w5alU)B_*WQ75pO9v zBcYy9+b9H^87er%;{*n76sv*UpN{zU$2d@084JuOaIHH!gQe%9%=nT-0fcTi5jIaMkK0zNIx2#!K@S8V+eGNW~{J7dR{L z5l?2ujgDDX6x^XjPQ+eJ(g?_X#&|24FA>{`u&wYIz(Etl*v;uO%Kb>C0~z*8JpN)3 zYY=ZOLy{3+A68Y6-iNUonod|?gqh2c=;cO12o2ukE~v!}B;i*-~)@_U=~~oFx4$9vhP73goP@bEfvc9)c!>IzXssd>x*tps5xxF0>n))DkakA`RzssrPbxiCiSRRMz8j)L)}1=mPW8*TbS#Kl2S zI8u<4gN59MB2;n?a$6DwOX$f&YQIHhPuwzdTAU`l;yUjvD+ocEWfWmh=OCmnh1*^7 zW}&9K_JVUH-@p*n3KqP@I11|Cbh{01Wx@q_FxkXj8G_D2va96;rzys+lAr-5Ke+<- zaE?@4j1T60b}zxY2m+nvl0TyfF63KB#m7;}AIGOi`kQV) zVg+po6~tp7dSZ)Rb2=MIp9+$4KC5Oh=tu2?u*=5?T_t6CsK>#o7-g3r-V`3QQDRJm%$HJY~&$}XL zh+r{q!dk>xNA0T^zlp@2$EZ0GaXpU(;M&VwFd0f?7`4Z!kU*#hNEU}=k+gn+hhP-L zIodlan-ixva zB3>%2y1<|g!jBJkIZ~6Oh2SpyyKqpuykIJO`x&OL5bDiTl;<%EGq@M_9jVhBE-_Wu zgV230#UDs+CwxIv*nwMfbzR?X_8Uo$(xRNGKK`KK6n(NpxmEa#Ct@CkBtKI)K3XsW za(@xLv#a1RG_QIHz7x9##U6yx7}`6R@O$wv>0*0~?=%;dDONq9BhY5(N>cHH94CQ6?CE z?>ODXQ0arn%f7D zB(8ZTn1*3|7B!k7SQwS>#JCJSvZ4zEXx>3f!AfWxhDLqVxK1&PNomEwhx8TMYNJpU zq}#^o6p0*2G!``+=t4hoxF-u<(EYDYg4y)#G>=zY1%4!N%_@z02U1`FBr_A>B4h22 zrf+-&*CDOlXik&B$-OKxb&d`<}+MlAoL5mHPE23kKhy{7GwlI zGS8i0^_}wFNI8n-M zCthK+ddq3%@`BQ=Qi;-mcxMsk8S%=|%a4@x18?Px4sTCC68#{2 zYkVi++n3YH3|B@1M6oxY@R=#0I#F_j3fiN=4TyJz+F!2yCKS(1^6xaI6C|He^nJqL zA!Qv`!As&*XW-s&qcYH$KvGshuzJyg&geIV9{quRIT8)E7BnV`rK6w`ccyxO!FWo@ zgBp>{I3 zv-o&~;1!SGXhDN`K_|kxk{}47J^{u21Va#IH(LIvBKU-s&8f3A5YOcCJdzFa70mV!9DrI2OnOmF zEHhEwMev%)Bk^!x2&!{x#p5&vJR1eJrE|7;Y=Fx)C&6;+n3?`z8r_N$`I!hAH_XLQ zpNi_I+y#NOasuAl*gL_b`~(i*)02qP5nvj@deDg?+=3s}Igftkfma02z}Rm)a7*IBW(WRWMU{zO-OH7dR?P zU}BVl7%n8Wq|)55xsFFOvdo|p4J-xGF@i|C7>ZjhJYtYyhm)Wb99BT-KWJ`dH3~|( zu``i*D#kD9$x|*@U?o8;cJs;zs#B~5#%~a17OO!twIOOPL!QD!-iEX;82hp}in*MF zMw5Wdu&;(&E>x(%3uYSy4yK}BA%cUv5O%P)oMJN4==zAWhdSmI5agth_o@5^k~k77 zV{SoT_CBMFHJqO!#83DYAbAel2E_}aIo*nC88G(6HzuQ?D`3FSK0uH}fc%u&AB9Q~ z{*I@hZn}~*sv8G`3Ez^(T1?SdhF~tMtq9SDpzFD>kCoTBWnPTcx-v??CRjg8oJV1{ zDEN+~6X7}>hU0;^s5*~IPIBR_IUPophTR3Fk?{cXbf?W-G5N{m?+c}=2wD*88wlSV z0lKsL$~0yp@-d1SgUMA#K}SR>%fUGcn?*Aold?IS>oyfQQchNMD^5$dQS3qD%|8jUPW9a$^{eW1~ldAb4dlEH!vVS;6Df~yp`wU*!lk^l1eB}I^g zey)&g0`UtF`U}4v&~+kSwjjY0Sly;97wk4S7EFRwPZTmK^%;aZ(xtyNpeplpBT_JP zyWmX|!6;5AcnKJZ(mPq*Jt@gW=wF-&I-!D#aRhdg)5 z;sJbvO-@(AC#3zsW3>i?^5`}Llbuxs+gR02I4QNm!ws2Z1Mo@_Pd_?4&RKC(#uoja)$oadRpeQDu zK7zG`dV}!@L~KWGfp7^YvNdgajLxZOzmM`=d6}icZwXAVkYh0(BRQA_KWpMGMAIE* z1#3||3F^~{ zG6&eme72=aZWPujN^s3dFbCs7?A?a=VA}Ek$yPx;6N!33vN}=Lpz3^T>ww&yxnIxl zElJ+{>`h<-m%zCJf(~WXl@Yl?|DEX9GgOVsjGZYvnTjnTw+K;oku)?$a1zP>;C2zAa?%33a)QVB?qIC$BUBm4O(T&jkGYw_ z%T&^X>aIiBjg<8<@j+xq1}BlA#To3*L{82s=!7Wi+1p4DUqkI2tJ!cVjL8Ga`W+`2 z&oI?w9AdcoqfvhnGx3MV*$hTLQz_b-4E0eN0;pk1cDfMn9ji>_-HOK>#IDZXIfmc|BCbT!zO*(UdkcB=B1b>CEFwo? zifIBI!7d~HSQaV>$KyYS#+}EZDDK=v@PwaKT5gmTb9+;?qiSjmi0o5YD7LL8v$wT&3Rg)b_ZF zAUm~XM4=`Tf?~v57%n)E?B9vp9WLFuexa=HF-^e?k`=4ld#qq1gYg|HCe#t+B4{4?+0m~tu9gaQDX`W-qGP^Byx8Uq!KC@ZXV1|3N8D9M|Fswf^J0$tm-Y;L4WP5@2d|p^GuUqS*fHTM~z{9p_w3!vOkj`8MVSlKZ@Axq3-7?c!h6&bX#0m@RZX{ zRPvi~&P>oCUNp^-#|i<8Gco1E1w}ci*GG_Re{~8#8elB@-hA zm6)+Z&}~DgaB5pc`$nR@LA-dVMIxdN)A1c)A5&^86rWN_a2*CEstfWv3x4(z#6U6! zk&lq~10KJD%7psC>+cc+*&AK*PZoT}colgMFn3-}1r@>s9SHBw-cA@?t0~w__!%uU zHY3a<#BoLV8fZBqy(VZb$}0H9d#PoLAeQzeAxc4rL@}#xF!9IOrh*^>HZ$A>K?vW5 zw@4wzYddXOh(;|@(4Ject(D*%GIoVr6Q<}42NP-uzT%cGS}>FrG^V9?bZHzK4dGSi zlSwcgR%elM8|oi|+5pC;6?4}flASCC4@tg>j=Vs;I<*DCT(Ys;&EgE?U`{i!y3A~! zN0O{A0(&lK7GJ^i@`48Bb!;n$M~!pbuK6NqEH~#c8do^4Nz&C2_Jgo{8G#3uZy3|D z^kf`L4<*EZ+^=K65UAfq&#mQr*2RSp)CQ_VM#}l@c2OTZ!}|`HIIz=Vk(Nm zV;Gt*gT^#>!9h&QdJF2(n;7Ql0Cw{UP?&6u5HUCN^oblTn2vcqf;~*-{PYQ=QS)fM zBSEJT>N_ciK`02QMaoJXjHo6k%j0Z>$V843aL&nIGVx|Hu5%HrE?`Tj>a_bArCx?X zV6Y&T)nE4Rb2(07{EH|LI|wepstG!G<&~Hjt+o?tZ)QO$rl~09H-_IyPIEGvKS&e> zjgM^v1rXv8<7z>?O=#u7HR;ny5S7l4DD@a5pEyAyJHeEyf?kZuVkY7YBpb8Z>L!Q@ z6x?OP5{Y+}8On@XE%H{j5Tv3@Q6^$BYD{txM6*|$A>2m*3sk!gUCZ8rW5g>6)6R7T zjwEuA6g($+5OwUzD0s;T_&~fVBQ+?SzymdGS(T%h$FTZF_#XHc<_?ajBFF;MS4@Nz zlUJjSgi@5;9bmL07+_YmC6B1j-!6x|v`MK^&4=wgFgECHejUzL%s zpi{#zJJFz?KsN~Ir<;od1@AF`h~p1LDcxVN2ZndJifL4`GDI+zLFc4 z8u8rmO#%X$jxS8da+FT%C-_BPcY0&RE1)cG?j0d$NOPZ4T|44cAzpXh0}}|<1-mVT zx`i^$stCLYFdJ!Gw-mI&WE{2kq+iP*d9{(fP`@Q*m1Gt# zP*G+y_|r^KfR;`o+bIH64i!W)3B^$3C3ZciXgjZ{)&v-fIH9nbPQCA8Wmi@(746TV zvjeN#xE&xs1jeq+abFIab2DAYTN1bozp=RaAw*`3htwC8V{e+Rpgj`*4Ho?2J(Z0+ zu(+C_HVn=&0%=}?ymWOaIcjlNo+497m|%{(AOMnuNnV!{78BG1e%rWlH8KhuSk+?^ z^A-?np;5L9Y78`g!zL$9d&yB3l5RrZ-CYDj==E~Au0p&?sP&_|ATd@D(m*gbNswGs zFd2p&2{p5>pf)NTuOz5M`=;Z&5e_Ca2asbIs~U_$D`VhA@SoC9d+8OqO$@-ihSpiyL_V3D1mZF9kHg8u3zh~(PcsVgwK3yW#qf*8SU=>G05 z_{EJ1VK#2I6tshBLkPK$ym-7Il=9Q4;~`u=v=v;&?G{~aO5+#9>QfED0AxSYS@0bX z8)QFByd0ebKOF>h8w)%Twy)|ioXi`9$clI^sboC@bf&sJ^y@hzQUUSo=}2iR2`DId z&r}vA!KYNgBj$J&GHzusGBE@b$r6<)xJ@|~JOoEcG=(VD5VST!P>S)NLEh!qZA=hE zF>QlLz7@BZ6nh^joY?DEMR1G9<@mm*;h%|T5FqPPL6HzaMfgo8M+(wT4Hq1QWCeP- zkUL<(=_XzQ(R^HK0KD=M+<<*FO}j|PO^jf7Il)JU?+14!9=p1X`dWl=qLH6!3Q~Caxe+vh)npQt zqEX+_ei)AvA^s#u(2?+YoCO6Kuevh?JF$E1COE+)EM{hpp->6RpURxPgYM__YXXhD zj6iW39|XyISp*5*f-C7smtH8Tv z5fgE-g1{w4@R@k?XmUMU!61@vrOJ}z@F3K4+MRQYpchx76fe^fr3Fvu`Q9T*haC>nZ+ZtzJ_Ha6;y)RSQ1!Zc`{sZt)t*F{dqf7P>F&nLZk#EHk4Mopj>k_ z48}K=S8qWZ!7U<}g?dZucIOt1WtNMgLovdyW#xc!z62dfB~Qp^MI~jj3hpwLt8znFIziwVd`2RqbZR(gF*joP^|U>`r79 z*m0>35w8afT&d_Pk$W)b*C?Nw%Ugy?*b`%uC_zI(P4{p_&BTq`mXCWvCm+^%9h9uRfaser`R1!>L z9Q+xK{B+?NT@S}(DLQBJ7JQ|S{xCfbwZ~k-L{?$c`vte0L^g?1h`yz8keQd0BQh0% z^HugXqMr?U-C>%URYod*g2{e7Is;b=3Az)?l9$ANM&Ldk{fN??R%B&f#;3o1DL)=b zszCBps$dF5XJs~gnWmq*8D`bYf{nEVcgbr_}#&~L)!G>vzqwszDp zt}%N}1Rp5jA=-Ch(63V9W0cH?R^O>@0B+tqjwfCQ3VeiCWt;@HIGxu}aFmgMPBFuY za)c=R9RzRCc?}xWAyF8F8c^yQIIqF@eLX=RLY;t6V=ly}+Jc%9feH+1rSmDd_i{5giUcdtNtb>JljCaX!I2Dj$WM83{TB2uc*3GFZ6_96|+?DPbuGK@ghAUA@Dt2w@U?LD!Ww zo}}J=(SjX_lfvb+VM>m{z?&;H8DR^;YB3~NQu#P)>q;H9vkKCP>|a)}h@igsdQfT` z2-zU<)P(|n9+M&k353cUCddGxm01L#sOAHWL?p>T(Wm1CJNyM@7!U^}=`v2x9uFUC zi-BYT9;;**Ow1+lLZ;wC0vo7hhVDL$5A%4mhF~tEJl|H3ibJmXWGxq3m~7wIEluT^I%zsTM& zRGZLBFp&cnUJpCT`!=^=MH@jO?Cz7&od6RMaVoVfP8MA75d0y>B2Mekt*Q{ZMQ1+4 zK8BGWjom@Q|0MaTY=TshuR+*H8sseKR6}5c zU}bFt6}g-xARYp>0+8%Qs51=(%Lz~w#rHBat)W{oUa7Nc${F)#S3E zv7KNFT!+wR&t8H~jRiw%3;NQG+ui~{-cwOzxkjC7gxXzAP=Vq5HD2IN59j&`wvcUr ztzZ#tc8B5bU_k+fU?ob=B3?oE-k_1Muiz|s-zN!Lk#`ds1*7yd^!3OguxKv0ktPVI zggNOW%wTL~a2;W~lVXN15(LxNUULM=(SkMvZ4Ik82!EFTmqe&K2s$LQAd1>D(vcOk zAOQ9?U==~-yMc$C29bOVaFe2o(eVliN-G*~f>L`pjZ=w4&gh$4v3WPo}i?0yk zbF|(K_@VJBE3a5|h{#W?DfN6i) z=nu&N+_q#C#G+&>*@{;btmlQ(r*cMpx9-#guow<^2G#}GGc)(aR1afc}n!~;bLEWG`frERze#a4SEW|4#T?T0E zK!_8Re~9ug(iHpE7MlgjckMKAL5s!=(yrarri0#utu!=eo z5aJHHWUvvmVlR-C3n1hfB8WwjG{QU3p3?NU9=)82n*}#upQoTDm0Rr+v}SzTz+iN= zU?Y!vfIJi(PL=1$cFj#-l_2m96uyaZu1r5$gJ!qI|4jA%Dr zU-P^Lekg92SFp-TaFKreVj@1o2}ZCwR#%Y7>K6r;Lok>0_n*5~^{DbO-I`D29F+v) z>B4_Jwj`wsf`wz;9zs>fQ3tyoBp*i|BeMuf^$~1>OIu2K!(JWqyUJe6_JWxff&q+0 zR($7B)+m@3N1SVk0w;VA(tvwtRXe-j93p;Wb&26B%RzgF;Yk(21Sq3wE!sRyNL_w`0^}eIF3e3SFihhb+FeSWY>ZOnXIwC3i5Iu~OuaU=WUq|bY zL4t7JMb8QAHcU`FQ0F(z9wa*wA#j2DBsk_mUN3Urptu$cbR9;q7i{lgQVAB@5oRm| zIsk{cS7T7(x2qr{@m|5_Riq#&haix6>k9~~G!opf(`B{nuGIw;i>08U)RGA?3X!7( z$rI>aiB5vmMFs6Rm_zbzD#G-P5geezv^YWA@`4i#mO&jon1Qp*$}sjSqxGdw!F^P+ zWbD3?w*z#))7C{4lSq!0Qw9DMbBz+RCkS@t78EDjO5O^65%hqgASe7P8iHrA@`@ES zrRb*!znbKQ7{ye;!bMOMHL7DgnH=wI1ak@tYNEk*xV+>oV_FFEk#|f}fiIe_q_5uC z9jPw(O)-UP2o5lB)oKfp3I79!)cQ1f9{t(M#Y1xdLRV5+$gGct^PTIhm|`sRB29!NWMgRHDpB z?v*IBC_r$SHfQ${Y>XBRUL;t>C`F5**%*(EhTtvy9>YHf8Bf6~f_}Y1X=^k;MYgYy ze9OUQ0_?`)GLw)3jTmO<7DBDE6I|w&znLp&50|sJ%>r^UEEj;)z$Ao^Aje_u#dDW!@af$%dpsJ=x|k9aGp2_`VO$0*u@M6TSQ3W#`x)y4dR z-Mj)G!TBN+(=?Z02l|~MUO!ZOK$LzE&l@CY#Fk6CRhgkuC|QtsnFK#qJ3*TO!5|2oaTnaB-J?j^ zg;JwjJgF2`eQUdSx_@jFsw9>)O4w$;2Dh^*-`MrQn1Qf zkcG<~$0QsCDp(2D!66_<;A$b5LOG=_DI? z$=edZrn;a!GqDy`H)a%UW#}`cUn~aArN7`4*Yh~p645-Gp|YzdI9XND6b7@CtqCej*1~+Y81v5Imzec^Tcs1qIFV2x%vnjn0L91>=~W zQLy(Q@9{{1RZGDo@;=QXC;+P<2n{6i=m^1ngbjf6c7`gfoZz*OAhxt%Adi_5>;wh2 z$D}v&dw}uU9WEHwSP%(~aUBINj6fsiJj6BoC>m^x5qz&K*iMhG z;W3o5=EBsKDhCj1EM-lx6eRJQJex}piSZF0%LWJzj1XK-5L9g-IL5)v5J3=og$eK# ziGv}28O5DR^n`iN0fRZbf$AV<3sf6`rqR;`-E#{9d2HBJ(A-}zs+HhYbwMY(pS_Hr z3zJg;NtQyb8HpxB?Hk1F!)gcN|KnEVVG;v5UFI$r%M`~K7c8a~)~q&hFRdwIHFx@1 zoWK*0Sr&ppz})SElZ1at(6pR_5bB8X6!_AVL0p^%1U*F21DW02v4V^A?GK&#RZ!5p zvS53PpaXA}Zg@24ELcy0oudTSgvv{lMEG^3N`FNBN~8Xo0{7v9P8kKm5%y16fe(b@ zyaX30H5YUBlPM{OYB7j?&RWm}&Ktc2V>$@FLCpp?cTNoyYDa;k`U_Ur2&`%7b3zR! zZ&@mu%}8C%F4!6?7)t<8Ox{EY$|3t8s@z0-(ik&KqGSpdWPtPBFu|x6f;;e=L#X$8 z1x1J)OZgx1n4Lp#1xf0&m&oI6g4U-|y)b#k)LA3WE-F6?q3Y0>&8T=2uV+@l(!zq; zP`kp_T>y>Z$bN@-IS9Xv@{=HR#7>ZwEEvv!6hY44h**|e;l@4Mhh2$2f;jR%p<6p> zN(hnN+6ZdW-=Xn>4H!3$7UU*J2x4dAby%IgRd*Jg<-%T?Cb&^qu#$@2Lj1ms{;F3F zbt7vDzBUp#z}cOYfrOs}l=2qTYAARQgUkd-;FT6=2wqzXCZS|E#BRzfXd3f;xU^sl zx@7Vc+@zT4sA0`LO3o#4A=E2a6{Dgl(A_}K=hPL{KW+KT7Zdn`>cc#iijQoNGL6Z`K4YV;Wui#^SK^{NB^h^RPuFy>y zH3EJ;8QY7HY)@GSAl{Q=_CxX(bC3kQ=3oV^iqXbAki3szMs0xu#x?bgh~^XQthx#^ z(XwMaR)y{(dY;1Q?Xs2Kb!19mHmA4Ke%B>zi4 zQqZM6L62kd6fS={31VU21?jpr6Wk_wUo;q9NAPsK;49^qM5aHK-wl&OM6Omwa3@eO zlU_bUQ)`k}r*a2gS|vRNub3e}d^6P$WM?lIZiOhi14UosASpob9O9MG-kP%9xOsno z1R9W~ieS36-~d6>NNHb9FoD)S#V)Fcz_F&_{XBuKlb{Pq#zD6y(lw=d^&n(2VKe*$ z8Hu+fx8N&#!(g=nnQ}8`j%5YCcq~KrkE7`~LLDL0E8J{D1ubZ8MbxN(&NESWIH$>z z1&iVLkjXxS-5Gzua@zRZL(rDlm`;@H+@q9Qg3b(jw=hBZ1VP+hK~eM=x0Yo>$#ynVLAenKfK}ca^oKl7mTwNJfyYxf%O!4BA;M4BBzY6$%~3?HrLmSqQqK->XEy zO`38ANp`X-zzZdT0&kKsltkw<2_|+EWQ0|MwO}OUQ(~E5A&LHr6!`cGdZPG=I)dL$ z0#AlD%XmTVc)>+K!L0!TYlbT}MNopWHq{r*Len*fJ&taL(7~guY>2!kNe~tysD^Zf z8wi##42NJ)8J!Eq3ffR_?f!z*6m5xd4LUuEu3jQ&IL5o-7fbS+0s0$FsF@j2w!wGD(AANAUPI9|W45MZP!NX;VHhVZtWR;LedXw^9KCeyyDjG*@Qwt|t&uM2j?8PlkPf)nU=f%jNm)LMk`escI%5%gtcqE;8$F^bdgSp{Jg z1=eUZHkTm6U(k}mN<<1KcM{ajB-qd1p6Y_4sQ-#C=Al5(27*Sgs*gs$(a1kgu!dsR z&q1z`oSApqFbbG?faSA~TdkZc`2o`Y*n)MYVBV8ny+rv{3Urw-*9NTH` zV>CF-o(EOVWF#%=>rQmG>L&1^@{?S_A%q{t!2*i@#$yXSPIMG_(B>z=ZFGqt`~-@= zLA>i2@39i}LHlT?W0j-e8tsXtjvg2{OjnYg7pWvzh22<^58Emz)>Pod<2zcB%&H`I zLBL70`brlX@=~c5EvSjGC7KJelWh?>?jl5MjB9X1?qSyxevf!BZe@^)G2oZR3o=P7 z!`kdyR_jTWJsLd*!muXAuIBOxXtZKuoJk^^^bHUj%@Qt?$lUND}CCyFyWN?7`pum2o_U9UK>F; zzPT_d*IN+KOArdvutow~svJ+=LzLAvPEe3WKEN%Ck@KcOtEnTF$k8NUkDQ^fKO7;L zN`sb%2u?F&Mc{Hhx8N_nk9mVO^Al|1)|`i0`J94mBr1T2hXV!G=t6O1DoVTwMDDpw z;K|6HAn0NWoI;QC`v@j_30@K413fRu?b=`|$V3;`asgNK7|DqA!Z*xT;Ksdp-CZyp zIX#((XDIonm0&bl5w9U~ZqF1aun zlu_^5eNkpSn!Kl(Vq0DTYk(0G1l@_U z2lkHK!8Kh4PjU0$_Uy-FD32)(1l?G9!et1j4@p#=z3`lZ8wi#+hhTDwU=TxSfd*TN zT)3d%3Zs|EI5zSW{3$Ld2{pHBf;9+n%vP|JdAW~>c`FJUGAeH)1lOhry4Dti1x}1lX0(5cLhCtr6)yOeN#H>FYiaj}=Kqgl`;O~z@8dX5 zMT$^KA(Vu7b)UG6LF9D#;g%%!^L%; zI9gjw^%3!gq7C`(wi0z2pC44nZ@jo#QFM)e|pB z|H~jznpe=z>EbOTe~@;sXF%$*UR7c#!vYlU^EtiPu1W(i>QUfN@fFE3qML?o3|8L6-UHwJ$ z)%dPuhzJW7hkJ-(Dh|r8Y2nL-?+5U*XPDM&#CjvDj=THW`SsWcii(^C#&@UJnC#Wh^JH zU*=*mjXFz{H}hu)Z`}<;$OX61hDfx!o1r^3}l^>bH(QBVm&uUlJQ}Rl9{9> zhNkRu*7Yk26g5(;zq))4T zg##nBk0;!kiWrKqjmO5bWnJnOPWGdDVh~a9BehC&`(0;Y*i0BfE=@J@7XzjXONzUK z`cI`I?IXl|7F|e%YqNQKh9s5qFr53!{TDNR|0`C+b{8*;2{#i_nyVb1ZN_dBXu=$B z-p%s4Wd6)mlxC?cZhlExfh-?Q4Te&+lIlr{-#9Ut`50*_22xl27vCwnTTOA4vU`)(J8m{%-$mLo*)64beO-4Yq>tozg=)PWEKau&2PoqS zmYonL2Jmam5D`r?HnR3&CS^AVv$Kmh!KNKqbY-e|M`C3O$)TaB%%Zob(c!A12ag@6 z((`+ZP)fFqnXhLd0vIqi3iXJ3to%^Q;THGd?RF*RF5U1#a8!f%StL6r)3}US7kZ(1jUqg_E zJZnQ3>Fm3jRhqXHM;eP4jMtqgG0;r(CXex)_SeK$l^(@WjdPTJ0~;;ou`M*kgZdS< z6#x2*ClR6~U8v81A0_(!q!micd+E73&px9Dr>SXyvG^b1?&MV0h!vxQMSi&OB89{J zP}WCOrvY6?2p5X;o6-#+!P%ywEUh@pdT|uOn&saUWTLgmVU@^I;uGn|1d4|>L~BaY zg%pzF#SUJD+cSkTRg0kzX<91zNXjL4Immogpy3V2i0V$F2d}12LE;2q`m)5S05OD; zdDG1ng(8UfJs7@f94Lce5!XXBP8L__=J81JVx$-xBKpi1XKCp-8g3IO?oisX3|a&= zddDh%N{SEMcP>%PAcDYpq8)|5!FMiXV!(U&5=-5o4-?yqDn`PUS41fyI7UWwdD~RB z72}zS>-v}+kWWAm7Dz5W896bRRL6YNe6bH#%FK7ql4%?>>q3GZ2Xu;xvnfbQ4ijW-(K{ z`k=TtQPd)n;}p41IsHA#2AYvb3(T1Kk#uQEO;NnHm`vbXD~K@SizBqv4A@Po;7IES z^WDPrVp2sFB|l{sX+N4OUUJi^v0^Nn7Aq%Kmle*|!i_=|^22@d98c&+8Pv3nB9M+X zCfSCh{fL6@8YKR#6Be8UZ@5=U6dVv6i0clmoY+{H^21>!U@i-sbrAhR#X@>KiOow= zp6ZmRa;9j-^hdJFoaSOnjHo~@H`10jfudV=(T=W9WEK*s%suAlA$`~zEb6usf0Ncf zME}%ZtnDe@M+hfs5KA(z=vPaUUP5VmQpVmPB7KxN7A>MV1%FzJoKnJvw?cnfl}%f+ z$s?k+xI;I4vWfvE*+Xb2*xZNdF5)c?P?wMCqS6}SOXgoFPA0SS)KPqQdPKWL`iDKHbFarozTbMAjEsv7!UJl_shU)IO)J zsK-Yi&9VN{?I;y=a}l43b-S?`OtLGuDQ}9{YbvVJzG(zW-9qOEv%nfsI8DFG+lfr_jjJV| zfE!)^nIsw$eSoWoq+gea#iE6HSzUDBD~g{Mt=ZSzNu2H{+^E$p!dOU_j!efm0&2Qg z^cW>hkYz-B@xoFx;{dkx7lA=y7mrOVE?(3T`4vPw$qXSG?>WL`hPcWQSaITBGQv|> z^l^wt=ZR2?ZMQ}&p-lU2#b~DTDnGO%puwcyo;v5bh!!RyU4xO*jdHq@{wUr_jrrlc z0!n_Ga+n(J65@R#PMly*6*G^&+h5E`yhWmgyNsScdgl1+gdYXxo z5hA3$c+C&r321x|ahqga+?{zo2LSTC}p zNaMZ)cX5?0tqR2d{(BelM289DKJhgt%S|*Om!uCFifry1&+?b)LJ&(uq=`s+{tvU! zxx3giRG7Po1j^KDv?#bEOj$Xfn0FFOD_Z8smi^h|9J$>|5GSaC4eM>CE^RHux?Uo- zubAf}8q&OneD|KZ9B3$9g2Zo@I=VpAsVHhXi%)!)M>U=@8$amBbz;6p(!QL$;@t9> z(YsShoF~3Sp7=3deB;+7N8w6W?fE#71Z%NT8>%surP4S71M-D^XR({oXa{q zR=H5PvD73|SVhbH*vPt!I95-TOc5iZL^96?F;YH+wvducaTV)%?ccW+#YyHPKO8g` z8+dQHQLu-Uu6&-D$uX!OD%R4_zSTq(D>0vHEUzP4Gg22>xdxRSk|BIpv^(SdhrWeV zrXQU|0)KeeuxKk*x!@tXtQCEUrFe)qO6|Q&L;y$V8M#%U233gp5m~n5EbL^dQf$5| zS(IQVo0^IV)bthWc^nlF7`-(c#cE>S#SiA@;z~&o*+-G?C#KQ~)AkkL_|u;i5%!BV|>TQnk;?)=(?v0X)HiuVvDI6}D;ryYAZlR{cU zahO5RVC6hI_>LcL5`D7{;`BFM^vLyTd{?-g1O3LkQ$JAJY8+i{4E9_7ClF}O9zT&+-yhE zZ;V88Pcg+8%SG2*(U&~xG#0gK=xUZP z#+GmS;TXg9!Cjno6Slp?#oGE`idjs~eV%yUP0WYs6s!yFwrM6zS*3ZZxWWRbNZ*x~ z?W3GWNg*gr)E*-y`iS`dnn%^Ta=;3i;<993j`6u$LkuI*t}JEG_!x6FkBaXk^K@hgdFl5UaDqZ&I-E6#tO#ES5j#Ec(_G&-gVm zPkblA(M;F|%6TM4tY0REF>t9Au^cyFYkoRXqAuZImi#J+gZ(L_9`B4V3} z^BE$)gm}&JFNrzyzj zrzVMfDn7owSV%H1{Cby2ZJ>s)h~VH9i4q4n0Zna18k^6fJySM`ThyQgKl~y-7cv?_ zXk~hf|?ok5~T}q7OAv5p{ytpEq0iRXrij+ zDsnhcPx-EZ&a`54cUJyi8PSuKec9s#voVPxHrpvoI*WC*wgm;-L^92(&{4W@mU8~# zi9QU{10paY{Vaa4fM_~xa!pJkf(Z7#VkMT<7ulSJk=)`=g}%}5Oh6ve7uj;>YB7;#CldH=W0Bll3?tkU{=#>W zIL3FWl*Fk(__6PaLEYPK>hNg)(Ts@(Z zi>S+I-d9yCidmez5RxetCbCF+B+-{C6n4z+G`?#@YpYSeAv|GAeIh6=bP&KDMV!~Jv<1AKCoJ~BN!RCED#5_|mo_%lL6D@fy z-3A*r?-nXb@N1EHv6sSbr7p)R~D@Uorj7-<{*aX zt%=H=ZXKm5WunCmmJgu&KYEE*ZACI8T7v~H)A&pLiIdKE;dE=El_)n}gir_{8h@5> zmvV^j#fh$z{zP-gZy1$~Dh|dtKNzi(vI7;8F*v*qM`$P2MBvVL&-Koax z7}1poPIeYo$#M$|9AP($@&ElbTzgJ+c_J**N{r%scWojT+-Bcsk$#5IbuqN+HQExh@)8Otvs^Fz@hn3Z?65NTyZAwRt5 ziIe1ZgOv*cMVmZvi(8@zs4{1z4|5#Mcg7{fKh5>eb5A)i(`$*(j9j^1BAZ((28$M@ z#9W@O(pc;yng1n-;naS2Q{k{)jOrjJ*o!k+;`A!<&_hgT`8MOk6Hl>;kCo<$;T+?w z48|uOyAdY(GgJc^=AO;O@z$dDcCm&I=Fyo#QgGlbA8H^xInXER`3+{VVtFx^n@xx> zq@GA&4{M_D?jvTf?=G0tMQrvLCOk2W%&T%Z!Y#zf>0*za_&Zq~Bk+mzW9c+;ikimP z5dr)ahN^)__e@Ol%$;R$$U<#$gL&PDC~B&yvWp< zb`xh=KG|42XRa2r?+}h;1rFVFDw#lauM^cN6S1GE+sDCA_Y>ZXsIj9s!MkAsng2r( zKjewQ1eq2rvPotdeH+UHuLg=Z_C3t-=d#gE@|YJdd^1H1Vbr2b&nQlDQb^4g#Y&5{ z^y3qYIumKIfpFr=zn$ojBCKeNWuR!s1!Ay^sKhM;>Bka! zWX7|Gq~KLu{36T2y@f|Bv4HO?RTTde7uKIe6~0?WB_nu!#fFILJa(2Ti61Nimx=IM zVuzLRWPzL^!jze;O^K1zsm3E_!;kn5 z^RW>TjG$3_$BCd=VMASxbP(kk5K9KGi>K&AGR?X92P@xVEGjUQ7Z!?LwBkcY@h=%U zv=jkk{+KOigo$e(L^}p#DGm6SMLRNAR($8lMmhJzJ>Cb;KMF%P@q$qfAi?d_*@Fl= z6aAH7@qq=lw-9CMM`{zXl_E}z5xzXT@P>#p71PtiJmM=#VH>s)f0q#!+_%eBTwtTj zrs4z%8Z8#)WknYUQ9nSL$+L&}?j?nI<0CE*S|uY?fa{SP#wwPH|EFK_&QiL6y{_P<;P~x?f#KpGaTC_OM9(GWlXV((nkwnpg-QH%1 zTAY+jZkbMK3qyqytE`}OEgi)Y1Ch^ex%EXaGVeir(WS(s1!5jocI^9!7sYzgAJuU2_(QUYB#Y|3ZFG{oJDo#MLs$%6B5y>IWWk9YHX%(jF9hrA<65Cj>DHAb^ zUti4-t^9L8n3WT(dQOYL}OH-Xd5KPR2HdR&89_rSBMMLzkuv_GYg5V_=k_5SoSqp-6fhboWnPK z_s>|-@_=~XR%8&;r)qqhE5e$Ik5r_Wv-o5#y3`XM$)W_4GJy7G))3~^#bPV*&v=nS z=|gz$Y#AVG`HFF=!jX;caWc;E!#PXw4@H^JQaNO_keAt?LE_V3F^U?^C#skA#oeyL zp^G@jJLV9Lwq!oeaeSZF6(hNtXfLu_iPywj7qOvUG6!h4|TNOd=t70DFm z39GoN`YFLQ<0(J>qTRc#GBLX#lA$lSMy?sgR2tU4sNvd79AV)Q=Y zP4kNIU9F+QzJzcdDI7YBq0CS=e~P&=5%0}JRC95d(q-^*YOV-vE&ioF`Gk?{EUei) zhkak#3s+KzCQ=91yF(!+oDe3&w}8e!;=ai|8#`TeX8x)%-hn>iU1?E^MQiayWqysU zBkJ>UBLgxkLEIt&BVIC&@H9eHB)(&e${T80y}am9U8EA#7MkZUTI{9l-~B}_LlZ#y z^TBwn_(=pGC|G44J4oNAakE#BxJclWsiZwu7G=e>ED=PRb`fNkF5;%QSj>bSStQDF z^$p^|+D;trEJ8>+BSx&C*qhmM0xR!ek8CG#t*EG0PNY;6L-=(`AMrFw>}@JOa^F9B z!mEsE-B83*A**ch-d3~>5EYr1$7~eD38+MFZ)=IM6e5`{C(yk0!^9o}-=8X+jYaLD zVlI#Us4JGzyi&BM6*c&lE{c~Bk32<86>%v|T;q*oI7=7}5rvHMv#w%$H8Hz|nBXg> zv3$W)@p85pOpuERJesJURS>=CQRR`so;pvZRx_BevWvwx1}=l{H>dGAlsJR#-)=4v ziS$R3SkDvt8JhBxsS=xqnut0?dXx%%qlgV$g){LDqmr@lq9SjzR2oo{{(2;cMcf?A zV`R#-#Ip)%zB?G zi6M0kP8Q|Zw=)%r-I?w?Cw`VF?iE4aziH!`o8Zci3vgp-?B7*3bQk+X%ou$9? zXv$OCSik}+Xzc->H7A8Pd&R$mR)z#uMTk8VyC}0ZiB&e!!2~MwZlkc%+d}^-TtAM) zHybg+LmZ42$s8RoZcn1fe<)X&CmM)N#1IQjyhQVX!iI4$uBksK z-OA|dJ~t0!%ERi2LQZBqxXQ=nRBHmml4dSm0PDLh%BZi#!5)87Rha%RFj6 zi>9q(PDU&ch9yN15xnx(<|j(%>K65Q+E*0ec*Zep9v#F(npDPF2Ye~$V z(#7KciJAp`v=(NsML~dYA(;!2pdu%)Noh*`uhGRGgj6X;gn)lbF>{mnN+27VnZ_<+ zVy2kSOQpm#anecjpzpV9iAW0inlN*~mgSev5PsCMknx*GxvvoLTk6)4_GZS3hO}>( zp(uM-j3w=%#l&}hFrvdpSzrNSoMPozCgDmy(XOJnS6p1^BgS&zi<0bRirm9hjHYRk z)MGr0&Lf~AL1J-7vC2R^rACwd#o$m;mn?UW6aK6m5-U1Te~`k|#UjOC7_w1VM;#c$mAb0p zAQtlLH%>?$y5+#ip3&kBbC5#JcPQ-8s-kd$=+v4kcQJ(~FXvCn5I#O8)iQ)}osV-# zbrij9Whcy?g!Ni+h4tQ1_K{4^^KD`|ZS-X2eBKDJ$TFA5!WW3=k>Ua!tj^f}O)Ngd z(vkRz)AOrzu#oZDmms1xbCo2nQAArZnnd3Y(YN^8B8l1P!ctE;8q1i;rZt2E^Ah@A zgz@ozv~fixahJfKQkRA~V(4N~tc~bsEN;;#s|az8SAj`4QLloSK%^D9`a(&{Q*3Xl zmP&ljXjvT+4CRILgEF;Yd`6~;x~^h#FLAJom_Yi=4vCgjV{I)_j-XPEel zXVVLczGeG}GsH5AGX0NdQz)!eqVS|RX063IYOt7_ zPuYsYM6i)mNAp5?IYuNE6Y=v!ATv3K<=ZloVeLgGHTX#Su0ur~QvEPmSbB>KG~i<^ zAdKtg;)<~_W6{wx`2^2et>7cY*+}|#n~F~D#7$cEfNH#^Z?mX|C8s;Mmq=hRN5>0~ z|FUG@5_qhnm#FV6T3CsO^kW_^yUed`Nx_v$x@3yxM0$C)Slmr)r=fdH#Y0Px;Vk}k z6V5HgHr8{ctG`Hf1oyS7D<0GncWA&h>Q^~NM3RTm9MOpvPri+KTte8=ZU^2kw^%QZ z8oZ|!O?g#K;%r5yij(y1-ZU|lJvLIOz}0_M*-TKM-BzAV3j^@0Y83RHY64G5z> z-%5({MtYSx@7XPw9x`oK1LTk8r`2}%jocP*L z7*L3jrNntMnwKU*$>UX?=ou(1{KcH2TDc*Ib16;vK2LNf3_}_n zT>OtFFWf2IN%|lqIl#>=cZgiLnJA`^jIoFIC~l~$4cvE`lV`#B^rJmPItpLv=gW6B zSov>=Cn|4J-2x4>#i#qiodolTi&JcVbC$^P6o(ns-oD~GQ<6%!7K=pAV}{V1Fygz5 zAxvx(VZ5aFjxJ&-tJLSHUGF2xF~B8wMczIlT8t5S>|2*=Tp+YnbfKG_h}tCTGv3}r zZ?;}cCgyt#R|-%3pd?Q@gUcvg0-LX;B)ck$oYf-5RXj@)%UdgtcjR_DI))}u*?u8 z*<)`_vHQRHNcB=lQJsQ4g(O=0ikO>|%#$?Hm7&h(yv5xWhD=0#irAKN9_uZBWr+9v4i-U)3<$L;`T+6JwVj*6dl>} zHn0DA6@_sLQOHt1JBm$=Q~}hc(?$J7hi&3pOJPbE+N6u3%=lE6nq6H?VgADShZ9qt ztw^M^SpHv9JuzDp&lOWcZ=HF)DtlT zZbuu|_qSH)~N4U1s)RkelX)26axiyRSB~^=_!iIg#w}^RBq5)%D zjlg@-D7z}+QfG0Od@sj`g$JEqSI47zTt#GCbBRM24q+g2r{$>Qm($F6? zK92STQv1u4q$$tdtuKmf7Rz|==8~_WiCD;NEMpE_{e*$7@SQ3wgT&XXqGUS}&97TX zFoGiXi4j*_ME-cOBvmXA6VFKN3g5ksdA3QcsN^7qvC2b=^NVRRq&-z@i3&eN%y4mRhG;fSyk?{Jql5(u3@7vbtHgA= zu#vhfppp)>q7NM`vtGP*7oB&Bm{9SV(BcR@&`DgNd81kMev&Yy;$4{7X)Hg(MkJZ4 zTm3reDuaK(I8jtr|B#j~)xF@N?|x96uFHfU?GB+)RS4q(2m4==zFtXuVYg65ep9xH z=evsj;ucLlPFlIuM4v&Tcta7-*xrp4Ni^jcH66&@FRm;;92Fhds5RehS}w-0Xfj(q zrn()U3Ky1dXCcngeM7o6psh$r<+~3e)Ijv2QDxa<#AwmDhDc}7t0ss*lHSY8U-(!* zO{5r!-(5unffv>kqnM^1w0prJ(S}v3v3wo{>%j5{RTup=++M1+Ia>6f@b=8?)d*og zGYV^qR4>s!PE4XB&ZO9kF*JB3?5Iq!T+!G;Ok;%a(cxERg*^p0TU9u4wDV63--RNX z)=#AXe>sXgTVY0d4wA(3>0%KP94{%ni-{?X#K>`?rKxDrU-T>#cEQ4&nioPmR~bPTMk<*Qk`2-STqoo$_vkQ z(T|FI1&Y!ZtVl}haubw!@K^V_5X`UyV z@iKVN9Q>rP%XzE@wMwJ*@nkfgx!N>DSk4grnVfnyBA~UX&`&g=gAJC86;$mF$rNXS zZ(Btu`#z(HhCM_v8ug3EhOQD*3dCym4RI8mh`C^e@MNhk-lF0*ai1+mFf?uV@f~|C z>cG{16(Z73?Zr{LA5Wd{@UbRQWz)P6D`6TSyh;nJ1mVGO%`?|KX#*=~OcnjOr2@-a zoDsox!j@jzk%A9%>ggrS{u^pC^5x@C>Qb65TT|jgH2Eu0IkMX#8s*7s#4Z%QyNL7D z{Q^SolhlwxnDx=w^v#9U;L5u198wQa>2CVR$s zv89jL>n<{Hit>|1v2J2FQ&(=OctYU+_=#*g72-NEPi5dj*kevdVLDQb?I~I^Yw46Y z(os~QM`;Y#A2PDw-SnGCE7cNXT|~EJQJ!DZeMEq_NaS$-{oeu{CjUGU%Mj-AX4p(u z%Vdc<+U?)>jZ+4~fZDgbg2ylhe+0U5z6C zL(H8MQLm#4>ly#Tr(!Y-Oz18g3Db#MekJ#Zl)|10c1jWD*nUoH@s^yt*kc#tRb;fN z_(p6ZeyidlfEGM!Aucd1^|)^^PZ%*By;)@i#d9Ww(*!w}L5nRf>XZ8|8aZs8_`OA( zW|du3p=GwHLmxtFi@OOThRNDeU2Nj9U({_QEB9rhFVMN!G-Gq9DDNdQD0dy^Y4!$D zgIF$372Bw9nyr{JM7)_KZp4b8WkenWnML$lSfxxek@?@V<#bh(neE?RZ0#!EIEbh; z;nPucWvr*?i@ylXm6BBASy!sIt(Qok*G_byk(r1+EwXv6cWu$1$84CLcNErxs}LvA z47|B7ouyLkL=jGF;V6wj!dG3jHW07L?doiCoBPbkt>SU9nKQ6zfY?r9?=#H1SnmV{ z>sU?HB>iF}-5^t}3=+OGL^!c*r1od2eH2TLPtky?ISZbFdcl`QjB0gjAn{GVWKy;Y#1*FQo7-c z<88ikCU9GB38q5B_%+c?q%uRNnft)$Vme3YHto5RC?>WMDTQJdS>7)p_D>XF$|~Fw zopcq~*4IS@CqNxJ6nC?D0N8l=BsDNw6g=M>Q6P)TI*%Zf`4EEf;g$#OL?a70`cT=eWeI85j!}8F|9?y z|HM-QZ|@@VDsz=7ENI1QdS2UKn2}(~I-(zuJ~}5B(y}O)??GCwq!r7rk$k*Pf^`za zr4eE$sfH3{00ld?LUc11ZmY#}YPDmu8r6bW`X3cNi;8nm; zu`18Jr0`mr{8somi&+iD?Y~4oX|alrxk+L;`zABM*GTXbb=g--Yzr1kjK!5KQIpX- zLY=$E@sTs*OgZ~e;;${lsm`LemH6Q<8q@JGvxkI@5i70y!L>Ok&)Z9oIveb5dh#A;?ZMge@gG%jU*8qDDV4$X$%j5DUAC1x-X%+PG=I_|;duWZ&{xB9cMM zqiPebi2Yy0PG)F08+|kocZu|XsVKr@Zd?tg8ot~TNSRh15%%2d&53$JxZlG?^)aH5 zFsgPEt~BL5kCp8yu7rt!-Gu|m{H`hHGdW45wU~_}3dA)Y+fSL?`E^2b@xfJWj}y0< zgIgTzKg?ArI@4&ixJbbcP#nW}5jRNGV8$P?z>Eqaii#h17r*?(p|M<zsfJkHl794`b(uXVaN0Q!=;PC}uYj>k{}FE=~|+^_jxHxR}lXOCb6X z+FhPsTX1SW_7P*KP&)Hcr?fccCOHLn42nkllh}`;n`Ts=NP0{ z7hf{P11FIeA!^cq#bzQHTpJ2^8nDn!yqPExX+Q%A+a#Qb^nW}yo24$%U&AyJNk&a< z#0WQWci7dy)@ll%gB!;j7Q_d!H!}Q<6XLkD3Kz{k%w`6QOjId zc!=_B?nsZOakZ7ET<0xSnL5uVmWfM61(t91KzNf|0jn5M`-Nr1p*bR-LewP4SFO~o zK#DzzVsD_FtNVznv&6eZF^%fp;T-jECyWSu1`)KnCiN*2qT5Ed^dttTq9;T%07y}+%n)hpPi!L7;%~ecay?D9OBLCx+TB1u6C02 zLPya&KrFs5D)P~V!*tI`tYv6kuy1{ML1Fh)7IEex%S!BQB8u3FYRu4eDsgj(lg{DlUcnzkBa?xU49kGpn&3K+8`;%G@;fL+s;x0?nZ7sfa7YjRx zM!6!ik~rN{>;*5jk0JhD)kXVoapsUXogjWut&W_A^20@Q-b6nfgfGP#W-E$wjDwiK z3Ow5uBx>-PJhY*krRfx(K@5sY>m3YRWjb=KA)D%0niNBIW0&QN%&>It} z8+!!Og6D+xmD~&%k!=ji-Dt6b_Kn;jW>XwLZaJvg(ci(XyP)f(Wkg1zFs2^oti@5< z)~uh(SefsF14SC0EzhQxTZ(^)uqGWlQdMM;&Us7mm8CqWhu2MEHbj)5GFdEIiKC^z zOI13hMAR(d?&y(n$&XiLOkx$|tzt!65$G@esv@rO>r&p< zGs*JbR^n!?ct$fSItlZIqC58uEg|Mou(`!W9-BWP^Xbe^E&A|_nQ$H`I(mw)BgNTE zVpuWJjjng6r3bk0A}9ATjapkrO*u-}qwU2(BB)L!0}RD87jc_`9LW&OUM_l(Wl)^> z-cFqPC9W}*$=v*^zVM-q&HO|FFO?hYo1G>462>p`HK3-m#)yTaFq;V0nuxk&dFGRN z$to9^7ZWNTPV??85kE}z3fttatD}~RzSCe`#qhrCTuLf3WT@!+PFQiXAElc+Rg4Z2iN$k!PS!Dj^q9{ij-=NmhhvdX_RRcXWGY8nAwWW)bDr$(W#ekPxL0uZgBK zC7ga(aNn^gF`=)pA+4X3NVk_M5E!H;`;|_{%q+r6F&L@l)TSN)A{JW8eP7+&(ieimLk6q$}hd4qJ`$mcg z@-6mO*wK$dVyQ+RsZ^+PT``>jKHo$vAj5jPpl{|LP%i{t=P+Vofrl)7RV134UI)$ zuBc=nB6vZ0O%kIyJ*%nJRs!F@S|rRAPHTlpm4F&T6AqKl9`;b%=2&pFHclADcGr{qVI4K!N)Xy=t&LkF}6)sh$yD1 zG0RsaE&u6aJE0wKBckbGSwFGQQZ(hjw&2<5M9ok$hWavNVNy~b%SGtwB&pi-&Pif7 zZyQmLrAG3x9^HDKAv!Y=_tuMr4B>ZLHlEPd@w!ZDcL^6?=ZY`IK4=_qb+48kf1TbdHOTx=m` z*8n|X@2{&i6yoV_kwKG_BSrXT@q3cUNfv$j3i}SCd?%63aQ)(ASiGn_TC`&}jGhYH zQ{pYX>{U*CY?`90*EFwcsxT@mdXU=`mU`1z%w)2S$tZ-^;VOoqm!CN5AclF16@>AN zfwQVD;`ntsTmI`MQt4oYJTYXPh$p@%(puS8ba^heQH@dt;(1f?V3zQjD-vHS$j@%N ziYD_VY_zt77)_Ap`wRa`y zUP}@7OwOn!;)kK|prO~;d=)d)few~lBnB}NEqPTvnkKrR5ofxIt>lqXTD)s72Kk6I z7I?zw%^|9)?Zi9YL&hw+KTr(du_e42`c@a~#){J9(T*+8khD4L6)Y1SIhThAilkt1 zu%&-0gzL@$Q z%oTfhRgL17diTWw#^NsD{TwWc5dF?n;p;3SO~mmx;#?JRo$vOa6>pmhLt>uiC+rHu zjeg>9zKa|w?r_V6e6fu}IQJL-Bj#f}!~ilXL)8wI5)UXzojRg)ysG=_h_1G-7a2TO z@uTP#D|)b$6JtA$y3Fn_92jpe&d1^w;=>}*ZIIZ~OB~|a#s7%GO+}uC_{r6AUR4&w zM6#W5Ss>DDi5jeu#*y3=ErzudhE2q%K4Oaghfm5wK8~kH9t}nNy5gO;m_|7VC5VSy z^#BTl@wJ3FJ43`|i`kd! z7Jrz(c8q)(c1x#z?S_ckyg=vjv8j{zi!xp3u`1O51+(^sST2+ilifw{%i`~E;x4a; zrF5_jd)(r_m5j0rb;)CZ%j^*|n5G)D#n}K+dY`yNMq4QMV+vuwAZ_zkMk^VR8x2Hp zo*lq}jT|N}_ZLMBg)Q?^j`7(*-!3o*?#%Op6tUuk=*~nu;aO*ff6H$%VxxFTdp-{k zZWXlK8e03fzDVgS_A&f3N{a^0qS9h9Ww_YYSsdiCe;@fYPh zM;PJL#X$b-nb1<$5JuJV;#InEo+D0ib2lEdp^`(Ii)TGW_tD~RH*v3`X!BOsSzFK4O&%q7n~5VVU$T|x%}$qWy?cqjN$?FD zm8NuFRLyOqh$|&LDRwOi8%|V2%&k(Vnq^fzHHtgP&{A+K9?0EQ^X}}@rcKcRTW_w zqRKpRqqRs07X{tLPGT<0dZ#ao*wv!%7;!&J{D~L6Xhj|^I|om8i|;f!G)xp(AVv-n zSumSD-gtMds1XgdK%AI!!b%6p=2XFGpifC-JC@IDShM z(twLp_nV!Vz?>@DU^DYPnCAVq6&tFH;!JS?XKQ+IQ8z?HGU#KwGL3{4cLthS}tOL5NA)rmaeb3{bU7C-r}2XCb1Y!pJv z$`EclPQ_e8`xNuv-^9(PeO3hgtfPpXAEbY%(eLO+q>vF2cHsB=$&QPWpEc-#I$x z`iV6*;uk6Q_Yt0S6hnH4=;yND1B%jy zsE&}<4wgDieP=Ke$yY>0LQCOeW-*cNDe{+#>nFrhnpUi&SV;YPE)u`k(v_n)faad^ z6*-i+FC_^H7A2!ZZF}*Ws%<`@^>1oPcb z^)SVlF3hVg0!b^QyBN!`Or;;z(?nGdk)165Al2u{xuPwIlMiIK9dtX%T4UzU9%`!*c*##bSsWz{v9nM zcZkdF#Vj+e+?g3l;K;r#E$$70o}vtSw4w{!!k#(4G_8xP0N4DdzL89!7u96UMi}y1K*>+Ck}_Qx|jEeS>{>ZV``q ziRWQr#zC?DxcIxGxXV({_`#Mbxnn7MGc-fkXb%yTz9yq-B%sMb!x+Xp%4`@Y8j~=W*h3E0M*bfAJ4!0F;dDRFC~ zD9_DvstPwNanM234iO%t`hA%gM&nD7peq?2<5gvuEt06SznKVaqE^gL)Kx?$(RH#& zbr-F;?=K5+fT~UQ6F$so$1|cT1D8#Id-oRw3%KebMo^NR`l2CAbzsK-;+Xmq!M@_+ zd6JkznJoH=GaRAdLeX%uc+C^zdWyKVBCVdNGhJ+=ra!1!rny+(NZc=@=$mxZ)w_Si z9D3xy%DY{}g1f?$p-!SW-B_goUC6F3UPg#%q;NAz{Gp+K{M+%8@w(c^47D7}M~?0} zBhg}jxJFX~W{UV)Vrfm`I6_>Y6`jfQPK-#U8lG&_@P=3tDq58g2BeTq(ho^t|54#a zyB~##I?Kh8iXwcjSWP7zZ;Rgy{=7PUSBHz8teJ|!}3iV5-@#9z^gv}?@ zlCZmVjlgtJ45*0;Uj0^ZxWnBRQ8L+5w3c- z6i+FR0Uu947JJyE+*on;sp!mz+A^3Pob#puq7F~gqj^RKqR~HMtD|^Nx4bTi06xAN zB0Ap}dl{r^B$Gv9_k{=#qPj)6D+&BL-whyech=j+vjL+-6P|rfaqeV^3&aw7ORTdK ziTwT6T2ozJ8ZJyJwjIU!(o8g&D6Vo$qgbUK!{tu%&X872ckzSKn>kvHC!nnaSu|1f zc!1EUYHn+(kEb3nkV0 zLE6b0$ z8;gQD;!l0?+eZAuqLHn|94AqoYRuX##*Guj8F}N%V!%0ZjQh+e$unz_d{gw9A=Yzh zQ|gN41paWB$R=}NYG0kHtIh(;--{ad;tv%%*iIa&C&uyY&0eBcvN+XNw9XUO1u9s0 zw62;}63g3*@5EfGhA^OX)i|LGs8CFb2&*b;^cIKiiGQiVFGghslbF?CB)k*HJ@hZ> zFQ!}x*Y$Y@<1B1Q6`>T=pOCWHxi8V!66P1OJHqxKiVBxv3hqXPuFU!21D&()E)Mh) zulV6Al@6mk&DV&B4&rlDQH)jA5!Vgc(&Ln9%ql1SMIO5~+$hpxgiVN8Y9gL9m3zyH zFvXuzg!Kk8BDXob9fCyLog%lUILs}3`N5V2yl8l>Y_W)$=+|7FCBZPloz+FjBnInh zA5RqWLj+I6ut(*g;vn@sOJ8%xiyO2c+gf}f$T383Mym17qT5$-gQW)2ptjuXy-4)r zoESXNN54-3Vr z2IA0cQH7`)Oc(Qxir+kOjvn0!6oZ(ZGsT6Ip%`N(hEd(tL_eB@ADLK z4aNL1qDx=Vn8yN`Nkfjd1Is_ZBK~$%w|3L%6O2!wz1U?bc2L;Ow9zVG__Y$|j^e^FaZFMX?ssf|TMb@7PWzw0k9KNGP$o485bC&7lKRkn@z z<|<0UXa@KQR|Qn#%yTihvv>yanqY94M=YL6B9=Ug_Y|9Yh#+psXeS(L-if)w zeSq*z6aTQXDNju4E>1EkrkpKjH!*>K1$42Fu7(n6)p^2$rVR2Bc4lIQzc@*8uFMvj z$s;C5cETHA{H^;s(1s78aK;y_2SvYCi2D*oOq zX7O?>Ma7fpV0p%;D3y$@CHk!s8+(ho{1af<16^g^5=9uK({{qiUq9rK+aT)qY=Wp# zLzJZ{O-ZnZpKxd^-tsa^q+pf#xFAtvFzE5g;tioqWk9;j6VnN;bxmPFP4_<*&0C50 z{BRxuHj3j!Kb_G#yi2683Q%@O@6%HicABubnc zD0Z|F_g0GmTZDD6Xw0*bq!m+DxHD*{*{JRUah)tD*@^^)xw(m$N=GbgL}$u)BSp+% z43~5jb()CWKEjp(_bU{~jKrD(v44)Z-9RLq5U1JlhO;d_EOCzMaA7bGQJj^VM1j9(I7HY|rtgFs z1zwKAX0X^;N)%fnX7dt1-B_fta!!KSK2;p#KU*749swMa)!fo~fS5-)&yrvV(Zc zX|N*Z2lGXvWD!9g8Dm8-_1jBfCs2s%eqzBI(auSn;b`Y(ibenD=q|&gxV8lhW5M0s z-Q8tycbCC!26uNG+#Q0uySrPE5FCPQ@IbJH^L^*f`|Rqj+O_stYgactIrpYvF-z=? zftI3#t#@)bET{nq{oWGGz~c;tvK=8s8Te>--r5Vx|MWFu+2aHImFY}%9_E{p%J$?` zbGo?#?6qWtv%>zWu+E}f=m`%iLh+nX)6V(F-MV}Q1X$l?(;-4J_+*NsTh(5-A>&eb z`vex7y8iCGRiPo#Tv+1D-`MR(tVd+idH6S0)FTI@zgt56J}}qkK-|8(v3)zEQgtBE zFt(M0?ZY6FLAHtoG5bR!1Bzq9I=b>8&x@EDZX0f=QSjEg9W`Mq+z_D*C{H%nYyL{Q z)XeU!(=I0G-%xEFboEB>&2AMFc03yFj0EFvLQ4}?-T3M|bFBPudn{C{<>4fVYPJ5g zLE;)ql`~M;W(Z@+&O~oHzZV48g;rkn!IJH@3gHJqKwBti4$2LHn)dko#So!4B=#`r3;6yY97_%r zt@P5BP|lU#YzN(4%;KW()lAN~48!b~sV3rh0*JQ^mhXaQLm|Mm<#eiWsh~oAnAQs7 zRDtp%;iRV&a~ceI$z4F(4jgc z-2n+I!c&voWHmf@y-6&^#(L1k78q}@EwCew9fJL??YSwwmKBEffydr0&wAM4-Ksf# zUDG*h2;?mQ4XouIuc+bg^(}WXdQc8FmV!yqAWJ@21JEQkBzA%6 zYr{{;@6F4vfP?9vvNu{B5k6dj_hsRluO-g|b2h<%^4$EZr3gChYX-U1hD&n|vbpFT zEuchtsMQOCO>r+fqL4SrVXl(8m`-gVNg~MO5{fs6WWJWj`<5>cw{k$lnou7=0~Sgb|Ry?A9C(A1q#GYxIj<_dOS+$pE=dz%%z?*Y>cp0?f4(kxxOF(#%)I zEAkg%6xmE>Dh{>W6-~|BmC;c0H#q+mj`-y2Ypy1&fvdLn8mn++AoO#UQ!;SM$|j6P z8bK1PwJScf-3sMBuUKa9>nZ;jP=U0tzz>_H27WLEs@{MXogwZ>7*-TA_k>fCAmMV@ zP#H4%_xYZ=8Ra)kSF^!?J}rh>t=ujq=N1Tj0xvtlV0&YmACPZ6Ea9ZBZS>uiad22D zY8gAkfgsbKIyvNYsuez<`d48z#l@`gQQyF8?>2^H?uvfvAhmUClLe~!-~YtC3N6}l z7&aNaaHlLa$O$pv;3#-*Rnr;$?g{YQE@(dtLgj=%54*!>BkdFf`8&bHvCt|h9JArZ`gu9Vo8MRjS@uJsmhi*0N8Jf~ z_rP77I+rsi^d7CPOo`U;k4ydC!#LHU;Z!*9%~u|Ti=Ld%!^Ccqfp+X5J11cn^3otR zqbb&7`%GAy7aGpujq@8B?KZ0Ck)X5rYi8lMdCE_(2<^?gd)bV>P|mESwL9~kg9UY= zkfFu1|04Q7A1a(3t{Q2La4>2x95sR{rewKMooWwt=fjf7@Yo!D+za!@K*btN(Ab$r zFN5Ixkk1x~?0>R4*)Ca^(L)33U{Nl()v{Rb*alv;G8A0_h0SF3hOoaj^l1m58!*fA znvnJYhuiqoK6u4IMlUA90@oYadL(E9p`CtxG3aj&dM$=9$suYmBu)$|GeK69m~|D5 z3=i8z!zTMa$otN#1~IC_4j&XD2D$Pt$bTMoZGtBqV1Y|`XMNYZ-fyNUi$&Sx^chpa z(FO3uQyx0i-x4b?iwQf0(VzJsU2kY_Q|C$won69=F0i&dBzJVGAI$QUsuu5Dba-i0 zsbs)Qcx@t@Se~J#vse%$$^(sj6cpYJeYDqgu$!fSszCg zVTDOt=+@ZfJ}Md?`g`*mHKCMi%WGwx8P#(Ci{~y*pUJc@dIY~Y%Utua)3wcUz1@s2 zaXI+c`63PU(DIZ_4KV^Bl($^#dW+Y9)E?$?BOc5Ep}l1~o92rZ98?=pbb?hKA-px( zp2|Z{nN|i8dAIw;iSJBCx^u}O4)3&ru)e!KD>N(&FM2{GA9(eb!a)yn&4De=VV=+D z3zjj8F-NdFcbc_1{UEmWi0w!Ivxtm3`0n#u(8U5ohylCozbR%YW&|kY;onW5;&}K{ z3xeGh|DA=dCE)f#cy9}2&j_h1KuBCj(+(P%zgEv7s}I4r4WKshwLcx4aS7vkuc4rs z$$1s}nwhH>W4l+^vA5H=fsLi1=5%Ok_K*8;PGjP4l!vaiLkm0MM_0IODoR=ZQ?ejC ztX>X*uOOByc|R1cd*1~v`{Wad(G9{EguUJ~2V+6!`cT(w&2g0%?Xix2-PxChQ4hD%%|viK4&=`a+noM+I!Lk>ijRcR z)@w*qNZ1S_TmL=Vp_J9kJsVot1W$adj%^B)Q^Gr6TVa|?=7n3ap=?XYU?&Xe4ci|> z7}qh=O@7X18L<^cS-wx+GG=jzYm-JA3;oS*9+Q0{GNkZ{zce1B8HVwzv!r*ugIsx5 zPflTXj4cWyNhTiZz~xcP3Rld;UOIpJZ1;P z%mPQu)#Ndd#`|`k0=-AT9arAlt<%PP6gSyJE5a*dzIPE4PJnQB>XcJ3A~Q5LIX&7y zc2Bi1q=x z4TIw*@v6C6=NpqU!29v=EjFZfYflJtWTdhCK!APvz<_dk^Oj|xz*tDP0ls=lI%gTZ z4sKYof<2*?1=vs;0&>72d+4fd`^LjjhB3_e7P^keZqx);f7ceswE*h+ue#$FsXsL+G_sZ6og8yC{Hk?_u6U0p=CoD)DeESCpU(NS9M`c3drZRFQ^ee!#yg*c#q$g zw;0m&22juP?e?0WiEz0u)HYFp=i!A7UcU*f%n$i2OGd9n@-U!LfXpf;+$qF0YiXR5Uaw8n-{&{UR|1o9Vb3wTwu(lVxb(S9^ zVYUmKZ&J2f@HLhyq$b?3`D)*HR1pgJZ-Ki$u@+g#qn_8to*n3Ydpl{{mhikNEVZO# z?1Y2ZBIHw4zqD+0_?v46@8H8 zbke?K;JM51UKI+M&PuBwxnIcUo3O{}A@mj)KNB+VgQ-3cd%Ktel^Jcx2C+;|jcrhR z1}w7!a~sP`SGmb5WOb?z2AS9=2DCuJzPvOBaJ-= z9*l*j?#zNo;Bg7aS`tFS!+a0b!TH4#U_So%yy|fXmjSU~2gM|48>T8c`prnUb9Mp_getZzkug zfymRL$_5zk6;rFh!gSDb7DO=-H7CR72{3Uu9CCk5v#%nVwO3vda|MJe2CGeC zSQ@&lulDn=ap9W9+t&=f7}eVr@YuWkxe^9Phwf(Md2bjR6Asmbf4$L!gK)!><41;E zJ}!SIf&q4CDXVp>KV%pPed<6K+dD~ZxIYqxxufbE>9ITzbQlJjp<@PA-W2D`1TD=~ zgSoK4){E-QjRuqA-y$*U;u3n>dI=grKR3w>D>LdbG_}nN*jM|y!1mYhqY9Mq$xzVw zKHCuyCqo>QSlpOp3~8J%R1fIj1UWn<$q8t_7>XM1jHxgzDy(`AV>~5AN?+Rnq0DZqyzt4+ zZq*I)TiSrlFtZ+cnPK4<$A%;YVYsQ=oRl}lbY~RWnIF2|Fg4)OJ~(p@{;{<8tjyM= z5XUB5e;gLrz%{MH8*_E=1uXQ}=mTcFZw%Nz6bjlyu}Z;UcSS7A7|!($G~586m{+{- zCbLnj9XvDU6CELO2n>q=olMho6I6%gpPPm{n!E4VB>BsFVAsz8IKaC1KVHvs~nwe~DdCofD4gb4{so;EmXk7wg8f3R7Fx^`&G+{?3GvAo|j0QSs=j6#WR?F_SaQ%VIa@ujcuWZpUE1e;5%wj9GgY8cR48F-N6m&TmiAx!DuVZTZ(<)rgrQD9sSMDG019M-S&<>V`|bCBFxPj-wShxpA(Z(W(h~ZmfGVZPL6Vw`zPrHn zrt^GZXmS}Uc-Si^-%y6!WK_{r#ybZ&%y?{P9&cs-t^ltMZL0Te76I;Ohi|q(i%c+d z2&_H`ar_J@8jaE3d=Oz6Ol$}#l0mh!P__tk=>*Mf^h!>!+#Dn{yK6jUdqv1%VrRIl zqTOJfC*L>EIoujuJS^hcHid@ei@5J)O0G?Z3^C!@LU`o?oRvpTsX)U7dClvx8jcMoGynT%s6;G1x6)>o`!M9yZx*OZ#zS;X7JF%$cbRa zKKL{SdM|>>(z(`fZ!ObC21J*mxpbr;sj{=E1Y3e|bvas1^J`w|3ndysO_InvP;kyqL!0FsDz_l;&wHZ!-J1@LR!pw^- z_;LIAouMBt5BE#LbZZ?pCa2^o#;9u?h}H)#dCFfS;jDiJDN`6a*!h{)LN_m4Z8hun zgQymAu^XXwEzZko<(5B(N`WxUh77W;Kjnf*1|HvVTbupyURKv;E?N<;MTKTbAZiIH z-4pUS-*}fbz-L1{o3CO9C@}=yWP*S$u){Yx41z<+U~M6&Qvm7@hw%nk#R+1zhI^@D zR4nN22j0jTjDG0~|5@QfzR{)?j9LlH^1*S7oVOC(?g7(mhaRILyN54YLU<$1S{Uc%)q3Rut=#$07G z+^E94VJ9;BX!M~6Lgwjk+mjD^@`(vBxdT-7mdh;JTbF;O3l#IbR4?H2uaK-4v@uN) z?XZ&8a!r01;Z$)x!d^doA1;AGMzzE}^Tg;Eq=SwTpsXv;kOuns?CN?HwtDgwWA11+ z@}-BMx=^|t{Nc)Xo82rm;m#Zg^p+dDLw_%8Z2oST`@?Y|Vkzis0XCT8D5m{P6ljnW zdVB3Po96g-h_DVmJJp@WaP=`+3l+d9%UP&n`xJBKZC%WZ3Xrum6nEx#tzd6MXyxT4%p5Ah%U%ZbeXH?6!sQVDcMuR&Zt_gujeK@5o zY3FCS&#vja~ca<0p_3l9>*Z#y@-Z1_?DIK1&8c^CT7T_MOofbkCLZ!Gw zHLD1tc>l-ggRD}!c)U^4SyonqvzB0fcsOO?bxhAbDeV=FTEO>NaCI4s3xu2Lq4^}( zY#M8?g1okHw&u`q3|ukOh1Nr3Q}V+9J0HL1fn#wv{5}fu^@aN3cx{MLt#EB8d}dbi z%gB!>jB5Ias8M+teV7SjY=WhhrKWk=;_mA30hWh@PBvAtEb!U9{IDlJxuW@|{fx1M z_=lq)*PCSml&=F1vh&(j_r>+pu*lKgTo4ii2JDA3Euoj~zc4%}pK!hn10b&V7+{9l zyZjyQ$NFZY>tb(YXARB<$DFFP6HKwH_sc=!QqZO>47Qe6+`Q%dg=_Z#Mt^(C6}S6f z37P_DV#5h1h-?Kr8OEJYP}G(0^KmqPC8M!xU~^X3G#LI_4l%9e<}%Q(I#kR9O;$jf z>Upd3eoVW5%1Dxs4%>Q6*{x$9z(Lnhy!K zamsZ|mLmwJZi1#xFwWd(4hws_LE*Hp>n+?jIYAqtQb!n=0B**Bc+FseTWGcgsNfp` z8K7r)IOjda8hE*`aAi7FsRqdl!L(qgmJyztmyQeJgRzuK1i&SE3TF5L(80FtHHO3HKC}unfz0+=piOhf zgiSQ6lm#HP5gcp)VY+bHJfpAO4mKo)n-3v|RcId7a{x3M0y%t2m2%P( zCOe~>^Jq#q_Y7*9@nxN%L>)-tq_37biV2-B!C%RtTX^`}`>wnPwe!QTDIl~F1XYK6 zRbYlIAL~?4%zfFT5c?x^x9c8dfVI}+@f2ubCZ`vJH&%a!hq2B5R%Z!tf!$%Q_SlqIQL)mM2a#_--c0*>L-QgK(4K?S3e55sta&>d|25A^644 zuIvP{>O)emT~!qVY`EJ=A?AH7V!=^#?!SFQ>G-w2C&DDTNaM_u=S;25VpVJP9CaECW zRT!VZ(Ns8^6TT&c$yXq6b|`Br?==x+oV1zuy=b`mO++6j-8mZenB6O_;m$4Sy%dsI zg=X8~bs!}x?0t{cW)!+0qr+X`dQ1+BxDCR&aZ0-fyZS~Yix;vI;?;qq?V-O7658|f z7->ipn0NvKQC&i}AlSJ?Rzqyh8`1=( z4S{`rrW|&Hg0-REe0X3hPwEBZ?2;H(A)ndZ?G?ky!Sh-0-Y}~97@1=t9{W8kfw%lz z2FebEM=mDn4EQk=78&2DK5)hg-f))kVY#fk&zu|Qptw6=a4ksm7j(`5LG_@3r{uJt z)q6tiQqar7pYI44Enaj3YS9hqCxxL#8Y4PX?+f2t{%6CTF%704faDF}$0g|EEfXAq zhaI4kjnvL%O-c<AyE7} zq;oN4t->vHwRa9&83vKu6&K7}X{!)x8|-k`?)53q$}1K*+PezQPKPe<;O;B<&=AVo zP3z5l-ThFzI>hM=Ga^EYxDdmWkGg~(3n8M3Xmb>1--oX*A+AL}>OTu2cZcgHHqIF6 zl?^WRfWN0eY8#|;MtHghQhDD-W_OLJe7EK&8bd`3ki{J}`Xp3#r~DfT5B%c)G&7_2 z8zF%=ZzQLdL*PiL85^ohf^w^2g-v+R9x8Aep09(YMs?fDw8#%%ebPL#s$sH1z;Gzt z9Qr4PW;V#Rp>XgRM63hrxnfJ(PO4|Ji+r#oj zy`{a;Z7SrL2;XhTH$^?PH(D)%B!;`dyS*_@_b)?pli0QxEOpY>X&}3g!_aQn1?5Rj zVwWqh#&R1z0?5+=w2AV$pX7)L!4_cO@=OnnMokA=Y7rt z6H7z<1@O%R%r))R`ubW6NE-s>E%zUh8Ljh*O>^L|CztC3O}j(YM3AW_1n-38>7cv0 zYE&5N*|CrFLwH%_8zE+6Wd*3{e5FUgC=-^_T6PH!!@aDbZ8q4YKFkPjI>YZ~?Q={h zZI{g!2A>wD{Vb(J`;sX4byDA*$N<_e|JZ<2#oO_DzS+IidCo zIOKfytohTaFgYsp=>enM5KTV94yW2t9wv{57PiXiuF%M5`_8$HGP%k{Ga-+8-sKf3 zDnn|YnE$%0>MpQUEU0Hudb!H7hMVUJjI;VDT~^qXuq8ZHGQNM?!cNn^+Ni$yKnckQ zHOxz^)I_l1H%4zN!l~%6%f3Gn5jMYqK>suF+1BH%L6++R&wcQu-2ng9f@k|6rhimj z(UVc5V-UI!G;xDHObC74DRpdtu%}>PLHMx+svm(pwc+vv=<5EM@5y7#cn%*5qs?x} zX2@3zhE9Zg^I?5BNHQ0iR)Kf=9kIugBq)ClnUJ`g}vitRi+%=(ZelGjv3OqNRw<|!| zA&{W;|9^?g=-!*}v^(wNx2d6zxeWH|b;gjybyl$D&e%3fJzSI>5(UBNm2jaO%<{?c zV?3j(ZlaiDA%_V_HxOcEgBPAR#i?GNhGci4gI9E^56A6^GqE5-4yO9%W%Z4q*LFxd z4{H1l(|v7gCfM)V*SUntTj6gL|GfrOO$M#J(Fi{Znk|G5A@G~Yi|cEhOnkP6(8c18 zehVc`cSbvK{V;gf5xUx+OYNtZIid7f_;&~7bn8^P16}vQkh&0iINUU}>89ya9*E~C zNqG3^QV*KCg#M~k!ZckmiNBic`0n(aCSr~Ss^V+?ZPEw(A@ocrW~YYor@Ri<`lxMq zVF7$HYYkjNWAnT^I=uCHJHkY~-v~wHLKSl`+j4&>31=F^NqgeJWVq>~)BfARcs zjZu@L(8z#><%57$@Od2ciw}=lK-4Bsz9JN~Mq_S6bN`)R!^Yj67dCmy?Zq(LL=2D5 zyRV8dn)xRbtPHzd(WW(!b2%)xbAA}<(*OwLEI+LNgT8Rg8@0;?u?|30%M+LmuJwZ4 zjo`bpY}^C?+=3I$xn;@BjN(UvT_)mNS7_N3&Uy1%HbW7c@VI~CtvrKKn}JZl54`U7 z?tetR?gFb9XM;QS7d&gvhZ0^LpBqQvmlBA<}p$nYgUl3TadUb)qpoJ7LNIK(2W8D#L9d8%6waHMYY!Zm_OkA+7w)|KHK0IAm}ya( zRfZZHAo3)b;~zY?uVr+mE=>9cKhMLyS6a@wtN_ zTR$k>8Qu?ogl28Ox2*0h$G8I`)?*aLR>{*F&e>)^{{NF&UEXc$5`H9wluIB(PNOkJ;(}7WA%UxzSG_YDN zvhl{XdyEdXfcfSsx#fZU+C@8&~H+u-WLCozcmIuzEaP1BaLiM`L@W@ zJ1sOj2ffVDZ+?Uqb(XG%@pv5syTG5;C~qrhT@Jdqgys`q&T0sJ46VJaLocYb5;~`Y zQ~n~`hNfxXC3vvSx2ZlQ}PBv`~Uv|rX-`aHrhjH z`8*#6x{~xJs`3cP-2uv&kA{}2qPa|DSGF;=yPQ6&OB`z62AQ5SHQ?(BDCojIdBcBL283+WBvDKfvfJgQ==hgHkh6QR_28V?Vz(Q*F1>P zuA=bVCs9jdT0S>9WhO$#yqDJq%!S^{KLw7`>$?6Xk_tzj)bD+;9P!)I|u^iK}@$(Pj6Ju_);u@ zBSV;A|93|FOk&q0@Y$C7-446k9zG_7(l;TVGY6TR21Z|f1XMT&D~7>+pC%`!!9iD< zAQUq<8J1WsHJ+t=2>6;G&Q9gS2a5K@_-Y?tA%1 zybHEKeQy+K?xT)}C#hkG{d{mVgmKjAF^sZ{J5Pi|rQu-&sBa6TNC1;c!3f{jp9dD$ z;~5+cj0ht~!Hw>4#CAMh5k~lLuBEQ%jP>nod=t{}TJ9K(X3vB?-lJYiC=eBz`Uv0Y zwTZ0nHCuj$yQj%4Sl$SVo`ypMVOA^Xyc&}FKfErofKkF45Um14v{gDd)fcMJzD#hC z8SIn-!r4?O%lVeco0J>k+rlX<%UyS2ToZaZJG5KnYdxU!P>8n)D#nHuHssqfu-WuX z%>dU1!4MZ4Fb7uq-zCNF$f(>(2yvYOp<#j%6nE0?)gXfFoVOFk$AS*F$c1KHdvqzI zSJmNgBn~4lWVB{F9I6FT?2b#1;H@2fvH=XW+xDi0%`U6?Gzgds$=ksu*LFECY|IFe zJ#1DA);EF6ZjQXgV5u>Wstpf9AVyNC^cKdMu>8ZIh~I<)+ITnvMvj3}0T7`*>~01f z?Wew`oQa@5&yaO{we~YP3JD3Kas3Ld}m2_5H7jsHxnSK zYwPwae5(YNJf&>~s5KY9_?(Zj4)WM?Jt{+FlT*zWm{AO;YKWXljhH6f~Ity&-17+jDVi)sU ze+V>x5$nU>^<@uWpU!-QjZ&IOt_xt-{tT@YDQ-)Z^Nu)fhD?44H#rrfoLl7Z~k2_E@b} zqhOvv);JDVhr_Wzm|~v4SdSpPtw%(B?>Ty$eUZ3_`w!tI>!>@A$#1?AR4);bU)4~*Xq zb^WXxHNy#hWi-i0M$tu3E+?-A?O@c)fXXz5dr{$A!~g#V*I*Ch_(px!8RNMXZ=`@e zZiM*muJ7JukZYfu3;y*6`F)B_I0f5%%p`3D&uzZhFQI|~Ppt?|Gr{%$N3)F4AVXT~ zW%oqaDManX8}r*R+7TD}TdL5`9L*)n zb(McuuL7s0U=KM z+GoQL3m(@_sL=s}&DHTaQ0M=hFq6?VpBxnoJfe$PY}F5Eg<6)UpHU@nzIU-8R4Pc~ z1nqod#bn5`6-LK|v+E&cJ{agMJ!eB?(-hTzTc%sh=v86}F_savpo>3DwXy?~o0lYR ztc)}GbkxMQy$DbD!-BVvwlVDXMu(F@Yxmi+7%(*teFb5QW4(&g}htn|cHe9gCbG+h+d*+6%a&9=3 zst*N*zymWh$@mIex9tlcml4b@43}#|9M{&oC`>lvFI_@b+w5s`h&K>Yl!gKRk>iL7 zn--Q)Pxo8Kq>NskV3f5a0dNCyg}he69U9&E4*dyV5@k>|yX10Qz7_Z85h24o%!ITk~!D)8O&CQO4%mEn&9@Ny^w1VPj+ zFeMmf?t{BN6lRrxD3_siMo1kS!nK3VpWs*Xe6%5)>j}ABR+6mnaUwKX1*HuryOo)^ z4fZ+x!%W0{)>i&%TfCB!q*wYWbTBu1*aKvPHstQdEJRm8Iu|~yB_9&MX*Z!N- ziAnDm^Xg_$A~c6HY@{)x;8(vCe_Fz5O#?B+Ds z20X6@>1~h=o|p6}^5ONKf=w|FfBD~w^}16bMonyj4~L|tIsg8J=``2$rAAH7N>e+ zR8c*pqI>Ih1c+(Bw5ci9vfXlsX7Rpl<+4#T8TEJtkuBqtF_6;buYL-po$u2D$Y*6g&lWsHGPz2IiqmS-|^scRxv6Slu zPs&n{xf>X@upJBSgz^huOdFWvh8KpOu%fk`ZLTu4;EmQUq1 zVF)~RMgJPrVHX|k285h~XP!c9@VQkFTHS|q{!{!`AOv>hFpMp*%O1~>5_Wcg+i_vD zxsMSUo>hckbM?u`&HFmAbS|_k0hJ0v^Yn0_IE0jf-;6Ywu}muluhKzoJ9cVPM)PAZ zO22|pXgBc>m+-bJe6WYs?t>(4p@oMrhd?ne8+irxHHOoMd-fbWt_*qXrdjpjjrC~o z5}wrI9_>0Z>g#-K%EAhpYvz3D?NX~-+NiBzRe89*i!0`=XSBf7MKYc1szcO=5VuKqi_ zM-xW7pTN^FkjK9`|*B~p6h7IN*yd8Vi!(84sc3nEBZf!_cIAb&1GoVy7MQ;O&Xg`{-UkBB+ArR+{usz?H@%DsOHET~Z~3Pabn!+( zi3qo}b*no8Zs&l1D#1kiAcko=F&Cnlh*KwgEfsw43wwvdp;3hqyZ+ovJAD;it_mK#+y(>~uS9OwXv{eT=>h0)$uu<{+GGM1F{ z;H#O;Y$qlz42#>s=pwKt8`SaJ*DZI&gm@5QDT+B&x^mFlB#w*#O*g^kf$%Uod@l== zKfs7a5SR-p$A%+b(Jl{M_Lgy6;BfQz!U8NZO#$X*T3Q%&3jX!A2=$>=Z5S=pdcfKO z(9(u$N#HC=qrsbe z9wvhkt6_T==o*1U1eRiSrxv62ZkGoZIcXMXXW@sWfzww1NCQZ2q;;pmQb*0xK|hyu z^deko2sPa#-)ytcZpo&HA+1e4$Yk%gs#Wcw@6BL}E%5RTOxz0Le4~Na_VSj06@=aRw%BILmU^Rqs_lS5MBp7KKYdnLG-64tBuCnz)xdYPsQ+V`|jN%yS+^%rWG!=RY6XQdV z7I49OoR|&QOnX!tJ$Vv1X&=O~H|n`@o==AKRpG18_LjEA4Vz}Ce=b|<^XmIt$nEm; z%!844;g~aT*#~XyoGtc2hn?{15+wfxJgR;cqr#5-G(oWHZF%-E}>&G z*z8g-dqv8(5ah?sHTOrB-q6wp9+eBeM}>l(+|zEaZL8F?|Gu01juvWWW9~7u6Qg`D z;hFVK`X4m5BYv9B6Na0v9aJ!kYPRyuLNI7QtaFt$#z5T=*kjXFF?FqLz-(jw*Y??H zcCXEWk&hu_N{Ch+em;UdF5%pI2y}~Yobmr(;x?XOJShqE_c>qcARNw4z(;2?%3lkT zHHIc}-~!hKe@hO3d(*_-Ij@wj9gPjU-a}pIzUabQ#f9-MEN}-@^oh{%JoIS@|3!dN z{UFOwnCU2}1Khg8q?66>?BcXvyu*t91G4e7BF-KS2 znT_i~BXc>p82n;)l&~yy%xV}bGA|VbwBy?3=JKmKXlmjg#DKK-U}+gxVY8faf}!2v zOHRnT6moZg-Dab!=`Lw;^EQGKX1a~16zR$InL09xnHG||+4{tU3KMwaL?eisn!`zp z7)>`rX|6;65*$|ln^EZc9{O?9%$4se3$Ofk5#ME%YX--gb9mGIJ=qOqrb38aSaim8s7E z$tX%RxaYr_PZffmH91`A{x0A~yfGUBPQm(K>ULtpHT+3yZx`#__Pq9*=0u7Z*bm_uI;EkRmTcweWN8)0D=t zCn99GbJn_;$R_NqW$a`@gZ%}t&{;+`%}ahyz7qgr{YPl=v9R4BM_-0-?I8a^DC340 z(~nW;3BGm^^3;Yy*6q?Y=x$XrH-S(kIr)rxwXmD1qABSquZ-^(Kg|Dr!)RG_IF$%e zjN!FQX&4>16RWwm;$`8rPXRF5AfMEM5q^LM{e*FLao$=m&u2-GNHE=BWdGdA=$GzL zz-PqFzkH(}Om%{5g&>s$4YB4~i$mzhFwWe^?+@oJSuVHGozrmHr_`V#FxNyhaK6m` zBspv}qnw8z%}{ur31a&JI?D)>zJpl)J2l@@M)!>6h#eNswuo2;(shI7ogn;G_~AWv z+=or8;i`QaqZJc;9LA`J|LXj?fKkpV(7go=u!3VNL3>Lv(fD%MD%-5ly!a5y-_$Sk zX4E(z{23d{`|hmhd=LN7jL|mx>b<3CeF-YL#p}9tw_kw|PJhajocIlzKZn}upq^j; zCZA-~b|IvPG(SX&MvG=Vz8*;jYNshw1tYbcD)-8f0!(jSVsOhpEx~yF5p`R%(uo%ANf#-8! ziW%zRL%&KMVtHiXwL8P1ix6y!eoqfAdqDBJ5aU-EXMD}Fz@v;%-IzyagZLep<@qT` zlOekGh-nj68xE;_RDGHUi+Vwhd=Tn5tgs5_&%hy*U9%f}GVt^E%SN|u2|sZ%#)l`P zpqZD&e*`Jb-(_R2Z;Eg4fnp)>!IZ3@1EI^qyTWkMZdz(0np@vJ^`WIJDv}h!#3K66 zGZ`H!1Fup*6@MCBX!G~?vTlbUw4sez0%ht!+!fFz0vta99r{AYTd=MeB&`TvOk&~Y zP|D}&Jxjav1N{37^tSNB{qy9uu8cO`hJ5C z{m5!+&8r7N2b<=Pyl~I8mCXg~MnC~e@n<85ZtjchhhFF4lL;H-6&rneM{-L}zX`d# z@A|T^z#pKJ4`vj05Tw`wWphH!q7XkbOxOq6JiJ~5)|P@vmMp9d93>WH8VBWez%jR4 zqz^odX4m5I9p^bAeCq!P1_v)%%v24G&LqUXg>owhkiw3BRX?TZ!P`X%M$BbhdqxZh#+l;*%K= zVH1S*@mkP6$YkJs8o>U);o%UN(H>^IeAKRJB&w)<1)D;s^+0XqF z7UhM_pEesA?`X`+{oKz|ol*JTuxu}f>7y}9F&>KBdOZt6u|n|7!vN!3J{%Huhjmln zssUxNS$}cTSCt{leCTD?-b{k5Rp3f0`0P|E{=fZ9>^iTV^%o3`#?8M>WfY|?OtQ^- z9fd}_Ad3^Ma7C+a%(m8YxKp*R25;g+#$#|NFSOhOAI#qXC)oG_q8sTu^E`eLb@C8)|_EEkwRh{I-27`3pele)kMvtUjs2%QT;?n2AdP|wcEvla5T zfl6zk@*$|-5_-mFsyM$eN`D=y`>0xNEkoaiqsG_046J_(19w1}KH@JS2i`E+wHwxW z-)Z($upN=O8AN;yX)Vg>oRDBSWX=Ii(nCJ?N0SFI#b3xrxY=vQfoV4IF)urI7Irm- zSXTP(1gP&iUO7RPG*HL~N|00Kyac1nZflD?$||%ls#BeygwLV5&ez6MzL$n1*0*+j zDCGo|l0%ACaIORtn+-Gk=2qX7%=NViS>Rn($WRByErik5vPUAwR2zPps}D`!uXS+i z|6NyrQR@Uub<;M>a2-M!-}=0~R@iz(p9uThDZN`mNOg!61$w%f8s~>jSKz+gInQi7 zGehM(Ja1HeQp0yschlGU9frp?&8j<$R=Gbeo`bo;Ft`+N%&5ian(N)w2T~b*Rco}< zH$u6rcdop1c&O^kQLe!+*B@`})PA)%ud{)n)uAfxJDR>WG4 zaOQxu`UDv1>hvo7?O7qgsz)L)X z?iQuIla36{c|(>l+FlM8w1l-W;Q9ubkrR%Ogv{mPmPJYDSK`;Esgl1l{n`fhjN-70 zg@0vEi~3LaN23|-Gxu?(KtFfXYvU{VJL^d7eCK_wU2`Z`6YidXfSHhRCG0v1KTJuE zD)7eMIO{robcEL#p@>(Eu?nlsL)~9s<3%`b1Mf533R~e=3kdoP?j3-s*0*dI81@#L zrh^ks(Ab&(^LfyB9RyT_n%SVPfp5qGSM1X$?v!5L;Ye<{WP8sU2!+}~8#8{|6*V;G z`DNj1FGyULydRGr*00FxTcvWr|alf=)(IV=DaR;hRNJ-&>A! z_q2DuJGM$;qq;{2(Vc!D?y2@p}UCg=GP+~d^^GBFu zekt#5VvnVQ%VT}l7D!;$Iv8Z>lkhP+^f$C#;~-8DT(7~kbL;;9m$(sTD{vmPEdrT+ zL?yHXtGU?Jwp_g7u;C?aF(0|wLf-MvA_?sI2IV$EY`4xdcg+a1`o%|7Nk7QScVHAb z1pZqK;jZ%9`Yep%&W0fWL6_$kqg7V@h|6y3Xx&Wc=5i(`fHdDZuis`y<;{LhOLgD< zUB=$&whJoEfg@Yskd3y{Mtc+izU6{sraP)laQ`7wt$xhtu6Jv1YR}w(Jw2dk3#d~P zvIRpbn>qYq7;QD%c*{BIp+x|k83Yri!h&uP-(GJ`d86I_qKFeT)<+)b{qB_AM9|2nrK&8}>+ghG7C6QA> z2{YMgCmi;{x!1LIya~Gx!GJa%9*6C5;hkLE2>ZS7?jumcYiG2A>y4qKT^XtlBz*(> zdO@wE5N0HVdj~W6z)sgY!1-F9fDMb_fN#`xheR&~%^JX!voPTnT=Lmkd+PhMroK{llPsbvS5fGh9}wq3~iWpo5kr%MFH(ZPa%dL5ij4W zfXR8|%8UMlh-2W!NvJao3halVHSpMg=1hQ^7oopj&@Wh-CeGZxEi}px3!*|I7Z|Am zEVeuiHbJ@Q(8R30FgYzt!QWFMy}93EWu_&AHK`%rIG7m|qPK)FuDnhWZrLasqc!%y zjqT7R7yJwZg}nK`j=tu%ftafqt;)jay3d@!y&2tg`Khen-pi1}w3j>u*V92}3vl}n zn41O;mWCo;JAOUrlt1Mn|=r6cxx7V2so3g@VLpyI7 z|85Njd@ag)NH+uOIzdmD5M&}w+I5lLu*LI3o4WAaT87KP2U$ncd9#YkPs%8G2Yj}h zPC9+wE0C-(tnfGHYik+(xeHPn(5?26$y35thhz8Qk6Q4+_)2@rHQgX{N@$fB;`WAZ zeYkIm9E@iAt-qq*=Z2=`u=^-zY_g9!U*l!4!dBU5I%62=nO2a@j=0wk3M_#isUUeX zSQG@U{JT+F>yh6?3>gcf?ASa_Aj@*->l@{&!gtsE&X|u_ylJ)Jp}n@x8@2VbCx(f* zZR+C3fKEP}uDO_5eh@VJ0NotDG@xGBpreF0=GVseCK#SAC8}_yc(km40?GXc``$;4 zQu&}*YMN4-(*=v*$_jW|3hM5ItyQ37W2jXbK2L=xhI`KT-kg!CT6*8So#38Xn_d7` z8+}8cgfj|3-tMs9R<7O~qLzbxzP6(sG&0itt|OkEbE^b2X%1aWL$Hl>-dUzwyf6cy z*9gdO1Z(2J;V6XBI3lCnnW1b5y(83ZxR zRb3nDc5#^X1B!UC(Po4*uewT){h>e&=;~VgWAZh2pv4-X(bKwkly>^7e-9EA#6SmJvxKG>gIZa zsPt60r{1XF8_ZSTMr+||5}caNbpw@+F501o+<7hUHtceSAz9FQE)>=8w`9%vSXrX+ zo8!vdDydEzmm|-Xw7%Ru`XFZ`9U}_O^nV|G?e|f}2AX)x&)mk;z1` zC=TbJLak63mIWn8!cUzY(SwU0D5uTGz;o@7>*v5f77TQ^WG&i9T|6WkOjXeP`b^nq z1MY)ilG^7+Dx9Cic!jm2dTV~K5@4jFr5Zj*mFXAGB^midkJZ@~8WDYoCkodko$A29 zDey~6SmMKpVWu!q`>o$c$XD)LYJS`F0Ek@zeyZ=8@&4d8beOm<`)O*GS}l`wq;Ts43qTKRu!)?2Pny06gZd2?Mnqbpnp z<#4JOuwgUoy#iCOv8`HaYfLW*n_7dHlKoWqE71c^scnm`2BUbm zp!*sq<36L|tY#Ip6Nc+ybkZ1H$3rL0DnLKtLRH2Es`=;u@D(k3!@zQITaDgN>y6Y0 zeYhi$UmeKQGq(I~qIGAWKgr?$t0A^N@eAE*qh@WZXTL`iD53fnQT7WrhIR9xO=&ox zi`Qv}t^A>d%95w|j`igR0dI-cs26wW$&sYm1Zj1-=OOC6ovC7Pm9YYOBqI%jZWeUN` zj!^SH_&dOE-Ewz%sIKm~ya>i?y8h+B%>_PbMb27pq2cgUd!_s|qAX?KX#upV26t6| z@Ahy-)r?rmbsKbD=qp%g0ttHLolyPDX{ImQb4hv#(X;t5S9Q%-+8HQMI{TXJ_ z-Wx_l!oFrObpV9agU81p>mv-%Yw23=LVd=6QFHBxT&XSYiFXdMTwqHC5jpe z%{ASZ+o8YuD%udb>O@E}IJz5JO@T$$FjjT@-~_ewTG1d_uOtqs0#)hQ`ws@`Lp4!F*`*$TplYqu{7jOdYXqF{ z4!yPVN*exFXQ-n|K1zcMs?h@tx@ZRciiKf^;lxC6Q~`?Kh4hI$3yp>l{ZamYRRw2t zPJkX(6}6ZLTA)K4n5#dKEz=A#%%STqh^oqK^$Rh|YGpDb8D6Uo3fjX1tz(*ca)oBv zTQjKBnAh59_A@oB_3dHH516cs-%fW#80nT?)44IJQ%e&T<=N%ZjDwJ5Tk0@_2S}2N?7GS zW~f!ZQ~rwR$J%MJ?hhSxU7vSQS(iN05^OY~-THN~Fp8+8 z8o0b>HT*H;AB5fddRJAIX{I#&*9OYZhpeG6^B6?wMw6Gp8MWvlGq`2P+kyuZm0tjR zHPnhq;G))ZP&*#btlFv+4fQ}V)DnhWeWQ8@@#L07bd z5Y5WM3eIcJ7IVS!04(1E)3(8|)v)3?w3`P*GU2~N@Sz~s4T9ruASwgwqnXf6{er9Q z!eLcadXE~Zfg`+AB3>rI78PZk=HjG{?V!WGPS7O;Vj969O|pO{{zvurI||Y@Q%}|M zfL_Zu3EpaurYfkv7Yx@^Wpogc^;X9(MJBAhl2O8n~t&pV$-D z6o>b=@M|~hxBy<;!KoVbtqy-Qa`-v0)eKtd9#Q%%E28`@Yyd;!VZ7#2)D=RTfx%)J zt}ZDkOs7M8EvCBzQ>zp}6dD76*25#+ys=ifb`WP5{wBJlefd-stegn1eIdLnnCnxr zb1>2HIZ#;72!GxDv^MNktt~`d*HG;L&6fh zwi&KkLyEfd$5zNvOXcr_Ol_f5)y-V9Z=^@nS?z_39ihGIG1?B?#=!2*;APLnU$vOZ zt%+)=3jNiNzvE!=Se^&VmJ(T3g0mWB-yV3I4X!(2>uUJz59c(~YASL=Pk36H@vdl< z5voGDR&ZQ@5S$l9bWTl^s%G%Dfz#$-m;&SXa>)oaT+%~Ws7JwLQ=(}@VB}hGP@yKO z+@(x7TT~02s=|lX=WvD=Xs!8GSMORxLeH^q%m>D4fv@!VZ`+8d=w3+Z2cOiA!!?6d zD$h#&w-4hg5WPDOg;ZL%!{FKsc4-IX7lX_7!9Ez)YUH`PWr50YPyexIZgKKA>MV!1 zGC92M1kJSQSQUPpGk8sbU=JA57|toXmGyZPr?wrYiKqOA>zaMC-rKA)gLYGg6?cc8 zDqcg~{BbxKssJra;Dvse*qtEStceeN3Wq&6+9hB0BJ*_^drcLa71uXQJvp}_q zrOu9Q!(pw~L>u(ldNr4!wx7j7Sf(<**##pz!G%O9tX$cQfKowF?-yL~f;!uvyAwPc z27h`(LyfXPqcknYjeNC^?U!J+zUKt0o3gq?xbCt42z)Yw;VO!?HC%WIeQSc3D^ye; zY+kQuBNWtE_M@Rh8(zZ`4Un#67uMObo#C1uksX^L1!l6dIZBh);%X}!PhFf3dYqi;YioSX=u>fNCQx#VnJqDo0HdK^sB zhPb6)B8h5&#adQnHBuw>WJecB&?iZArG2mwgz6qHYKB(2M>{<-_SS-}>e$jsL z8?vA1?_@Y>1$FflxNHggZQznE^lA^*<-k-!8S0;|%M~Wt>IUO3L#M5>^yH(o2G2JyTJvF|wC*ptX!MIJr_ zrcZ@dJz(%&up18(E5YG?@LI)l)1dtiK_h+lxu{D9sDkUB!c8MKUE5-?`ZI@ddbn*E zM07>{H#idtD)*oJb7E;hqCOR&@jO`E0Y>Z3Y;_wEm8lF57eNno=X^C>m!q)Q9%8j2 ze&&I31n(HxO|LbC=bF%tboe_KI>bS^Zgfb0S}mdF$GJnI`elvEn55Zf=#SZHT7p3= zd{RyitKt0SfOTWI-WR$jgKZb^*Ci?1OpUaeDzAd$O6O_~Z$1=uZHGit_@PDriiWh| z@I{+sgBcW87tb#Vnd-WTU>Ku!#A|<4uMKU(V4z;By9U~59XFJSHUr?CAp~eKUsR|} zwZ&X5t6NK0Gav4r0arDgrKWZ_0K8OCJ0ECm1zWY4m))sbQ*~Wz2CSV9xf*4wl3mao z%2+^GeZwoE7C2pm$W{B}-A=HW25m>eVKrgt0i128v&B>jL)EQ@mjAjVEQx~>`iAmT zf3?il$WGg!i^_da`D?udI%+3-Xn^yxV4_xZV;sEkhC3sm=L#rv01BUlokn1(oVHP4 zg|~vy>g+nIzK6c)ztda}E{ANbcgO#8pz_>*0jJdh&$Tb_s=i;E^Nz`riIOA!|ChK0 zLBxp*V2HZ%ojTA)=RXT3EyDvY$`v&9vDGGBnq4j%VZF4&2 zUISk1ua=vw<$LRHF4@p>4?NM-%4>&AafeCzf?gq$=xr1j=-bquNksGY3pi>5k&7l& zNtLUoHjJDCuBylu<>19`sH{s4DU+YaKwJ~(8U{~-!N?9~O=P_HZ4~J{#hnDA`?F!Y zMk&1!CUyp&6fpCJ%j(KjYNaGi{IUZ~)7dwh!6J}RJffgT6%Nm=27B#`s>v`~J$A?v zx|f5DO~~KDg9? zitl;ttor%P|4X)%=%h+36h$GTu%7@U-__3D!2|NrZ|=CVZZxNry_Yi$#B zOW*&Xk`0ViHikBZQX2HCI-%L0PwxW=$`K2il`zyoQwXn7+m)K}l&$Xgk8=$Rn+DIE`iQ1>W9~_B<<&)rs zp2iV+NBb7Mw_iHZ%sP;^1rm)Q#u@(ggDbb7WgW8N9RXK~s%S+6tL?uVPjxn%K5qF>cvoVuhzE_p7X-$2vXaA=eXhl}#s-E5+m z*N~pZSy#OyN3}Fi%daU7rh5AHI0X+3;p!E5ycsSGfP^+sShIhsuhvy>5;?0-fl7&^ zqHcGfeNWD=oK0lD6C6~4#+szP_F%8Z&{w1MQ42(x!xjzIsRg`JQSSDKB`R41_2jN& zuvi=0QT=!8Bm{au6RmgbRA`e5b}zuWGc?zZN}9nm3iKrEn+p%L%5*yjuShmZ|0BAs z^%``Cb<5zVw&?-gcdk3!-44a{oZRvm+AfC5T_IA}UFrbGwGpdZLYV$UGFgKC! zRo}? zo*aUdM;xBfuAQidN1vY%ei-V`1rME_-3gX|0>hzDV+wDpG6X{Pb$dZ3uN`Skp7-}6 zIxz*NYQ1JfAyn&_rv6Lr2=;DJKxe!A^Ns|~xt}`wrREnB3?92-qw;*U6)Zgi+23H0 zdc(sChKj#I5U)lGwt+k)$1Du~9f2a6#s=-~1)fko2TuKh%;xZZ9pot+H($a-6>p_B zY#E(BR0DD@!&4Q$QwsP_hX0h#vRTkUZ_8H0HLb=vwkXBr^xp^6(lj>qg^F6fpORBT z{|w^147yHs4uy|ud8ga3MDybVk;OECc`MK3ZbS*=WN?FM17aPc6V)M228udM50o56}ckf4rjRS1TtuLkXcOkEsQ8@8$ny;|uJjG7Lo zPm_{a9z?fv^A>8eMVjvX6L7*Aa+K_3-PisVd{c+nXM)SZFb`zC;mPsYC0I^G==fXWK?m;Zwp)0vE`KZ>JwpK54fN&q5+0P6E&e;`au`2 zU+pzDfOR5F8o=T5i$w2&;GjnFs|fqlNE021s@EY})B$?gakxZP=&n{-sDcjD@{j4_ zCt6^a4EWcTL*M#Dw#suur71;)icrmaR)TeEII~mGUVWc62nuRer;MP-2IzMPHdcY< zy4Y_T1e}J@5)fq%?L^b6?25yh&}3oa33oNM=MkJ35Jhxn9Jp#(o=u=f7V~SazE2wp zW=iavxiF&|jNb=+cfdzOu8Z;~y8INJXTp_m2n~eNH(->i6;v6%YJnxL!GlduwG~uK z2h$wL=>l0w-LeQ+J`!fHV)!ZLi8g(N@9ItieLZ*7dM7J6hU;OR+NYxuk*fhZ=sWcm zmF$oj)6sy#s=E2V`EbLC|5PJaQ=6Iz$r`0d8_3qy4bg{x!wE!2y4yupxTJbi(z0&U zB4I_GiCU}yD_gj(yrig4N5?=!8aSvtPgMBEs#|^4d}|=w(ce>gX}X(d!9y)I+?3bM zR}(d=1D=-Pr>*;ZAv_I+y^4Ic!>nOkT%s>gycfi5g*Ez*+iGfeKVASo-ommu@bMcY zXTwJILC2*KsY%vf0h=PBlSV200d`ymPu-)p$}?GKe=cU^B^E^X1K@9aFinIbogjTF z+32QK4)lR=b;NNsQa7DVvw}&Tp`3PT4|k}p*2~o;VZQg=uuh}Y{U%h$lsftoWTjR(oi0R8~CjE(K?AHnPP+R4ykaCrL92zMb z&$Xhw^N?8uUM*(O$tFbadx3}c~qZ+ zz;zVSq%26(bQ6jYja~$yEjXK_yS-5k9v^_KXJD&Jai${tQs4j3VuomQdZ|U{&IaFi z@KM_|L7iPwKUNBtBzhYNEoO3PsK<@l5SZ5oPN?v|)ied2;9&wdYyngKn?&$gqV$i@ zP*Yp@5=L2re;jO5X?Lj<&K01mreXL8E~=?*HJ7oY!MGAbWhr4rwXv=BEqAaX(T{wX zs<*jUgYylbTUYSVpvwxvVP$AVVcs!Qlf1AKE-!|K%J^=zRK-}%UK>Qzxfk@)J4ULs z4>uBhP^FD0fO{J#s&3ln%-JsbDioK>;q+WE(3kg+O^~F!Emod?t43M&P*;0v^CNhy z)J<#5C1tgRDmR3SI=eu>XU;kjCC-82l{x%!fhfK{QKF`?u`w8_jIIYErWx3cg)b^k zjm9w2)xTJBdD*fk)bno3(Y* z_1v(w0zb8Kjft@L8lW$@3;DR}ryMmSKk(&*l^(i^Pj_7q&i7?+DafOs>Fy$uLSwy}cdY>4CS*4UE-)zuK`^8>j#^ zG}CQ*Zanx7^^}cuO5&P)h}3vaA<#wZn9&d3t%oA^@Vq_@RQq_UMXPm#D|2D$eAt}; zdFs0P?Z89H-m8xZhr>ioH9$~27^~bhbn*NHFmVF()>p7@t%<(#M<@Q9xJYH+s5or) zg3vQiV-xJxv+MF^sH+Tqcn#5dt(NXL+X{S@GN)HC_!uYC}rF-ag^be#bM#Z5KPyJ#5o2!3sYdY@t2YPiuHqSW*@noAF5#j5hWqS3BDx3&VnrFS`Lw?CS<5qxvRXGXc`+;l#a@CHFem-RESdnCOX49 z)u_-I28fR59z!%xC#(snA?gu|c7M9s3G z;!wDw3_VdgKm3Jq-e9R8&VBuf%G$vAAXuc~-HLG{+nwlAHq(gE+iJ$c?@mxz*R@ii z7U~{j#zMDwV6q6VyoMs(!D>1TbcCuZ*~Q-w+JTWbY58{A&}&qRv9qCiOL(F6uF%=h zHK9oa7kfIvuZbMq9|8_~gsx}^H8kiFm3y=D5_u2$su|`T2Fq-?sqrk-%Kr9n=M;qa zGhRhcqO#MVwklY34fyG`Z+cFdstSu;;o3!r90oJgNE>x=uvV0((z@%@`Km0k`|vOXkxK@a^>vHC-F zWj=Rn9zm39MwH%wsMiYka0rg>1S1`$JcC=6;F)S!OxwU#DGBQht=scnUt=PVG^nR4 z4BiKQLcv$>=&xK|_zr13VY9L^Q`HX&hZcI$G^s&!Q+0Fq1=F(d@GErGptZX}J$1=h zEh|UQs}9QK43)N%l5@ZWdg;@we=DMzi{P-**(r{wv<=)|2(vE1#}iO_5@&zu2Topn zQqso@cHZHHMIRVv!3jg{tc(jyq)_aue8&h25he%>vG}gCU;K`<)^^OB&fTziHaoCGbR=Br#M^%B*I)0=9A?ylEvk8QJ;zV0j2%0}NL?JSM3k`O#LD+XiJF?1 z`oLU;>Z1y#^anr9{-o;Lcm@n?51-ti(|@pD`8$;bHy<+8lgUH}bl>_az}BO1uK~Q6 z25U6aGRpI;B}Ct!KnLyaZA&%3gG5Q0(6A9ne5@Y<4RlHA?nImQG&6F5MmqaI&yAW_ zpo$hVVg&qAkq@e4jn#0~l&hJVpGP++)fO^Kfzwv#rZjm7Csiv%&pLZ0d-q-NQw#L{ z0@-?^Z&D{tuL;&F-avJ1M^~c3Rp9M?$WSRFR2dt+wk}Rl0^F|)4b>nEv>`q!S4Rpk zK86DZqO3l`z}Y@VX8Z)SMku+OZ|zuD;!#I8SsW z5rW!5B}pN z5|Y%mhn3>uk2u@62GN@3u;ddoehsD7SBo^Oblt;P&(1EFp`W_RMK^z=7TBk$*-Z!Y zG5a;UxzR~v|8%%RX7>$ z>tB~0^*ypwM-JZ_5tXk;RC^22*kIVEluW%rR9%nP7sEL$G77#$Lc@lTmJ0LpIs0H8 z(OVVjsd}iUz9?_AB|1L|$|x^xI#GES+zx}uGoif-Z=gm$pkF>_1Bedkv(`l4|GVgc z_fqYXteW?z&TF@ohz1*Bz!})C6XzDd+{v(4zwbV4YQ;5Z>QksYAC5RccYWJjZAa8c z>wR*JD4+-29Rwpfz~R=M*rx`bunc0OIh;_HsEYp5P)W%ytOtPML#TTf`j3OM7dY$H z3S!T2IHej4R1+Sl1o_$qL%YHDJQ%hcM(VobO6TJBF#jg335CFY@VGfF)>6&9;g_CG z&pe@ieTaU;jWRUU>dr(h1``d}Mm%*278t?Z(ojO>DWdMo=>%`o2exIQn4SWabl>vT z;nYAz*&R;QCJwSz!cfi6TRHeomxN5C^%B*sg_)K$bzW+0QjpX=50Ty ztW|ze>N=>o{1y|P`~;y6{0Q|?DUPW1COE^4mRxc`*>G0YzHWd6D!hS4?wA6nblv=e za8>P7A_ER;_$}(Xg!xcKCpM_PN6dimcMN**HBsNSV64I)X#j)OiGF$(AJf!U4J2x# zxfIn-@vN&8t)NLW*uD|IY31>);i?svj7uk~t=(-?9FBNEma65VRi0Lc*1JK^{d!Hy zx~@EXs#?|bwAf(`0foRtPyV6yMCG&_JF0C*t7&>Jf+2GtJ`Ywna$V~cM5`jePX)bo z7#ge6T~)Wa%V4Q;aH=6JR(;cyh%r9U_a)rXYo=Dv7TS%E!r`nFEZoFyq%UXH4FA=;`4LCLk+h|eNbM@I-?XXn+nET z=;xwJthG}2!yGaLq2~~=(4b>B!HbzNS%+5V;H?E5_Jsy|o_=l%Zu&#j>Xt;lDqiCi z(7G<<9ptr26^QmK&wktCt@0P6?wqb&QAJDbZvx*`sFjJ}ejSSHudlYLV69btb$~&= zV7WT+$RSu$4EEWB`v=I>=giA4yrY#7QLU;(?e$s-VW9F%(T;yH4hE0p>;)wvtqX}5 zTZ9c^S_0ZC&vgtSM;`<;)lDbra7mX?qNRGTizXSX$`n>9a&B?mRxNt7`rh~?)Yje_ zmj{m;aN?c%r9cpD=n5Ck!a61PY7uC&8kXw2{BqT;TXRU$Utj-d&m7lAOuGO@)PFC$ zh;C@ptyBKyT!qmooG7JFp)}>CX1~A8;uMj zI_wB9RmKmR?m>OD9oAg_wgW?@q=rhd-4+^jfpxmLLT#w8MLU_o#i3B;4-{5|tT*G9 zt@RMBzX#5#sY^74vU-*{Y2@*`+kxG1=qHyvzeDu&{~hs)Xt|ofGanwS^;~~JmGw|o zt=vM>h*Ler8S~yLy19+E+URl|2I*TyWA*r7jbf#&*=+%9Jsxh)gQr^7_OUQ(6*Mjn zW^JHR9IU%Va+T^4S|Ud!Off-T^UJqeFE?3s*z7-DZx0jY@GleLST;g0BPMhUR?u8quGDV0#fBs&l^EgA>c* zFL6=on3>uV=hVmEdJd$`2UGo-=yVC9g=e9*Uc1}_CaH^x>&~TJxuo$pqE{cG#$lML zFR{fI6W!MKe5&qvu6=PM8an7>&PorV)tBJ4{^pRPZwQT)_{=`wvO#Bc-SZtVUr&T} zdiZVF1F!YTP@z98SLxIB-N<4hC!&m@in3~}qMc5F)bX74*G8D2$5wtxqN)z?))L&^ zNW5(TQOJ9Es&^Rm1hd|ddLHWJ!S8qo-wJo{L$nq%p^iTWuAK582SHx6g3>Hp5*aJC*oaca_;VvZ>%4!ek9ybv2TCG8EPGyW>$9up4$yf$b`MNC+4EtJj8E@aR7Dfsz%Q!QsaJ zutkhftCZdb1w5hNSjapFXEfbQ9~fYsA6RH#ta$&zMvO{fLqwbL6b_dyGxOH*+32KQBvbU-`9Oe|jfeC96XO5Rp)7tx(SXp#$~4dLMyFmQlOMVrhOY0!I#a8@@OtnxT)g!dZCNRQfg z=|m;ZgGCh%%Ty;SxEl6r;`yCP;;qRWHQm-3P+dQR7Yv5m;T%>t0^`)Xuk_H}tloA042?tKQcuV(!Nv8|aHGpX zH4o@u3qv*Xoel6xwKUPTa(V>uWqC)M3(*FhNDy8=yw*Wq%ZK=K_*q3B{r_)2YL%Y_ zp=d1pTMX|V;pu9)c>+E*8S&0&3a2#$lP`aIY&8;Y1Ro~<8IOKpSU zT7Kkvy`u*wuIWb2XL7hlRc(Hl!#euEO1PLqv|hDrsuhjb4hWvdCHdOoPxVZ^ucm&` z2i7cr(iI?AGpI5N!t{k}Xb6#Q3rL;<&Kj?!8mYuM*tP^d=&y$ht`q%qgS&|wKF%ca zQKi4Cs($JcSJnL7Y|ef@MC8^9*5#S{R9mqTS)`6Q(ISkar zZkq0UO=$QHNUaH9HJ+Ki#EzUrba^Tq(KMn}054}a?E;@C!i4*rw!y~!HT&s<~8pf-i#>81d`vw z{a{Fpgz#gWJ>Q(DdKWmap`LocwUzKt+1Rf4_UQmcETFwgd$=)g>!F+XX%ALcILs{y zwmmtlnnZL{^(e1f8tExj={cmU^-im9ebZcw4h9)yX*;bjwO(isL`gyxozc@^4yfMx*@pf2{-0DoV>vWi7 z*k2-}*PK04lEV$#Ib7okHflnP5wPVRC%(B871MoF4WX?Dt*wUJpbVYYD*fW1tXdvR@^*6}U z520B~XN7#ItE_pdF-t2EXS811k#Jk7+Yt+m&%(0)FiST-wweK^Yj@w!hH$wAO|-YZ zpC+2}8r%-RHErxO#+>M=eL2qwT1*D#XK+MiETo-xP;Hi`wcXY>7;%|*>{RbMR)U}+ zu%Q+-(L;ZKKcWWub#)}0Xs8~!?rLQNGw=@Jgol#2APjtTc8q4VP0e7|4MMcGyUI(} zbf}aEuh;OlCtZjJ>O_dLVcZ%{G>5nx=rjoy>m99rfuRY>o;aB3gL-$kBXoWV)iswO z{r-Hfa$lSSF1Bz(E%jB)Upoz2>VXoa3@uk;&9y^|*MY-bA*C-9DmIMB%Mz+95%&EU z^v4>a)GzQ}Dc-6+7_1t3sG$9Y|58|@tgX?BdG-u7LpPc}j5%8_AX@qZo`k}2KPYVh z4ufE@rs0(arVk;y9q%=bCTiRr25FT`#At20pb=144fjo-p`XneK6@>%<+?#h?W0$A z5FDu)G$3lITaHzBj|Rg)7ua|XzO;juec`IU+g5A^$Ft$meqQUU^@gc|^OW5+n%X@F z$gB&dZMp9IBcdcvF!I%jO1xI~22o{Ae1P8eOgpc8I46pz(*Mpe-H(|H542-x0tE zHSaM8D;-ud9f6%(7^$=OaLog;${dzyE)tE7m=N|M?2-Cmu}ubpIz?SzVDk6wYx-QbPDVO;B8e1 z*JuCzD59W92-L`qbKq@%PMEvtwF*S@)P7aQfv@J0kxNvoE>pYZMdYoAMUF4gXKjxU z6JghIm~#utHiqc&V500d)QL^{cS_6SL{~<^ZS_f#qW%d`^bUNm;*xxAiY!w&H3@zl zg%!$k@jzJ80$RB?^IYiI3b?)ny zQ5ybSUvMbGiGA7^t>{Jn)r*OC*Am&_+KJa3)dDSU!k^Y0wwX?}Xai(wBY3`p>Q?Z| z7pmOkk_$tLmMOA4M08S5Ds#PUOD?ZvYhScdb9GjGf7K;fD(KoFL>AWY(*{o1@|ua3 z+I$#Mo|4`m<0D{J2N z`v#Gx{-;^LpA+3U1CzBYHoPHPrMU$C`~TnIwyJTRufQ;6bx}#)GxjM_yRWdf8hClb zGi~TOCm~qn>(d1WMnNUr`SDJep#hFrz^Y~7r1bRFonPfZL_e?$gVp*8+4UGvP8xJm z^9_#!8>M@P-kV<rX|4 z4|143h$vP?Gt=Fc)`p!*S+{c#ujUKMgTIEbN~J%26^`rTJk_X>XD)@S1XkQij zT!tstz;`<2jf8g#z+BriaTgS;4}}N8mPDxK59zvY$zI6PqCNC=eW8jHQk8quJ3@4- zJUG3D6i2wB-gz(;Y_xw)YF0B=LWZ6?P3sW_>AwFOL2*AwS4x7_8&TS=@AXt1)d0?@ z=9kr8FLH=(heGLS*r~_hWgDoe2UDRP&|2#V*Jp{FiZV`f>7xt{S8uc!4nErWuaz(d zRlls>c3;&Rv=km{z1x)Hi<;j~4Y1$<>{0F)Edrxqa7on~rF1%n!&!YD>8x_s9ta*A zVXmsM+yyMpbIW;RuF{^70x??ZBc(I`4t)DxLymUE&~fqyp2{~ zI2Xohc$-h$a*^`qt_rS6g1IfZ`Ev`Rf?9dFHsTE(THb|3wcft6nyC?ysZuxL78tyQ z5$cy84PjU>=sO1`^XD?HIh%lVpcV=6qvGg31&>0-xlmKDnH(c( zt9!)1fXf=R(!v4-MmqTS)RpIpK}HsMe1aH%-g8rFTwzAkUG;k24xCTI`Ks_=S(rT? zPO2f}_2t{AM}=|NpMpNOVDMc%dtl z)9{|l!D$0SE!6yerVNX`Ik*xTXTU(fo2}L5neP zPUTsxi;Y%8f30^?A+Ae#Kr}1@x-0jyKR`7XxEBO7yF&x@#2oF+z?aatC8fXWZ=xBF z(dDz2GR`PH33lm&-Axy5&<#Ad!2GX5g*?>)Y&*cmQSjA(izB8GRmg*3>Om{jtC@Cg zZXD5n{fPY1iTY~(2Jhg}6IdDsY;c8TX9Hy`e5q)?8}9BGo@-5e(=H*+;o#s{@fwO(@oo!;4di zibuk-09dN&KGpJn8*=ttQ=*IGiNd{!D(DaPeRmRdQq$i{gT9mDl70e>nL%WuqQrZE zvx?kR?R7@uU0Vo#y7^BPrQS4{eGi_F;*y5CuGKCM5334eyKq<{4Kmtu=sX-IDK9Nv zK?7CmufFQH8cg&-w_KsTyd9&+6Yk%Io7=f0Q@i!c45Dp%MjL*|89?$JcO zRz;;9VGg<9p^YKDSD~t@-0w!hHT9ZJJUI6N+w0(P9M-wP`1^2Z1}vMzjdt3Rt7tXI z7iFlj-d03g{O>Zj-xpjS6j>q zhN8l~rw&zQivzsl>=q)kl0=yr^v^;_(9hH`)%Vjw7^X%)V@BkqF21V|-=fWkN@}Qr z%4GZYkY@+Ms@B;Qs89j^>bgWV`imyK?eQj}uKQqtW{H9n)O`!|;gS%2g-g@` zFSWP2)rQ^&py^m>e+jl~(S`OywwmFPs=s&u_+`NfYltlbi!^9zFR&gC)qlYq4e(SQ z7OQGq)AFZkLg%%tdY({G-|{9r<+WEuiK-kWN=PBv9Kt&uYS7YZi))ThF&g%?f%Sgi z+>`6K zl3`Xv_mqeQ+KAV_f`^)LqYqTf0rMyDRz(@L72fGnzKovtiND?(RykJ}C*6WA z;WNnyLOL4LV1o+#3Ntx_Q^)Tvx}GC?Fl?>A5yjpC84l64gf@{g*FkC#Ae9a^f9{?lJO`e_IJbB5QJ9JbMWZ9-s* zN}Ho6O;%|L)-9voK*cJYXgZo`%}JQ@Ly@v(tJiLfhd`AqW)hLfLFlEwacnaq>Z+bJ z(mOIVa)K&-yeVh%^rQDcb8uY1YaXSEJ}VpRdqN+j$xEBgzcDBLwCI`Bp}W4^pVU@+ zW&xwGzyY;h9ZS9T2`1>i?)vkViyKkR=g@f|Ol`<(W3*=~OeUJ3=ktm@4mZ^Y%kEHW zJv>c>5Y72uXE>lD$7+=)^hm3(wVmw2;rhc6ug{O+sz)IQa8ZvRP{;1lUP#^pp8ue9 zQ~0g?ndn9)>dpx&N|zDvN^d)&$Ct5g`AqFoF&l=c?+beV|8HaufkX4a*9c4u;nNK8KLRT>he{@}TNBxJ6FMlh=4yhX`joGFis zJ|~)}qlX=WUAAEP8rE-wRZrNcGhNshtLAVRq5puhlE&Mtxugz(p%b7*CdBJmIQAkW zY7}qvtdDkP^ib}x$BC$RJ)O{=pR0$x)m>2$;?+P2D&IPH__-Rk>J#b3JKlSJ5Y#Ea z&7bY%wKhv3Q58P%2`cV@h9$V9vbOu_F|cnXoYUs5tEPIdnJ%(`#$8~m^7kMM-sv9y zd|>=BXjC4~tFBEozqVe`Sv@gbn`2%e(LB|w^JYc0d2NnX{zCuYddh{vQTI5kzmdqJ z0#OUy++XWGpc)%F4?;@Jh z9_lG;Cu@R>#+yLf_%95Ams((?TB)q&_t+ksyTbaCkT4I%SA{+aU=#!el=kIn!{I7u ziZ6^^1|yWAORM1LJ?3(A8(E|>FRe>*b;}mI+tyYPq-HJm9j>Wb12plPI(xJQ zY+T62Q}jop(s0h<__s2r4o)^Abh=L=aT{?v5ZV~ZN z@i^oUfzx`L^cxPPUxSCL6_y1-XQ9pp_}2|4h!3V<+Mbb1mtejBW^*{_0j$^weFwpB zb;%L^VXxmZD4^1Y^o3n7AvYMzeZfmV5ghLk9aLWaWx`euSfh<&rVMr83cj|mLGOr7 zhP({eH3!o4gq}8+sC9@=Xyp4N;qM`MtZb}S4sxwIj8T`|y#ccoEjbNU_2P~W9XA~$s_6zk`aYMbwY|`n(;{c!-BH-6pD_RRB@DJwbWu-^tHVZe-*}eg3V{(lP><-pX&@u5?zW1 zpB%6}22L5U=ohSe1@kqO(?A%f3eLIHKxXZkQyxRQNN%^$6{h*=D;)chUv zG<&VNJUt9SouR7c?5W~y)hes}g=EdNR}{FvfYFxlLA};(HZ)hwUm8G@T#{(^k7%ay zJXZr$9SoVeM@9W_KWA!`>UzG+Qx#g2hMZ5(SraO+bzIOoc6xJ3warAPanP&=wAR`C zs{X&v@Z~jl&VUqE>#xdqOaBO+rTcE~3B_z7p(d}r)i&s@^}5?Zqaavo0Y1vJ{R3Fp z2ga|3fc<)HDQ`<~B9l#4GcLAFOR}>En%{jV6Cq`4jON&wo5&=a?)GaF6@&aXaG3g zfPI?A4>j;m&2;K9NY!g)^{eF6P@?CNMC}GaOVxah1>{|T5$cjZli{eAZ#fbCl&}K& zt{STH)QgQ~kBS3e9I z=Fy zcj?Z`{U~M9O*yTl1}Sd{tp>qQ{S{zQJ))!&@KxL3m8xI+JB;#&pL?KKTkbn9h^SjU zEKxl+{)Ws9Xwi^SVnd0X^(ZajL)3BsbW#J`y2BVxcxlDi^d&^~Rq4f=#;*2o^#Gh# z#$%eoL{%_mKFn3Z#xx*_%{8^eJP1<{T~eN{^i;lf9)?upk{jKKEbL)vA;`N3NA(Lh za13Y9&Ehb)gHH4Z7Zv4V3fxy>&#EJaj_0~PdRwA);|F!@3*FaR)4i=9DSwxP-*paO z)P-GBAYB*d1VYd099CDtl2sHxC9Hzh7N(+1d=8E)!CRI7rFu-#;b~Xs<^?bHxsYWH zP8zx9At>+#V*0@zJ#v%PNTu|b(Oz2Wp%X;C^($wRihMnbXj>{#Y-6IY`c(7P@2rT4 zME?81M+4Mf2aP(z#CcGCE|(nCPMPljUPB;XUsCIJBD!V+&s4_l>-5mA^M+|`ePQ`)Ba6JWSLYuB`Z_jNg3sr#-y zLFBAT?@xm}gTZMr*nEO5+BjwU!nVKgIDmIt`F}s_DeA2q-%QsHR~i4P^^WRpE7fbc zi(sKHj!}jjm6t8*;*VPX9o4tR3g|bRL4EWKt)?x90W0BG1`m(S3qE-@!QvTx-FC-7sDY?4XSks!yRcVMML< zjux{x{9;Yi`~fV;0sA$~rI!m)knZdA3OaTK3+;;117NB-Y*Q6>xWf&#_kX!?eJ3R7 zkzp4~87k6nd!Z>S#h~+Jl2MylYin z8>E&xIveUt(rfw>cuI@;+Y{<(FB}esT}$AQFHG16#yaukAs0t0L%-D79kodeHHxP? z!bkmgPoEklT9K2U2lms59EQWZ+hC;SuhQMdT!cBw^XKKzeK4f^z@9-6v!47#n-X1) zf*wubZ6P*i$RVOe35>kU01B(LZ}t$?P%~V<#-XRCmZJJ*IKt~ja9*8rThqwZb7Qb4 z^#1_U6eX#P^Yt{VRD@CfX?|&!U{@X(tMFeA!12b=R!@QJ`ee!vBI@25HWz^?Lm022 zvfIGD`fy(}=y?p>cJhv#6+{O5>TE(0|#OqZ_?ZI@6T)=qWH;RX8~nTGbWG zfn_Ef?FLCoyH`O5ja^Gr@Da?{dq?Q|P%9<-uPzSKI^y)NPal(r_Ng7?-Jq>{W4HF8 z+e7Gmgi9)Ex+j&yQyO%Z8NB=fPd7ktCD?l!yfmTjae7UKkG=q7^=Y-YG*L_^@K<(w zXsNGVIB|bC(OvcFf0i6p5dCU%IPWCv$b!x(&{IA1aS!yn%Ox(F%coUD1@s9!d@qM~ z8Q|Xa|9^>F)R$L-l6fJ>9;~!mn<+EXH1)%3!@q{)_t8zF6xI5wcG8{@-WJ!2sBQ>E zJHX0$5U;O`KFf$6De-Pg;YT`b`T~XO!QygYSOFgPfeTJBcN3K959M{Dgl4e%3VaKK z-)dot=iKsgd7>Aa;k;6|rWXW^h3x7OybzL~Li#v}(fll1z(^Hsffm!;7*^`D&h`aS zm}a$BH@c>E%vFW^s5Tqa7}flV9Am*e8X^=8s0jb#;Jo9xe7iW_e%eEOXpvM(v}lor zwg_#C5)C1#NJC2+N}HyVq@7YpX`n?*d+(v4t^K?|zklAZ&$+JazQ#G{I`{q6?|E{S zKzW8>i+s7$9XvP*TvZHA{-Aob0}bng-4}qYpW~r_>m*ZPhGaE2P!E-qU8axEoc{|`>3Vy|d%koD2JFx6FxOSciJXC5ORDOHuSnCy;!gBWG2f$1zFhM7> zum`?6?}RAO`xTh3B@0dfuU@jDAu*^S>EM?ZAAT6*tq1p>f-fo%G2=n0;vjD&nDXCM zD~Iy#2|mfs<5gyAXrYVIV4$*nK_rOQ5w@!>dj#mFP(;elL3*O8-Y?s9t$J$lKAXYM zE8vhbXImrnNoPBz`DQ8 z!EIgkTiST(YoPxgkTppN0VeNxY)S+0ePN3!ikgol` z{SJ<6$x7O3&N#4Lu5(KQ4dlrQGr`Wmppg&gqeDBYbWa_P3h0S?z87Vu33@0uj?DoZ z_7Q!*H}w9}V@EY4PcPNVX{dC0?T3!PTfRDX1bo+$O}5BX08Uq6aL^~z3B6xh=&z+O z=3zeH2uzjK5!%5U4Y?rY*9zPV2M?6vo0PG4E(0emboMV3q$}&3R)9v6!6KPOj{;l$ zEz46|^Otv*PY0{kafH-BI{wIExtl;C<Vp&j_WjNV83QCmQ7;5RjBD{P7yH4v4i z>Fa2_eJ_Dt@=zgfdOt^^h7SXm%Qnzs8Q3%fEZ2{`i62lEy?}`xdmRSq zHlw3&9bnc2)8!?2Iv4Xx3sm?5RI}z_m4f#s0<_em2X%$o>lasH{b}026K33Qu<|j; zw*nKFfRl3FH|53wT}~Te$5wEDDk!px^QO;Yf+_1Ue@+2ba$@6X@JhuaRtdbnH0Ypb z>#3M;wL#rckniaIX1Wp_QNm4uK9I;h*VL7M)ma6_J)@Cq2U=LlZ<6HbSNm=)TC2dBUw zNASE6Sf^vf=udB!`czM;#S^{PqpoPuGHp>GwAyC{Ahs(=)$go|`oJ{F!u)%jCz?B> zYF`C0$}4-_g%xsQoFemCH>HkNGt6di9c7Nq4$K{+z*SxQK02!3B~YsiNGeX-+^=BO zFt)bcg0>ZfL5V)Vp)Y9r9^{?_cXfY9=*~-qBH^7X)AWRuMPwI)T?q&yIdep_^wWxji>f0>81aAU`k}+!sXo%|gfF79BEm4zVK%Xb-cm#$l(zrUP&o-cg?qHB! z9rgF4KIwvOXpTy02I7?W=_^3W6wJl?9(t$4^y&@LlolQL0AD5C5*0?DiVTTX4NDse zHiZIvT@4G(+*ghCyklFNwIX( z6Xr+33zaHEtuaOQ;HlhX+ZrUwYZLUV_^&F`X@&8K(yUAhSf@zmYoS8gMy{g2q#Stv z6U@^r1-1CSrogHLc&NkF>d$=BuAo{U0gZJHjvNOI^>R3+1lg`Tn6(sDPkwRL;HS3W z?H77@T|#yi0=59tXvoVp+CPy^(ck< zwg$CUzJFC6Z14w_w3o*xzzoe?sS+rv_|}%kO}~MMjX~k_;O_!(>m$gh45rwFr^~^8 zMLN_9n5Kd%#;n#&&&J3bL7Lg5E9kxxxLpMsm5C-g?^C7OALY28%FV=nsBL=D&vpcM z`f6Ei2+Z~Dc$JpQI$OXxQ0E!QP`=Fi@2wkwc~}3|<=q)nRk?ZZ0D9__xf=XoJ@AYI zKQ02Z$DqMI&{5~usEzk(4^F+nG%^6CT7e|JIbUo+9dJaMS)zL6fC6%7ca@Blf#6mM zc&xOzs!#D>n&o-}5TSIu&=Q1XfDFYEpyLX#VjSpNn%=YWuCqdRZzbq7 z61@8ZHnsz0_XBq;PU)c~Bced81&>YbjxyT-*6N8@3i1m1^x0l8UA3-TELg1n_M(j9 z<{-z0ZsFO$_NZV5{@gyyeu{$SD)2zty;dC6R{_}b04!88SkuhN~wiSC4 z%A7y?Hv88SG)}`z7Ov<=L(dDKnWE*YSpKPkxn?$)tQ}NW+f}^>lXV2Ev!I+VZ2o-k zy9=RBgHq!_rp6`Xzr&J6;M|AFU9i{oFxwUeOQdEgcV?#uw$ zTEk-|`0)t*ZxoZB+=1GsOl-3lbFhvzUyIjPHqE{W{4_x+1F-J`7`>TsmP1jW$AP^^ zKzps0qZ>8C1|(%-8YF=+y2NL6%92;WzK-DODUkFV%%23NY0_~@n#sz)DIuW0C#WlL zj8+l`X+t*}F>^Zw<=tSgOZmKSAc4Ps33X7B?sf}RMibof0r#eZ+I{KRuZx(y7F9u4 zZA&OPa}Mka1NDvpn{U8$Izx`Cg!i)n_gjHu6M&8K#X<>^rIQ!dhvrpn+*+Fq9t|ET z%{&#$S*BohFA($$OwjT7DUl9Fqx|IJdbPl-MWESWI&QT=^;AHYs0978rOi&;HIVP? z{RJ=T0N;C{O=S?>jo#17zugrDBicSz#v2VQU@p;LPIf2K=5`Hu9;3rrkt-T(7`qh2jzW%tK9SPJ6Nr!U$q5i<-FWO!1*Qkq=J}P zlgaMtU{|VxAVbh`IBhAXP?2&}AJy-M8&PBahk7>z1n9B78nRwFG5aWJcnq}a50>gA z35sTqtKhW@SfNaaa_6znrBTnEQL(DVyV5bU8Ug?Mz@!^E_5%DpPw$F`d{C#&MD>rM z?ZbU=(E|4*s?f#wY8G9mcP^;DidTIl-~R@K&&R<=f{Aj;OI^hX<<5xR;IgjRW+n6D zGaBrSN>PQ5)Wx#UZ>qHcYEzgemI9$eK#4n=Pg!1BYm_{Us-@p7`9D!RbO*+d#_XiX zOx3g5!%%I8p_=Qar^vh6N|r|2>8TX(PrC}P3KEo%!3F4D>V+!X0@z1^hfZLi^1Zyu z%=`f$-UC#%X7J4wAZ8k7vm4-sGR#0(lDGo=QQO&l!16pumlI3t7w}y9B_b6Z>;zu- zq|GEAELn-UM}H!zI3Cq92TW5`AL`lQyI{gDdi|9z-{U}nBWNW59qbL3P6oYfz^G-Q zzLbd#k%koglp!r)95|Z0X3yQ z%2G$QX$ow03&%eI(>v0UEbkh4gWmcZ>EY8TH;uDX@=UqUGmE<-tTDuptl!ekUxI2i@^dI(vAM%x<%1xnx;6@|RT}ODJ#C)Fs zo^_?I&n}QG*A;6E2AI+D=>RJA4%nOx?38-Fqe0?P@KE0cPwxTyM9f`^c^Cai+1?&C z&H%Jo2IecD$9DsVd_kE$;IbJwqJZ{W0VZq(shYIWFpxF}bd(QbHDtajT!L!dR3*}I zZP$1vxYrBJR*>g9OKI_Hk5QIwPzQZbU3CqHZvoF$s*;r63Hmp^O?o@V$+4>gP#5~5 z8XZA7DvLJ;fs;)!4ThsCPXaccmS!2*U4z{ed7~c~Dw@8F>d(sRfp3T~ia#Nxu_}6HsRQHnM7f z8XE=7r-RCS!J4t4m=e9-4lqc$wpCy5gOq=p%Yf6HK|Lkc$T&Kl>r=DRf1kMW)ktN| zt9GIvI*Hqgbt19(ZGaKrvy;OM!Q5in2 z8c|lM?6?@SimrigQ_xOvYphR~)B1c*RZjY<$gETOZ+-`4u8`RQTvN%dyA#z~d+w2p z8LV;Tw4sA?-CPwxcLnsOJU&3)c(on`P6j8vaH5Hhm8YE+JPdxSmY8e;PWsTynT9eN z1zsEnhZX7h^6ruhR7@K%ehVqql+hciSXcAa_3fP}8{7`$F?(H-NF(q`&aSMj9SQ(1W9VI`j-s07p?0-R8MaPuararM8cq2IF4K{- z?eWI+dk4}K-)bsuN3`b}a$PTF_O7}-ma0w8)U^-SxcOG#NPjwJO+XncOD^Vs@Pf2e z8H`Fk4QeQ~#pUPrN|m|IP=;erXX8*8wNO%R%qMoJF;zh=6`tGnpp)X(!+}k1NJY(2 z63$dIcCH%g(-qJ{|nIacnR-vZ_K8TCMEFXH!&L`QV7^=_=KTQcAd)kLb0~xSEx~%NWog3tUp3rj`d`a#L(3 z*r*KiR4sOlLWM?igtgx>`}M*!PXa}Bdpc&(mXnJr8;-i)opFByFx%Y%b-sgoD#QD9 z)Drfn)!Oql)t5gj!8{W%trQ*WH=sJme7pmk9Sb~Of~xjl?jJDFA3Qh2NfP%`QScR-?FdYS}fd*RK^)D*B0C=owJ7yGUyA3=r2jk+wFzvu+8Sua)8F7QV&YNtG%HUSv!1P(Vrf%_mvcfqX-NR>K0 ziD!K@eX?p@&_>KA2B@WrQJzat`3|V`9Mo=i&__G9kh5>)u#Iwxpi?mBf>EeHI>O`w zpuHFP)dXB~1?yCY76pR!%2>?+S`#B6zVL92^QN$xZ9?z?6aD z&S@4(Nk(;z6V#SG5;*E2T7LuGJiykwV23KmTBVBrGgSKw&~7q_Y6-$ri(9yW+0LMy zd_P|6o=OFKKk(Q&`MLi(bxg)w-3;ZE2^KsDogaW{mq8cZvNg8AVF6~*R^VM%-bcAQ z{@^=cnKIE>mt>-zT{9Z|n939G3Yqs;@U{*p6#>q9gUNltbY0y(iqQtGYc>(Add_2Y zw6)2`Ab$?<);ZqDFP-~?`|rUKRma8ZxHlIxRd0m+*G@kphZ$nF*6*!mTBy%il)v)+ zb~vV`eld^JV`)wx^fTsp`R~peuvKrw&FYw-?Y>oLD`~zytwBGfq~oXi z{`Z%-elyU2Hv>zhYi4`Uz852{HCZire_Ri+My@?O9(Y#-OLUU&irfR;iwg4jIJI@_ z0w#9{l^TE)IjY29uuqvkS)1#v*tD;Vs_+CgYdh-E0aW3&pwv0wJ_Pg|Mn;d+q|cPS zCpy#i=mTozRnS&X{7>KY868ngU>w-H8#Gx0PGp1AeZgdz zPbLA6F<^jR();~T4%*cnB~Wq#%ESPy+YeHog2`*a9~%(43e1sLEiZzW_d(aHB-+|s zRQxcoNOz^}X<<3@trOnsh5T0GOLt~)UAf6pY2z3Q$~9AmDMR{vM!Ea}!#02^idG@H zWan7W_ZYb8$+!Z?Q7NTCUP-V>i{DfPeYD9MI%?O|Ahsj8uP{D-2ln3pvzh{5-P;8U za?5_eC>n(7qCWOUrIte#4?qp<09woAF};EP08nlP*e&(g6O>E@A9KJLUl6NPep>|c ztibi*Ox3pq$~y`e>vDW;1YVfaG3Xy^X;*MxH8Z9iu+XE`nYc>vn6GDjRO3=K zL98s?YM`Tnaz^I}dkY3RfpN(oPwBXG1n@hHSwN-nq+Hiqe@Y z)Gq;wm1ct2Pb@TCpMk@bSC(0rx$=;s9J^cpiOm-uREDl!h60e)5|yh!y-J|>$4Hcq zBDj1A_+M*Kz>IMv6(}!d=O8bTrtBOO4sLscst190AlRG)0yY4MBMK`qb>6Mu*u2utk|u!wj6B4}NMJm2}^(%g-?h zp!x!^${aZ9Z_E$1wHaD>wrYR#b|6>2gF1?LK1w=5HlU zxx?V1lCVk`v#j!`W50sDQl;vaF{-M5fHkjyT3s6)Y7REu1f#Ws>5BRJ@(lU04RuUT zG+7BA%e1!vJ6*tgZEcSwII8>cv^$tS7%W$`e9JPy-*2di$_T?lpn~d)iDKSaZA-OU zk<}op9H3gCDy_|XHz%XE%m+yh;(S=wLOVAPs6;N2C> zMOLV;dSb2?FEJO~(rT;p-{Xuwikg&;I@OB77Rt$o4&Yf!Odng+hzRhuEx4%y@F)!R z^AGr)1nMdP?e2maa`6}Cc&2_f4AV!fq2e3Z5}c89l2wa6HKeut+_)>)oeIkL0kzA3 za7D(pH#q+jY#9X_$m7}a^W08g(0$DI+N81OYv2sxwDG)DdN1i!-bF8)0hY8~Ne3(B z=bEZvRT>lNFWPC2FSw>RMB&2>&Rl{TbOnT{ko}1V4|F9L{RItXgKfGCXLX|W3&FSH zV4CXl|F(j#6X1c)VXrFSuLQZL6d3yowODD9^Z}$sgOiG7xPD4(&>tw=r((9!je6V# zgnk6KG*xU9@X%FlqrsrvphymQS%Z-6&=EGP-rFfC6~me8x%P515KK}%m^1?vG6Ib> zv(rJaR2vG`^bO|#SGo94W9EApfLhdpSzdUcwpTI<43pRZUyF_!{$ZO^|d1 zvv&*dQPDcA$Go-Oqk}=nbP(#sxO}DFbqCZZtvgYUeXZBi%MjXH>mH5z1+3PBW3R!V z{h*jPDAf}b{RGC(1C^VBfAzpYg>kgT?K1EX0~K8G-%8cG;@P014n4I4Lr%zH8=*$&!~Xwm$(& z^qwBr8gx-&CQbmGVt}s)IAIPRDZbNm#Uo3CcO{s#v0e`T0hrm^-|lPR;1E#p3Me`h zj6V(rdxEvPDb*)|eV2|#q_Y`nJ$uL}AtJ@j)>zeM< z#^axXeC@PhP2eqalGa%J1`JkObO{1)<@RCmprtY~U5+SJ8|2HK{d6^oDqk9^+|=I) zx+*BWb&u+I10587+xFms7LRNOIz}_(N*JnU1h7y(+vy*&YG}z?+RH;L5Zn)3j|7i2 zU(-F{&`Yp-GHAUY*vcELux*;>a7BO zGeDCuV4o{ETbyye`Z??oh}p&gbczFhJwTp(8mKpzOFGI+$?v3VP(BOXI}WVR03Uns zxg+B)C_!#%yTxrlq;8qx13H@9g8_#y&$Iy!3f^5M(gJr7BiH%e1aI>}QAIUMS@%Vm zW4as|Ds9i`^So#m%&UvRCFM}!PjE!(bBoXBG43iEemZ3#yT`9z(3S{3F_D#4O(lyw?5$bW$|v-TC#)w zb3$`@V~YHeuY{{Q54=+J-)Vw#Pr;$l^j2Ao>eLD(tG0L2wc4?O3C<~k-WFg`8BDKV z^nO(J_MS|eTRrefUi%UcYAyp~kAh2IK}I#;YrtcTXQNII0u}lL*Q>xwrGAf2>0=1O z<=BmSHavpqL-n;ZMIB{60^gtDe<~U06ujrdz%AkVNv02tMJ0uUI|@`^9re{XkSxFC zd4sj`vtKt5sNX$FzNoEAn#H;wuXVte4N!SSn9px8rrA;uulr7}@EqaNp(X+0q zy9rxS|0bYXuScy?QeTu0mgj-L*Fi6-n5#_s*O_tGzoNFw2R-$r@J`Nts<>5Ef>f#s zBKv?<@`m|o@XHb`eFS`ugLp-7wfr(!8Rpjk^t}SIbl$!t!1K1?aU{6y1&VF>?=NxV z+OpL51R6f;5HBa9ik<-D^xz63u=F!{;0i9bWt--DZ!FHi{HVkTR}5>l0TxQR9U50b zQD42C!S(K->V5$u<$&MO;0r5{sWpz?&$<__RVD8I5Byf4bL;~`w9U`%sBsHX*$VDu zwS9X<+i-uBT>vM|9s(v=($?;>lss+x1i0yd9}?(@S6fId$oLD2X$L#)K$wb!Daq-r`wmEJ8KA-~hCz349S8*rE4F;tZ z=G^+A&k}Ip4+sebJv3ylrplU)cRduhR?~o)YWj$KAgL4cg|7im^_mOrLEAKAP-H1M ztP{P`{=)P}uESj!QnDlFfHfdqL#pc^9y4dsd#?c4)&(SNq+_`Qs-sS{qbJIG7OH9x zxGiUYQ8CEe4|30d^7p|OU9t14)TUI)uL^cQz^o;=4^#=T{_nhd97=OC8j@DAds?_S{mvJCr`A7l5A@ui*iDYRK0`V9#ps zI|F<=0<4rOPn2s7bRib%Smug!S54rn4c%5TupI}6DylQ2thIRkiy%)I-`fOSkcZZ3 z(yxl@F)g%VDZBFW2FHhC+MWVS^XYA>UG3NI(_W$?mIH?rU^f^g6$B zQE>MJ<&J^NT6}FOaHI;jqJ+Dysls%b9_r*RHLkrWZKWTh>@K60rlM@MzZ2I$W&Ln| zV~jG;RDZR}sartthQLXS-%y5)(=0cSHuiiOT<)M?hM~}<$1+!B5GJg|jv5>X~ z`%v-9wISoB%F(t|$9GiPmLCXA735lq`Rf#LSevY)9h5u?wqF9ZkQqI_y)$(+PPN7CUJxu%Vy=h=VfR3j17N#0UP@eFoyRxUtUW^BH7#fWk`eR^}jU9w@Gglzau`HRRb%qfh|~O3BS2P$OqMxF?HNmk@;D5@Tjf=r8C5=f8>il0|><9iRpqEvZZL~(_ zJ8(p|r$r0!CM&>72~K*}&l|D6Xv;&P6@W0lSn#7Y3jf{Q{SF zfTdca;26-nH#j#5gezaBXMy_4*k_8qX@8!rYKA)F4GQ>zT^_WJ(e*p0-N*F9bXHMV zw2W|HZHQ_Xr`}vT4y;ER-UScWfjf;rsl#BE7Fwi9U)5k-QCpN<0VWu547EUkcd9~1 zL1)ww?Y@a0WzIZ~wvInA*U9&NM}pGYP$>(Py?mN`TphbPfH16ILrhgv>hBW||a`u-Mpq4+Fu?K9_iH<9!7Ty59d5n9u9^Ac!IV%=5SSc`4 z%2ziaLW?){0dw>RsLh&rxAyFx3$7|R?lh-ui92dj3RtLxI;!ye)z*qAb29aPa7(^A zDvz%?hdHt{$~qD?N|C;$i<7$#I0w)+Tve zVhjI2h-1=~dUdq>Yr8Nb(oog4?lU=d)@iUwzo>(TF>dT!%o8g0U388cO2^$HpqK}3 zll!2ayMcfz;FS|?oyMwd6KJDnedL!!eG27=VGcJ1J5+*(D6}ti{hlf2jrM>`O3}K? zzkYW?iS58iYedPhsd}uE(z|X1*l`wIkxLfoY^~MyxenMH4I(vxhe|;i)zbtG-dPtE zR?(`Q3l3=#3%j!U8aA z9;jOmtVjU1nqZX@({Coou>ubNKo9l4RLU>cu^#I9i(iAb8XRl~4C26zqind^ z0h7xhP`)3f1CCPwMl1xKwU>_y&%H=+CI?vbWrD%_3`mpL9xAl29KdrI+QRgK@!cLc z?4oUVJ1}S>IH`jC^b0CZSu%edsHf`KTqz%@$b68mZfp7ng&15)^WE1aHq;BZ(;C$3 z-5})zNYwF-+S0Lb3o7#h$Z!GSgQ=bUN1&Ybf%~flYO}KGY)vLz^By&@BIvJ_I;j`h zlzdd56kt$|A@284n+@rR^~D@C1J%DFFpytrB!UJL!0P9~c0V|#oNTRgOjimtQce6j z7C5SqO;eG++yXRJl{c~myZT|?Iu6#%0Si8Z@;buyF5r`TzbmRs&VdK|7O1SkGr<#V zc|n_Z5U8s!%dbySU*zoAyI{&YaQzKvuNz>|1#iski#p~CJdg3jCasp&0n9H6E-Csk zI)dd_utn+URUVA>X7GW3(v(mric5(wSPf?xJkF)hx zf!eJCT3xx}WQ?+u*Q(7z6;uUjtku$QgRYN2`@P_^a9M3-BSF3qgIDM+xk$k~X$D#j z1#9|)PP%WCr+`LW@lmE@()50*Sc(Q){R}RvbFSB-M|OZ;4&b-^c3>Z9u^Q}309{5g zcuhQTpN`o+Z`Bas=yWChc_stgLTsr3pMzn zHrLb#HQEPtG!sl;4+?6?65Zg+T4S;Y=)RnB#wMr)eh{jyYWkZd!1y9Z_PnXovo03Kd&-y(tV66 z&#n${LM>YWPHCK{a`CF7d2c4;Hk3r=_X1ViF@F~Wqf~x#Hq&-+7ig;@l-Uim{{VJA z1hbS>$IWrh_|ceAdU3B*K+7sI>XpY_p=gbG2jZ53jru7z-w(Aq8yxQkS}NZ&Q^BVs z@Leab?+kkB{`C0?jODc~`D)8r4l`GwHP(uB!EY&^hUckRF zc(;PKy&b?&CuTV*kNf5T3uU66PT50geM5UGsk52)1a>;YEd@EMDp>UlREehJfY!*1 z19SBb8>y*UYC}aoV%loSQsJ1!2f+H`n16H)j4uP9A7Fs;z*-xRQq>u@fFZLKqZ3No z;6%_^=`(9LSfP9w*%5eYNbkiAPEuKzq8+>)3?BP{Q3`;UF5M|zt3!1`@;{Znzp#pcq8r#X4iFKrS8X< zCt%D>uvOb=r94fxUu{96t(_3ZG8s1k~0wr;@Iw%~^%=qm4qK46wH ze^FI+g>Fm(-!1~5-8>s{PD;*cx(h`AVX&FfdxKsRn+~H+C|ahCF`eZmXER`_OkAUn z;?N}EujIPp%n+w!u+bAU&>pp0JDsu-Y!)naNlx4WKm9=~<<+;*AX$OB`i>{k=c9gh zM$OjEJF1gAZ3Fp3!K!ZHo${bz1nAxoG?O}&1&rkqYu(j#Em1jI$V)GRpURCha?TZJ z(C;(?XRNdi_(0PrRoj_;i|BV8-sS)f8aa8yx!^#+X8SO2PPR8L)(vrjRv_=8JJFn^RpIh{i7)wo*0 zD0{W-QMjL5vfc3RsBcP;{nb$4AAn?C_HKEo8ZAJdouK_E@K)YUP{LJJ4o#Fx0(DbX zt^=_HLFa3rr|w6B9I->mU*HmWnF$Otz(4)a$hQKn<3ZiNw2fE=vh~Kv-wf(14?b(E zcY4>lsU9>?;jR`)+k?FzQQz<<<-aoWM%M%2{!&m)wQik`8g~Y`27pHAXe)RKwP8J| zuI$X!wQ>vsPn5;ZwLy~HRA1-aqnlSm8+xm9(_4P=JOM7~UF*{t<=qoCEgL6xpASyD z(PrsNTVwh3{%O>AKX4`n^NdRANB!Zevje7)A!t;R$6gts#!Uxd`g=fSMc-B%x}a3? z)`<>&0A<}lkFj97z8Gk{Lj+%Ck9ndPONwz7%PI| zr$M|ESf!{o=mUJ_fqB1xfmB@&a5NRT_XeM*f_h4e@w!JtcY}Bc$ zz(P?duj+X7ARXB=QIX?NrEEc46^cGONBa$+`U!d++JF~>F&jhyW4W%Tev&^)LETc@ z8ApZ`ABFm^A8&PhP|a_Em!&Yv1%fjDFmKid3yeV@6R^PwWT+tT9tM7dgQ?XR{Czzt zSQBjR1!~u$ZT&ISetGx43P3;{JD6;TT5}#Ol1p~z#WLkMX#SZee&}u;ya)`njpP?7 z-yuH0AiQ@}OcT@J&8#U=1o5GNe@kIHR(( zU0GtJgzKeCJiR;}1N2>DqTF>=x$#+us;iV*w*++1;Cl|B+85C35eTRc%9w$j%JEWH z!Npl%f=bYN{UyXi_wt}tyX69^D5Xja1<^X?T;=!%onucb>VJEIeHUPvL|g1k)M9r~ z@C)X|x~Q9VQF|+(+!Y1e&*0xX+VagoNe{3>FVfH5>DYS>l-BgKHlTLtZJ(>m?mUz> zTNmP6=QU=lZJ=lvc;640YN~efU%FE2z4HEcaygU;_R>xH ztpi3XS|cU{^SNN`1+ab;c%&C|m~wLc9MqpZ;BqTqQ-ulYhoI~lfa`iawQ3EH8-gAR z%4FTz_d%f2O3-NlD6BT~F`Q#a3)F1+^s?S>z2AW4%E=8n;9X(pSj^#?IZ741paD2m z8Ehy>$CFJccTGB5X}eX~xkAx@r5m-P5Buw)J-_b3;P+DN6#$>xV0S$Dsl2kZ0c$i> zb#w50BCzrY1?7nSa`Dt+;87K3Nzw~ERZq0b2d*{1N+a-AKY1cMf@j*xMU~f@|84Rm z<`w-~3|a!5^`TVe8Ep>5L07rBntmIY9Ys}D$kH;wqb(q$9w_1s3N~WMpr7E>0nD(? zp#Ei0?+2KzlJ-7@nImVRtWVHZ{V>?4P#9_gcjdv@TVR`V?YK&Yg@*L_3{1v=cB-~1 zO3VpL{_0vXO9yOr3U%!jDn_9=CI4+$3x=r7mCi#MUI7!TV_Gjo6;A@E)_{@YY3t{V z%F^Je@_6H_;L;IrO6HG0V7R=yP+vxNshE4@mx;>zp%%1l(3PyL|9GgHUgd>#@*{6S z|1%)g1@x*&M>VCRw>jg!YQB-mu&4TSLgFD*?cQLpl3}Y(9_Pq7rwmkxz6E?wgUVmQ z*>S*1ZN25#?4ID40fQ6d*nj=N6Zv#+2|CW`=AG2KEyyAM64z3%41b-y^Kvk%A?Dwn zsIpsutsK?cp2=1yqjzc7i*%9-dij3Q*+{EWvkB zt=v(SmCS9QgUj8(sQzGA4SIj+e?AY-$~E#E)P18KTROSHc}s?e5t%RjS6W#~jfTfots zprKUWRNy!VRO|ufVqx;}8x zi!oHbkI=p7(HT_JLMP6FZ*MuwSsn0)QuMX_@>Z4nj3!-C43v8WR_dCZ8p_}w%Is;0 zv^^OF*3JXV{lRrb>$din<_5mWu^u|~1!Z;>rPPGNJlkR*s&r$}^AYCM`zTYrk+wGg z^&&uvR^W{*=zJQiR6c*v8sRoP;UdSLlwSra|CZ^Mait%TIp|1R#1hP8Md71PG`s_- z&>Nii1)j^3gY<=;b_-Sg2Kdwrcn5$wDsL7+D9<=BQpMCT0d-m@pQ+EqwZ52z2BLyA z^Y!1L$P{o=DbU)Dj>X}q36nwT6Cg=>beqSqau@?LGLD8RCnFb!3$B( zhoS5=U-UL``WK7eorEf_a??l&GDfetSnV`i=WVF}24SjtziRp>D?y1!@Yw^z=`f4k znbb&MY}wjhs6Lf?GzPQe_WNO=cwfwZD!NVDV>YY`-WOM|KCO!#Mr}$5Wv7AkDYOk$ z^xt0uL&t)~8K7=?a8kv-;ZanQe1GL27-$TJ$ZL6W_S>D{SznNR3H;H0+at#&sKd+- zBy9liw8_&uP~m}KoZhD$GeM26psW`-T!A5n6#arq>iA5Qo65)?-OyI1AY6EVhTe!! z)L(7#{Af^gJ($=6{CNd7$gxwNfK(N&#wWpTE6n~WV44Ny4CVcDB~k+?V5}N8O68&T zDlqUmFt`lv>a`i5JYC-w(@kDm(;fUR2lne7;Gq{wZ~cPvRJ8W#wO;KtYO%f)4fI5Y zCT*|jt1CAG-_S8^4a!458y2Xv6ww>5+Fq2`bYM0L6w;@wlP@TtjlWTyd_4f%PtLq>wzFlnKQrBx{*T^jDlK1zfC|?z z+vqTdHlt2eNByja^4EnZJ{b5aF^~QLJ99yxa<_qs$Kw*HPWyqCH>RP^+eV3b<~Ycg z?@gZLu=es~xaNzW3x;lDuv-scQ=Hxa&0IME^dCc;QCHL)t$RWjyPIm_hWV)Tn%+q} zcqZ4ixd2wq0n4=e?b=3a7MSHGr9TAiQ*KN@iMgpLD4GUl$b3GW4x2uxF1Jv|iKydx zBSx76!+jvy1q7%vSm>x8Pf<>jP>oek%IO?Ev}Dcqm=ARgejPwP(i(Pp*5eg8t%b%^ z05)BL*%I2C=)XMZ{S$T75KPm*Gfx_gDz7_}*$>on1@5OoSCzhv%AtvSz$0hSHx4wC z53K)!6AJR2MvSwKKxH_AuEGM{-}e)M?MslT={J4_8#;n&)4>hBdk$uSRrfIWZv+FU z3a3C3-M8<02V_U1Ug=@RBExqa4e(8>s$(_e_ZexWwVli&Me)>g?lla1+Ig3{7K zFREV|z+oB~EZ6NB!4Oxy&+j+ItfC;VD2`cOUoywaf{=~s)sPjs73Dp_zKURIM<&g( zK^<)m`acGrUw{yOrd&UdI(caB3Oo zXa&AjW~!Y_QMdnrKb?V#l5kKn7C)f7KWwDh#)2|B^q!We!wbPW3vehCylPE{fl_|? zCrpEH;I6jo=1<%ES->k7Ge*e}q_|lm(so7Z^Hdkn;|^-29NX$7rhy7$F$JKVF9=jV zXI29FPdMd(arEXb#&p{N7M%fibU)HnWXwl0l_7CjN0op>n?ZRRc@q&pepOx;aTjj%M99l z-hf`Z?AcvFy-{GQ%<>+L3)bt&#R@!f0pW_dwH$j-x$6{&GF=8j6{xlWV6zv9(b-mCGg#5z)IeA+Ye?P1!0F6 z7bS<8Zv)jEGjpoaY|ahT2xa17y+mHdhY1NCPlT4l~n|*C(P3BEcVJr?+|+*Tk%N7rY*Zc`5;vtctngEvRI{Lb;kW!5+Nq z1THE@<5NK+WklOS;FBRZ^@=CP>h8}ThgsMX80jKj4FG$VfIj*-nOguf&BjcUv)lIp z)&)VhBE3!5VErZ4qk{5x;dfg2kfa;|pZQPd$jCzAG z)tnoP=$)!lHq-ss)(5kw#vSj3`m0xJpbAfp4tUZC*c<~VHZs9L-FVLhm@)4`?ZIG# zwl*ynv{%|rz6Y*80U`2+rwZuD*3_^@DsyMFxM6+Zqjj5Zrfua)P_Q+)(-9OZPlvxF zYHfXxtb6oXSL2#4MB8$pTL!o_ig6vZPaA0sqy$z2Bcmn=^#LF5g5A0}A?HwC^=#Hl z%(lf)-ZBsA!@7zYYL73f%}>-xRhq61Fb7+piYn60l;{(Nfj9HO7lnIy3`0^Pz~6k# z!46>lFOV>eHv8Tv$4RIHIbe`6*yT^#b0vC%fuOCf&}{{8rWGN}oP~Kq>mE?sbFI2SB;)UL(2@O#@O;G+Z8lokmFQfcIP;25*2I-)qHd%8OSoH^Z z@1ZyQ2g*-LljjT)R?t>SPt30bE-H&RHv(UEHRe79O%{R;igZ+M;5rQ~zXa-N8@qH( zTbhCni$L{@V6~PEuEqf^U6|g(1oO%>ur?DM)>Lh+L06UQvZ25$2W-h=aNZSED^0c9 z4>RK}Dst|Be~GJ^gq}8sX~zyn9ex3>t02DFfeKV+)zJQ3wBdeDLBnp~)g4f#CgT=r zsbyNKTs>y_rzCx*WJ%Sob9CdHXm36<)T_>`y1R(0MR=36h)-5 zGirj0{X7j`w+&?80u@St_d`JE{q#nc1N|Fde%K0Z6Txb|$lht=Qp#{pjIH*^G$6!{?6VYO543V4wTfp_@}PtxH!!BDh4&R&@`PbScP-1{s6v7o4mN5 zHYb(PvOPgpMPZZ&uxUkaDY-7FENFWO7_|n8`ozIO4FvD5W0u!Hu>`8xHCFQNYz}G_ zrsJ~CHqr`nS1Aw?4YIbgmyWt7mF2`r3S+4JQb%Tl1=!yPB&UNZcfqiH@J9hXt-Z`I z1a>S3-UmUiEuf&D7_05p?gTc=B^MR9j@Nr^|h;m&A%jjMnIqapxHc58 z9~JK5sJG|TaTeI02m2R*uO;dA(f#(+mtw!8sGO0YW@pS``Sgoo-r5J8R$~58Xf5jj zgPOqWBiQQ?URDA%Zh&4I{BZ|ZXTdD5G;_~=nAOUIbFIJ;9lDeL*Z3y+Nz? zm|wN~`aUR6wG~$^Ykol)>6H<&8MRgMxS)*(Yvv2em!1_sl^P6*@vSn3Yurhzl+UEl|bJpn)d0;iiGx)|8p1#D89nd^z^ z&-(%L)m9)|a*Xwzxpd`>F3>f|fA3lOa{ZIM7k45b+ z3GDsBQpMLlh>nvQTz4Szjg}8`b<|A>Aln|?kcWya2KVI%-(g_63We8NFiDwM=mMCk zD;ck;5>JDJr$9@kPg+&5_ZJu(${L=RK)zC7nKm>#3Jg+>{ns4Tuo234BPz2F>iad+ zw;7;MQOq*0P^)!eE2#>kjt0LC>8Se^w+w1T9aJ$z-=i32 z@?BKE>Ol{8%$jpCYcB(DI$;_Zq2jlJ14#_|sqel)doio)SgYbdv&Ue{TsnR>1-Jfl zm}YJ^0Blr1H|Bx+je(!Gu`UI?S1Py609)2E^H(`+#&O{E3=BWYvkMBLO8f*qZ80r$ zD+=hm$xA`T7)*ohz-0$!N5yh#BxXas^ERiT;#D!Du7a<6_YC)9$ohq-W`|MtPk@73 z@|QweUC}Di9eC?4bU@xU(@XP9UsMSV&eq%I^$}q0Ku5Gb5})kE{GcI~^D!TVfd#4? zBf7GUzt8D-p;O-1SK*%KsNs4WycQPB#x$2FJzPO`YtUSg4r)iQt?s^|C+2`e@XZDM z)x9k209x39FK?cnVdRx3A&C%)=dxD28#$Qk(0z`U!PctZc1r&D?&K?xVToR0Q) zXxr8VwKt8n2`Viu%)vcHYhY7Qe+KxdB&_ou6s*X5W@;r=wHtIClQ**T1$fCH9MXB$ z>cS>zf{QAGiF%=JR(O_oL7hE>`mhRA*PT9J50ublTJQs`JOf^+X8)g~^N#EJ`{KC0 zH(3!fLsm#+CnH%INk$rytc;{V$}VM(tVlw#l2r+rMfR5T6{74tf6v$NpXcLs?!E8# z``&ZUIrshfRNRRGQF_f8#Mjp_XYOtJ>^<-dM&K{-zl;f1qn9YftUWAK5#s6|t7r`>-jw}!MC z-$d=30%rPvGXCJT)=|DW>Y+m5llJ#w6V%D-V9+11dJyRT30!{&S}2Mw{J<&2eUF`} zExo{R-C(iSHY5u~PXjZRjkj$WS1b@^t=-DKf=ccI5}PsSGxGQkZOR%gU8eZET@SUTF32s7d9@DMt!S^J ziaxIf&#gTM^GrF+%*mL=YlD`0u7`f0nWwT|LuYq_LS={{>ShtpQl;S*sXQ+!3{0sWDpzU#I6_$7AqbAs_ky zc+CW3<>zy{pSxnnRB_c)cdqFIg4T1ZFx_hD43v#Zz13*U^Y6h0MN_CN7+s$ZKlxyk zP+~l0-cGRf1sIf1Tl13O#6(ad5xDB%fA#&*2NnHddV$=jM>-UVD@Q&n=F*XlQv>5 zRKmv10vQ??qS$B?3(|*TnmD39E(U+EV%j-?9v8vxKj4FWZ_*l+uT9jg|AiW@?QWx8 zIHn)(c2IaPuK-Fd!0fKvFQBh_eoRKW>5OVDxBpTMZBy80OaNW{=$P^oY^n(sRt4AG z>4>lajShn<*0dFN2Gh1+?rR1bYz3}u!63coPWm&^^WDCzE)f?d5q=c=H5W5!w6Lk;{0BG+LSS_Ud?!aUg= zbo>eKX)(vAfw$VN)=IiQq2R_k@WP5Kip>G9lsGRv!2<2Vi07c6PQ(zMmxDByR`TwP z?O>&b#0AokHv?r;9p%ARxZm-}*P4##gUhQ7y4vf)p?2)eM?KH81E|;?r0DQSlH-Rc zyG%C#UnO~+THsG%ZO|*)rf6IXJz$^-YLj;T#5nHPL77zM1E{ByaM2-#Ja9t!D~@Z8 zNA-UKy!4*YY!3HZI2?1cw(6-8|I=VPda71CZN_Xc0IbmM4~GFit)srGgrRQmIG(lw zy-@E|2cFA~;VORSOF*3);P+WjMnkHmp?V7^A}~GQq3VT$9#&v?J5YTwFz5-)J~3ol zL6EFn|ERqEqyw~#;weE#!52$ZP(@Uzf@P1^TRR(bg*I}B((ZE~7Fbj7Bm1=fb233i zV}@*W2We6CI_rFSAs>Wkfgd!X*?yp30vMomMC<5VGKedt%T50E!D#l?W3jfZha2$q zrI$Z}Ald!{v)sAqo4TmKihLhc?PChfPkJMF*iBn+Rg=x~#tUDNr|Q04`Lp*gYQ-0n z=}j<8L3L7RY?j{fhH7o;^HHCTP`@ovr&T44MuW#n#pQ2+waR66B}Z>f!^?yj+~0|^ zRf^>d0uA-t_sfArSMJgz2DQPMalikf7AY@o>h@bMqI!P@h2MgUDy!#}vWv|?@Dqkq z8Ht)W4z%3^2I&U&_T0*T5xu|eV)iu#W7>f1hhUaG8F~N&%mpRZFz$#Btz~7wM^%_i z6_+Pb^af7>tCeEWd%+ncuaP#uO$)5Q3^Y}Y57+X)T95|q`=NH_13T?jd?avGfb1;7 zP5Wuw5glZ9JyGTKHgBP5dNt|)U&G}ur=ezI!2<5HJjN*KF82mzN_i_q-o^m1Rzdf6 z2QPGXSn@r$z33SQnug_iuz5I` z9{|oO&Bw+t#KRHnzJOUg1`L;nPsp6snvP2+QGwdF+FjYo5?Wx(LZ}}4EWIKRvzqEy zBb^S%+i^u5t>{H#@N6uYq6c~CFq>Tg)m%RVSh@q#O%K{+1YDI`8|A-(%73c}OKH%ji+S=>&=BOgE>vH^3xi0EpPcXkJ@Mr>tC`(fm3?6sD za~;52Z9!TG@Ng+@8=8X*t@r0SP$m`Z&^ch!LC)@v8ls<@{X9j-{uEHq2b{A77aG#h zPxXC_#$DA+o6H3Px|N?o+42w==m~0S<&PEPJ5;WU?E}_|>~Fh4i!NZC28T`ry&HjM z)*xBFKV6Ooo&1P0@Zv${6)_LX+1<=hj$={1ZqPeGuO0=ep|)2B3H3ndm*9ui`=2H` zLS7qMi?##0!BvIm?ai3cJ-}%V4xI<$wKI`s^!6(bIz9l&WoUCy`u(ki*-O4MD@MsV zJqZ=3%}bXj|J?&e{XohE@Ll!uM-|{854BY2xgP^(u{P{5s?$ke^A9ZD1!i3awL5`oT5s$QRJ`yu z0>tQ)HF$~|sV&P}0u}~>QJPxKKA_Nk@N6=ea)7~WH1QUX!AzAj*Nb4B60Ev*tGEt> z+=rlLF7VXrrh$C5q9Nuw)$)6W;KmV|J3)Xay|vDxw#v_!nsCKLl>!f2+8&+-=jGk& zj$ru)I-0pMq>%PEI|$s+9<|WRQp0Ev<_0<`^bHezx+TTYc2G{@`cbLNVh!W8t2KBQyZEaqGEER5()pSf#h^D+pwJr}fsTR*tdEKxU zGpIFKtU8n?zl^92KFVu;%TXoz0xO;Uqcz<}jp#V4bL*MBk*cWs&=16Ek`dbE0;Wu( z?Fo(3+B#gI?cz05b1OP>6(EI#mI~_0+J(@|^yVl!6BPm{+Ja5;P-!j3yB3$dP!Rr$ z1V!G0%T2-eTcDH9^a08@Yi-K2akM>b3>xTGz2AU=mSBJ?aB=@vvLF>y^1(ZUl<(t4MLfvY++C-|Yv(on9N_^M^#?on|18JMmRUEYu0rRP8?U2)EV zwwB)Dm(D1QB-G1Z;HQE=%A2+^it$1=prW=Sa1(9Wn$U?EsIyw7ky0q28z%oW1%p){ z4t+&MYHcsmz*?OPeUw7m^jXD~fWL^46#@E$f`TTOkQ` zMurAYIC87U+=<7OewL2f+aYkfWn=n=#7$ z6ey;!UDgd%`V9}7umH8HJ1VUt9cPY$kN0Vtrt5B)o|oAhaJMLPIu z2sXvhQA>%vcoV3T2wFD>&ojXMnp{!N4pkzQ!F9)=wtS$isZNrl6`22QP=$7(5>9|( zI@u2$0c(9h2QAu7(`c-K>op!6)7Nylx_#wCsHR%rW*1a7`CyAu<7GY6>SkbLC9uB* zZG|+AXE`8j3RtFEa_TiWeGeSc_lDJaFmC2(%yxs+(F#;iLj0$Y3e^jrw_@#qPMji2 z(-#Vw)YGVc$5E>*f&y~3YZN%IxfD=v=+Em0ayD4sHP&*Lt$Is zFRHTg!>=?C-+Te}CjpF8fp=7u8fby)DUYvLF!;!w?X~9v4ukJAK=xD+qe6SWG`OqC z`5BHHxftxW!falE+s|K)x}<5ejRr=V+9$a#L_V0G0{ni1yPDb^t*!1h@K}2}RykOp zA=o;Yn^u^E3fAAhbsvLiBOe@9aXTN0DzqJ>DYECN?UYJiU?ArE?jS>vlRFJqs{l;b zcU(~;84|BKkJ6%D^uS8Ra&_vY0E=a9=8Cq zMq}=LJ_&WtA1qf@*{32M{RFi~oA*VYOi`g|qL=7NolzSUjxn>q25oXZMP0vrpioCp z=Q?fKk5Mn;L3RYNDGSQ<0si?QFp(j}l{n@;psmV7!WS_6Eyz)Iyq|~Ks_NY`9`mD0 zy~R7s29rS3>X;k)qb8{o)KoA$(@FeA@p4g_JkJRn)GDJw!AMo9m3vSVf zsdpf$5h&e;-iz14wND^w6xewZv_A$adNCw#7ix&o)Ugj{)8nYw2B;fa+YJ3Y*eDaT zc`eMX79d0E;--u`AeWrgk?`juSoQ|Yn#|xw3bTuiz)sEdiy3Xp>!D)fP($>LAicl% z?MBs5wMdeOhH5U0v;mz}8Eh(mUaCkrXHbz}L748h`Xp@`o~S3OK~n zlh>L~2CmBU6y;kJJ+1P4ZtzpvGav#yI}5(w1P|7M<&nTG5SSbRNs1hMRhrE@5?bov zC5!OLukv3jXW(^@wp?Y(Yz5pqJ!sbl5E%x}$uFJd7r*{o7N}BCcLX@0y5_$EJaM7- zhc?PmRp7KfXm^xjE6OkLRg6B{gIIm#+juh_QS&i>=un@a?MYPV4OI42S_rZ{XbUq& zHPf99s{>C(`|1v;ov*>|J(y>@p^E!))4N)E{Al2&NVL@aTy)|@OF3*{$Rsa%XDNpM zYV(Fn0=c{CJ+2~i%m;OIF6zisFyRbru$zwcsRy9FY25+=%FwWK`Wpo~--daEr;Q*$hjnx<`DrR23%Ir4pm z%5z7}T?`VnrJd!(eltNeJ#E`C9+anZqqh>UatV;*fSKzJ9;$Lw*a)8Kxs5Xz?5fLp z)uGo!<+6?rk6%aV2;76(Kb^L2%}_lRN-O14KIo$yn5Ty~QQn5H1Tho9Y(*V^)kNB@24z%D zYL;i?)6bxWtmn?-wYA~xn8s*D&SSZ=s;1FGgFD;+w>ko|b)bR*{g+<&=cfZlMeJ#P zFm2czbE)F$)i_M6vfQt;mOADyC|48wQ*eD#Q1{VROw;|Q{sbqoK(^B5{!?IU!wv4s z#Xsr+3x5zG=ai^ONB$DjOl4>#{kczt2DDWR!OZLqCPjcW&E9Y)Sh*H7?gD}vg52Gp zi56JF9URp<##?X~yBt)KBD=Su?q5FY#u(5-<*ks+<*hIqD8h!y5nXH2@%1GtN7$AIi(Vns^K0P8|?B1|%u;ZWiZ?Z@p08M+-#^+Y?^ z)fZn4SFm)Kh6}_Y`dHgZWIJ@w>@vlCPqS^kfUA zr==1)P6=2h5S-Go%}#+92K1VoMIBV~j!OecwP|xug)wRX%KZg}Vrbj?2V988JmUmP zJplvjv(BLQsPs%=JOmhOLWUk-=TNS=7lNvz6*o{SevmH>mw-xgKm!+sTw0E*+7Y$q zF=~~5QhCr1m8a>>dIyHJpf|=GlwE=OZXPJ5%CY7*NbF8W?@y>-xxi3caH22xS|7aD zRy8Qikj<^YmjT>)NDO%?PAnW1wsB$)Cy~`So7N}KY!CBJ1CeR zJYn$uNvI=x!Tj04yD6w6x7S|^&Iy`c8a=B~(ElfdT3EI}F!aS{jis}grlsbWO*nirO?>j)G zPL)+&sI4EEkhu;mhXvqU3LVd)P!U$B(Q8qMwU#b<*(~fTePI6c^ z-S3b#+4BsjskUwx!0>Mjsp$mP=||M=qiFkKi+TSL>Q63ho})q0t(YHLpcZ^atxyKM zn1Kph2r9^v7RrG1RB%L5ytzGtTb@R>)yL3oDk<$%r%KDGmMRNNJyF$ffpqPbr^jds()x^o~* zaq6L5Xg?HBb~ukR*#qJ>g7S4}%aRYADpD;DYZ~@Lz#Rp8Wo7c4+F;UM@NF)bt6FkT zyI(X046y=hgg+yIMI!j9Sp{lbyyBowOJ+4pS$6U=XnqN-){x)MpmH9lsHz>S^&02} zsmESsm8;;2QLvWRH{%0!`$TVW$sH`vNtma?6Ch^?G)5)rl;8FXv)^;DwE@`EgJo?z zihAPD6#-RHYvq^aC&9$gTyavqveFsWvmL6Ss>)++^0QZ{uKHj-*AZ;cV84aj<@jDy z|2<&Te++4*EBHaps5dS`>+ z`XDKZw#&-0o0@Jt&2K~?D6@lyFW!JMt_SWs1oKORb4$QMee2Ln-@%ORg}MF<*gOyf zZUS#Af=en7_Upkn6~SP8a5Mt5VIPpyhTDhgYledIMqakgAkQm-_@wF(fEF>ytZAA@O_2~Gt)EVgPCJ6|87_BTFk*sP!9*v zyGbG1AOo!Trp;F2y+LiIMghASAfN@v)o1TVdi#m3fcadXREFs;$9IGM?ZFB?yhl8} z*0n%Wg?!b{v>Bd2)y)UT6dUs+X=_&*ywI%ry{9d2BzT_yrsy>2v|9i zHZgdP!h8E$%#d3kQSXdide^FFg4s>e9sCL8YtaX`fGi#UUb=l|DoAt1be)I_))KZo zLjBUGHM1mCJ-NN(3Sdz~rWqKn7hAWEsOi5z*~^$_DqrVSxN}#6qfde9P1^j1qV@!V z$o`>yuITBpWX<-!wX{1R>6D}A0V6NNGg1)&P>Q*v>h_V?5f+MX5=Y%y<0 z*`Gtjs&aYi6gOAF+ow`cG?rU+bD*v767VLLwu%8DB@YbJZh0i54o86~NAOm$)>0er zsTjS!eZcdpnAX`SlW^3msi=3mQO)&#DpXL(sP3VT)}YM<%&u!thsJ)%PS@ccNOC zLWPC{_x70mlmRX(3Uw-h+!}NYG(@$U1$N8#F4_eL<^BYP%3`H>d0pnMxAbkgOZl#- zN{vucM}fdOpsJ=@Sw09?S(>95>U9a&D@qo5aK+j!Xm0Lur1@_K)X*2)`dYGrh1rvbpE9380&^gmL= zwC8_cf{vX)*AKwY24pC$2Ka);T0+-fV7u~s>nH5mk%V>;^2=GwQQ0NM^Gpn4TT zRV>b&+wa31EKFC$Jg9Wup%;u^YRhv5O_Vs(yMm$Xz-&Ky2Wv6=dIN(t;O18lJsXtO zcE42)9*YC3HPcr5bq{BgQUEAor2N-J|bxgr`1>yA7 zj5Cra<4<9(Q?duy{r_vYuL_op4{7*Q0<3extfDBt)&cW~4>+L=$$Lgy&S2D08{njU z*mwa9RVEFL0Ik1)@D{-21}MJ;L~5N|&Vq5;*Y%1vqa3h7FB@%*!NZ!Eg|!894};O# zsvJ40kp>S_0V}6-Bgz?7Ll55+3JRzU)>C}e(sCx|qiU)KciV+B)cH~|3^ST_dK{jH z2a{E6wyDDWSC-xa+S1_vZ{Hr;_9$11X&>6hqsHF?nJP0Wy}(qxv2992C3gT#<<;|6 zpn)=}ho)hq>NHoO9-)LOq7^MylCRV|Ue_YD)sqh_6jZadqI=rmVWWZdL3&RN2fb22 zyVJC_U5RpcLZvyOI_W``wBhETX>0cnJWz?+x*FV3FfXtLotJ?tkHOo1z)nugR>eB1 zs<@*ds(^A}x;|*kor}8t9QdpPIXV+P7o!YrgUzKG{PP~Fnm_Q}2wZiSl8UkECg62P z@Kd$s$RuDt0Gw9uAyqbCIo4kJ-Q5~IJA%37Cn`?wH)+buX_`SreOPtX0w?KOQ#0_) z4YP^j%1Fh)LoxKRIoRG3bXA?N`+tY&L5D0s&8M_YQq;v>1}BDqsp?&-B9x_HOK(#J z)nGXosXK2{y*;UE#Qp|d^zeB_7+3Hi>V#$xVTrn^`jew|Ov$3Ht|H>%!x{XiELgNYjV`Z66E9;mrjL1W#;YC7tOs>G~m zsOIHB#7WG$+R)K@*&Stv`tb;OswT}>x(q9f`m1exso+1X6SJ?}K1WeIOO~iF>-!HnSxwpRV=BPX-<2T_0tr!Ej9b7oepUc*6x;R;-zpvsAGNjOw?&_;C2-ZR` zXtM(p(tad3pk~N9&OgA2v0(Eia6ps%uIc{L>qN>oRB^52*>Kd6R-laz)#|#zOBKuS zlTk^tL89VxvwH6-vgc`P6JCQS3ddp^l7AogZs)Rv@|DFa5Ti3YK-2ZJ!gMr4UCTv% z)QjGYKd9^T!0-{6%{0GzslewvI4Vc99Ye=$t>ZxuxUa*e+H`iN{6x%}{V-pjLZycT z_rJhEr%QDqBN~j{z>xLYnOpksQD+fqcN8e0YT>VQ%UWkjfKIx_fnan2{M^$Qb@(ed zGZ)mWeNbwF4|P#!Qy)(=_Cc=J#R&Fb)H++JLb-lsakoUMh1RHH~~#pVe1@ zr`%+64&2hg*ZUu;!FZ6;6VppyMIF)XH*5JG*&th&tx=}DYEAED`QV^BinIm|beAnj zsA{SQqZ@#>sxLpCfnPt+Tr)^o3bN&<_3kjX$;(yt9!JzBT6BM z?wCpPdV#)|!En`s`PCTw+#WyBZdOOR4 zN5yDMwUT)c)GdeC!Zpb^Pl2C)IWJrFuY*=@5CkHsgB>~+=gW1OS>WXqU^W4)>_*2m zIq`E7RMYyXfbF3BY0NN{;V$zrOAZA+<1s&bqaM`fLHVCi7rTKxrE{Jp9<0<|u!V6= zzMxDlf|{ckd}}buUhk9Jl-RSiz#K=Ap%=b_PN+ZIP(RdLMPKQbQqWADLYvufRB6pG ze-LVr&fo49pkoNQP?Evtm!pien2AMDtr~*a%HJ?$_pT>kby3FMQAP4B0qPinw#vp3 z`P9K0^-;OiRqD=Ka9A&a+e@KV>CO$ug0!l@T+V)e9V|Z&VildQ_M%3t15v6z2O7~9 zqD9Z$2(G9E)lEe?D=X?K2hXWcR0>8dNI<#Cbywx=T|0rlHolNTw65~fP}SUHpM)ywjwi);GX;Ij2NN&~Y0G zo6hp9Yr0*1K}U)7V|WL|^^7=wsYq4cS-++*t@>6`1pu(UBgD@>vaD z?EwB;K*z4Y*M;6wcTq$B1D!P8^_tKq572B0FeuKDae6g)*b~#MJ$U~bv!tq2fS%Uv zHF!Q1G*pT=P+-a7`_AH*M#0QGW*k1G%o=c-lr8qxQLgxq9(0pq0N+{23|1 zOb>zf+LU*?^C%qz2jek=<bZ3R{jR52>P4`ZqB6pvhkSeZiTfBIo+B_{Bn!72sxs*Zf~^-cq|7obAi!J zaNiD;cn?ksMMzVD~5_{S;p3=C#nq2Dim=Bs7<<``#3N#1`Lp@ zpv^NMiYltjo2ywhD+`Xw8}&55W`i)JwxfRh0$nbFG1`=>iQwZ?@cb>`oIvK}CC#mUT_fEuq{p(-GZI-VL7*%1i^3M$u7ZIH;na zu9^or>YJKsD%aNGbQD+x-j%@IzX)Y3jMF3g4WTXn7OH6`_-2dwXbGy88|bOS!KxXz za-D+eE}y1NNBR4J2G-z;(*EHwR4F-enR=^y2JijAR6YD=4p`U`=UhofU7H9R738v5 zMMTO#kSaF?>;=y==&)Of+T#mmGzEc^z>4m4oKjs2)nWpUF{|?)sQ<=+>MAV`Q7GqY zbhO@$a?Ll%0)=P-I&lM?L%h4KAb1K7tC`ZXcDKaNTO5R+-fcMCj#x zp~A6QKd_`Z=DyXa2|C7pI$$nRCf}?UY~JVwF38_gTGqG zJwFwu|VxC@0sB0T1+P*Wxb9D<1V;LA9=`%*Mb$#UMuSUv*2NwpRf`a<_-_=bZ`Y zsQ13JPT+=CXB9-7<$Bb8#rslk%mRvpf}Od`PW`;Mn8IthKABZsPp|)Vkfz}4XbZd) zi|2Fc9a9^eX#rlS9R2A*#}4JniUpXaT~LNc!6-Q(xiWaIBq}nJ-Vpr`)GtZEgEQpkzJJa2&X#Gu9yvHA8W{K{0WA zKX6iA>Aw>7^E{X@{{;!%XM^)AK;fkzQ_KH15x7_}@!1immnv2#EVx1Oh2ZrEaHuyh z=mpMYgQ7YUt&Bm_a|~Xz5Dd5tZfCN*8Tt<6h)U1elbEj@!FJug={Dx)B6nUHK<^Yit?xrH>;(u>+=re9CL=(`WYFgX zc)Xawo(F)bN@G<+?qX64Rc1PEJ-eXn^^9`5HtjOF^9rn0$OmZR&$YGpls(IuaK&%^ zMZ=#fsAkdNt0wfMA-G%@v%5+~ii(DnW>8&Gd{xRwWucKd9RX8NyOhZ*ZUS?~OJjHN z&JH|Q5SHJ^xRHUVhKEr0`pT-7k}3Te_+$y5od@13gGOx`GB_G_Iv-T%hiUo^wc8(D zi3D{@g7JIlc%dS5N7HC7XOGOcJsHLjuy)?BgassbmjO(mC~|cgjY*=CcBo zrW<&K({VKb<YQoG=wUpX15*Mz4XfR#dT&u@@<9kYwFXM$d- z9^U{thM41jg6?NDq!4WmTIy&WbHhfEq1M@$_nbk;4YVzcMP2U$!d$^)rR2DksO$ic zqg2b+CLhtmofA>%hrxZ_{*X2I>-7hfq;oP+1-{7$5U9V6yD7hP*M4{_Vhx^vd0Mow zUTCcKt`Mn&a2N%$v@9Qm-p^w6PO66r(9}Xypiavhv#e21oKU51fNd9oTDA z_R3AE`sDLok6b>8wx05Ml(w;V61QL5leSMkFvIGgMys?0m|)&Ih)T%>?jB&QFDTQ5 zE4FJxBPM}2t!Rq~(~u0XL7xQLZl+_0Fk5~xRz-T>77I6(_P|9 zA2y&^U)uWYL_O9`kG2N!TJL4Kc!Dye&TEvnX4*|zk*%ect2T22TH9lW=AjI<)Y^*d?{VOVW-#i9vBrUh=0+lOkBS+?N7NYGlbyLAOP zrj!f}0PjtJb2|pNzKCj`4^A8czl+n>L_4!ancS!}dwzBdYM)NYNV(*D0vO^2k_XaO zqaZ^Xr2{K@caAe1bC!Xk4KS@#n|5hMbvJ-Y>Ug2`_BWz;S%1`#2_Q}@%F6{MgF(6z zy}uN;aiL&a1KQjxf&>L-_YPpw6);JO*sd6=P#3UKS-Vgt#5VcLU?nj0#B}-#Dqh2M z)YJS_v?6uwQH4OIP>`=0v2hpb>1c3yDKOsx)+v12D+BJI0{>J+Cs~2NlR=Ei(q<)g zszP9|-i-b(MD5%QyeEQxYRgjyyw^<~HPZ{V!Exnk6Aj7NUdHxDmGDRHP)t603EnH@ ziz=QM=q_n%QTwWcYc;`ooszkF_%lr{QtL=kHnz~08-9&JSQ2KXa;T=m!CZY`aW0Uy zBJ)8_ZTAgD_Pqm`FXn<@m%(p&D0mU*w3puTs$pBT=+?sJ#^7#Y+OA9mv*o6~+RLlj zqY%eZ92BN(-HC<^Vol&^*ziLn$?Dm;IHPgPun;` z`&PR%y_5778MF-ZdT-S5g`l_U+FLi;DwW};eH3s(IpBlp-;<9hGlhI)9tisba=hvA zsRSNQ0JG(xtr@^i=f}&ZAX0Pge+KnK3-nf1sjO)CP30LCo2(M2||W~y86lK1AEj;-O69PFr*%Me-1o4 z39c#gOcihwoWV3r_q#p@wfYb2zlmA39xBZVwWAIyU%%^iK;Au(4%(%GH+R6kTu}Kt zh*<&ReuFyaL4@3%{}xn91sDE-HvhO)ak(>dH)ewN$Y3YtbbTMtA_NT5cLcS^(NXac zNDKkta{J-Mj58>L3Q+~wC7&LUH!dsWGgZF+Z36>z4ldD|@~IN|aRr=Ff?2fU&OX{u zvlMy4jx5GT5Us>FhjJl>6k9PsxbnU!` zbj1JR+CIv`hRTJ!ekj++VAEL;_Y8O|-(2+;-bwLNdOPNg!l=pGqi##UxlfqY=b_#` z1V81@3c<8Zzl|z78udN}xM+`x90bL+@%>}Lu@PXq4|t{n_hSjvs&x!D{fZi<@vShrtFpwtz8%7xzJ}b^u?rTYg&VnHhA9cSP0ei|X43)kNdMl?KDEgM0G$u6rO@ zrNBp#{rej5?+Xl5Mv|NjCZcOtsWu3W2u+K%`zFW-5R`>mY4ni87aq`zpJuzXi3XfgEL2 zy&?2AP;xd1!fdJ~4AWb|nhB^`;lRWWGiw!y)m$naM5U_tZ8n(L5VM_j>zgSU(GjF< zq;0W$V5<$t^hE{gT&lo%ny(6W+ zLOJM)AO*v?_rO*&D6I&a+7I+s6!&=t!nNM+1!;3R0$PP)UeNj0I2D{diP=M5d#y}f zdlfj&0l`@yLlN;)WiGZ6s5OKuf^~weYY(>01d$Cutm@y7CZP2caI*sAI-Ev5J&o#L z3M^7I&D6n{uSfpW436t`nXd45(;vNhN1$391kDv|F7FxQrr(yWwir|g{Ap@g6}oBK zDzDd|;2ZG63#5MoCd!8C9l#$2ZhvR+eH-X{9vm15#>jc^R)c3BK}H?!y`w8CMMbxg za%Gz)>`)7HjUvWZPM$Uy<@^;j#R@e+r$E0POqYCcU2mh_cBrg1pk6!(`UGOMFi+K~ z^g)>GEWqY*n9;GQiwYLEOi;rCByFUvtp|wI$J_b~QJb`pSG0t|d%&u)V4b4ZSM}mS zC0*7Q_2((5qG+>I&iiQ#S{}!2I3FyOR~vi*hT7bvDuYiaqkgDZebFoZ)TTuK=wCc{ zpLV^rT%4?xXAKASwX8^M@NWkwsY3En8=j*$IjQ^Y)s~La&OPY{9z_hP=~J zAE3hi;Q*@3V3e7*qLY^8n1LGq4%Kx$n5)VgxfkS41Z9;yhN=zcWG4B6z4B>W#qL^_ z)%YtY8>P!CO|A1>U}ubZK#NY)xO)nLF4mZ3RQBiVWzxhJI4Zc71_QTtnCZ_^t#ux3 zQgoJ#!wglS`_%%o{&vh$QK(C?sN&;6gFcw6Z-87mB0Gt;Y5GKS zT)r9|3Cynp|M|2r}yvS!k@T{m!2Svq0KWl71X+>vxtR9ix8)HDsLcLMvzNN$C5;!;s3~mkLAJcJGlWZ{*vw*6_{OaJz2e7acZN2KEHg@99 zbLHYkahTb+Q3E|mx?L*L@AO`9`vq+y^@%lDt{d_dtkcxYHiOrS=k$Z9$qMf+s(-~> zfc1|+z*#V6Cot&9xa~VY%>QeIUTotdLG7{hjws7ClGmat&!a6Y2Q~E+xU3HgWpZh& zY6znB5Bh9VG3u`C5inO?tNR+2sRv~kVEU-^nJb<@$I#}a%70M1ziJbh9IbJ` z!9LaYXa!CEstkFt4P~J6(4aXmR6)L}Np_O|u4rp*mx7wT>3Efea@8cqsysNVI##QJ zs;bmT)jFOS0GkqEovtwPMa@^ezgZVmdk!dAmt80}0Cm?BOjWec&j96~F|LJbqNf6V z%MNfrN6fFrsU?wN6TsI$HS!Wz-+VU#jlX zWfbFnu0&ZW2sbKJ+J%D3Az+Ipv{26|tFk$12}4erp=vq;uYZ{CHmD7{Y5(0ILq)5w zs?T3T)CIj1ZBq6uRzmdA5R>}A-G(9iwcW*aWPS6a%|H=*;5BWxi{b3X3YvQQkkUkP ze^a~KOF^?~C)k#ZSzfL?uAQDR0*o9FtoPDpcLU|<1Fq(RmyN(&fAC82Jkk~A+XK}| zDVcu;T+OF#mL{}$HY!qT>=e{RAx2SWdmc4XXjKNx(~HA^_Nb#ObL;f*aymqcX%|-M z85x?(Zr#AE7x=Z6r5^8x>aLjdSNYoL%8-Jos1+(LdkTZsWocW~3Kf19H9!YYsY;-g zcF;(w!(UX_VAObp)I~S2I1Dp#A!^tnaO@X|{sW$?QkPS({;)#XFF;voT=Xa~VHR!Y zL%_{_n159n%$4lM{lNlFa;T#2wjTN01Vm}3rxY}<MO&zoHJ{LMPzR0^IHmZs-+k zrK0`2JNSE)XS90-n&_qDeGhs!Kcu77Vz64TAK|LZ|Yky7UrqL@f zQ=g%NbmwF_vE3>VxD51E;aR13r1x@cUCrLV4OrQZwh{xu49%d7Nk5U)(>VgZ)v2y~hN`kn)uU(>d|DQb5m)aZUFyV;<$e%-9D zih^%b)S;HN-A=+hvKD+!045qdM}CPqg;}Kv>Pa5TS>Zibp3Kvt?`Z}nMuPSY8PY^) z>a1eqzX{brb?Ac;7!f5@2I<S}RxTu%fM~sK zUe>!~wM@qSr($jsit=lNiVr}Y4+iTMG@s=0`pdb&;Nz$(|3Ek0G)|FS;VtMAhPFr|a3z~I7jtlbDdvPOsADR*1r^HOlyt8~ zv7(i6s56?gm3HQqJYGaDZW00_=YXxsl+W6-xhkcN`=dtw|7~3bDov}bdK!GyoFk$@ ze^YQsPkW+zFv1mcjS{h=?qVZv*m!{C$#mS&t-7jSh3=uPl0J#V>UH{gU$D6a7^_J- zZvo2`e}`t#c0_HlQm<`TM}^Or#;Qo`(t+b|I)>;gjSb3_X_268PjFIKwA+blwGtJ$ z0QK`1SZ=^wY?S+%>%lFZQ8Nt~QdRr0tv>4YNz_?&{0j$T^d{K00hi@}KwVJ(9 zI*d8~Fv`~u?5&9zukd!*4nC{~V{~d9tc|)q8g=#q>Vmw?PZV2>iFeNjRnWevTHYk-d`$iZ^#RQYO}ZhyfGcwC@uoVIL= zc6y;!`R6q-%L4H+v{mVVit$F}bOkd!!KUrBjnk?7O4<0a9&MkME(7!h?ZB~^1LeBc z|DRfEI%dqn9PkGC+hPW{2S<8fS}LUO?gG{dnwAB@#3alHBT$Q+fvr@gJRYjN?3oL8 zRHbda;$W(7V5fhNW$FRi%#_o4wzU0Ka6Q$mS{+3VugVbLZK#lY;9n{ztqqM-!ba;I zskKhEl={FT2jo1X<9isY$PSPnfm!W8Y{pM2CbZAEkKrMo$Z)LuT>ikj6HbxL{k zJ^_5uPIpnn?$gr_%t!rxi~9Kx)mNpy&nJ|BGmxlV_$(JcRpHK3OgiY=PkP4jv8=;g zQS4fg-jWum&`eNLkuy>IW~5#>AF!=BSUnN6Q?xHqjK4_(*AhWb<-Ub{;2Q{vC~=zZ zSDRjDqYPX7MSDm%!;;|r5ujh4J|NsALu+tnY zn}98sK-WfeUAO@jseY&a1>L>r*xwKA(ym9`0Jbl|8?7@^q1i^U9orC<L!M6jzT{oRO9CXk|K32{fuVZjEy==tR0@db$xbC#I z(OXEE0jAk1%=xMku8To?J)>$@U_BahOn*?YFYvJfU5C-}Oj}>BD9Ya%)lCsyHyzmR zr>&ks*gF$*lPT)JAAE3hBjzampH^jqFilnb%Bw`Ztjmzg*HNc+#r1a}@(k#%zch&` zLT|q2{AwuIw)RIQ>W`uFAE4fT1F1^mjn}|9C2!j~;IAiGz8c zFt6xMVxVTfRw-uJ2XkJAI`lNF5#YEUejo#QX+pE|z(IS=?cN|mANM@9)9d0vX+1os z5p$lI4*F>uE#>Dq^8Mjbs1l~AJQem!r$F&>m`{}^!yGY>Uqtvi-E8H-B-b-vvC%)1jh1&jq!4_TJ#) zD=`^Ne7PePWXHJ1E?M$bSAp0L3k8(h=uB~4M zbxvVXPZRH^)8b4iRGKPzQV&#%JhiD-FZ~QAtD=TRf{~3e2P*x>=-hp;2bEiovQ$N_ ztHLuztBlni4cSH86Geo1XWBL$KpoU>MQH;L%O&=cK_k_~PQr{pFl;K=tT1!cCa3i# z94+PSVM?KsEm7sFgH!r>+r?(6EhkYnL+HIGM|9R#-5x7ZujivYuL9G0;DJ)ZRzB_8 z4R!w}Fd7Fw%f;!FQMJ6m4o%~3D{!MMXe!^2R6$AT1?)7JC{tjdpgy)0{Ec0*sH^p;X%5gGsqyYA<>nm1+%T_6-4VM$)!(9x7SeX#W)qYyg7agDDC#OCN@$YWY^n z)FEFPrho!EIxhbP`&H%^%|cal20tHxQ-+{pYq0J(Xmc9Wkn5T%ass-66ZgSbWBfNq zk#kS#cSnY#v<7z_X}c*;w!4BluFnKsL14OKZK^4QA8$wXo&e6vLr+zt+p5ZM^kiIl zJ@VUE)VDRL_8q|nx$dX7wz-}$QSlr#11!|W2M-1(w_zH}2WJO>E9RITrh&bhP`xgo z;S1nffVQdqfxm*V(Jdx)F%Gq6DyXgvU6RST^X*aI8&JCy2i^9A8unoF1Fne5LM<`| zr*<%Ix86dAE9nO4Qw)YiRV$|TG|dZWmihB~33anN4ANCjhiWB%%ndZ=B9IS&d< z1g$sH@h=S3t~RRoZPWyn!^|z*<=R4&ufoDs4=U;bO8vi(C7=q(8@5W=%ytZ^8G%a5 z0HYOayG*#jnM;^eG-Rk8v0*LveHQo!&~{a~DzpzgQAMAbk2-IL%ASpKR&cc_j~VL$ z&gf}PhJ)b#z(-s5Rn9&f33@6zbCnRaw}SA7V9j+dYpU7%sbh>DdArkhI zQ15e4<9DG9G}FTJ!4vtQ?I~2Y+-{`Od{}EsP|idsAsQ**CO1W`u8y*~tivW}6&)7GKw=bd@uIDj4=Q;iNF5E@x&T{SIzA|8 zzUbPuU(}}3vd|jToJiZ)7}UnYAWQel(bGz(+>}>b^|fJEp}$cP3hyiCU|uX3rHx-} zs8=C5yY^aOngmAZcrsP^bWr8*?u6<#48)b@Rx{PML!~rRac`swY_bI`RDwll;(IG% zhReIlYon^`OnFfc^OprGNV!m3`7u~~ek&8yUo55M9Hl&JqZry*5WG|pU#){`XN7W5 zRUT6qv|115EdmSVlEL>t32oz!6p(ikJl4xZUHw+__#Dhqu{^h2IoggGgHPH#uWXc) zB0DtzWiKZh>sA%oU>49eev&tODT({3H&?eBI~n{|NL7@Jk87jOPh!Y)`7ciI47-)s zPqk$hw*ar+e0b{tt}FvZ%)sZX|GxtGDuw#P`z&aU>QB^T$g)&xj{#5wf?F05`T;+;fvC{xG zx-6KdH;M-Lz`zy2QRA8^YlmtF?+1f1^5p!M^!8VtKb(%brZOCN71Jyb)v7Vd=pm}A zj)@MdQ8g6@KXk3>1Td%{m?iJ-)^{T5XBl!!JJVtS7&M3uvkoZ7LEywX%tMN`f=ZW9 z-@wzOz<(=vp!|3>l3pv-)3NO^%PK@)HV4VJ;J(7_)fv!7yO5$4P1QJ8g;dKTpww`# z?Q{&)v=TU`{cT#3m^`EdXqes)x~ZDY?uc@6KqanZ$nFqSVX$HqhfS; z1la!rv*sw^cNf#i7;JB7$ET5K8 z-EC`wDycH^^eDk};Ehk+$J=q=5_N|lTPa_pf$ zn07}{)6+m?5@w_(e!m9FT!FbqzxeS;ZXezjB-+q6cOj~mUXQ-&Y4d8LHhw@Y4h2yO zT(Q-gw)R~x#}`LcRe>tE6J@6>$}1dO$zh+S0oP`9Y}ku>E=N33Os>|e>8d@T{djP8 z4)D_LLv+PJ4L+b<_^1#yO9x(xh?Pp%Zp!l^^D&p7Lm6pni*y6Vs=%w{;v5axQvzkD z%Kt!f`5#B;9oO^s#c_O%>{<5S63NO=B{SKhj3lHGMKVh$BSZsPk%Y1`v$B%CRaSOJ zLWG9#d%k}EJRh%f@BQ5Oz2}~D?z>OSPY2kW!lD=sz z{EfD5(U|MCg?CD;Yua0FKh#2<$76jT;ijO@(Z>Q)G5>T$rMG5+n)2ThEolBfu;(Ma zX*#1l+%zF>J9#nUP~|3@zH!XtqW?cs*1hto|n2SCVHT%{zaMo0A03XzSAx% z*kbPNh_VgZPL%V`jHpa1jmG}nmb=!x?{uBvOl9em(ZJZ5$R@X`)$ z9tNvbw;!r{Me#w`UPiS2QzE}r8Ct6AnyOSsb{l;UPqHKUBh&cd4t-)q(`f5HOtN9e=oyfSC6@j(t z$><)mS&Re@dq9Z(WVD_?9i<0jUW)@0n}H=tw_m!1zRL&Ax`S{X{vwUrv<|aT9Z+4B zw81y9-VS`#mwr}5P|tOYCl$4|<%9B-^$As~+Hyo+Vc-)mt0Wz^M2hPoYtYPtwubU} zg085Qr%=5nqV}&uWv>BG`+>*~;Is;tw?FFjA7HH&EL6a5^alSahN>%SKL=s1(Ruth zj0#bibbJZI!$Btvp0SzU&06Ftz0JhR2iba&NiYYqW`NCdd(BmBuwenPbu{KT-Np}A z@rhoVbb*P6l)^lz@NOOhiphTy!cZ+7!0rj4v>9!mGEw2hL8>wHc~=0(tms%PcW#r% z?~euk3BX1V4@zW6h1IAkD}ZSo@OcFAdWyul8^xjpyJ8f;Wg&e&>d_Dwr>0=u`!IUBliQkXvqHzP| z4VwtCTU8|MGWe~jR%mdP9$7t98|+HkPt_P}<864i z@E<6z!8P>r>2wu-OZ~LjS-$@>9JPKucw7+pXbT$6K(f(3K@(YJl~s8`reU`YNUVinV_V{vVs@^=N^*rKro&8U557&KXVBTo*|V zEixtpRaM*a>jgH~2k(5qfI;9;9fq{=MICs6ny(;ysEfV14zG~{Gd&OZspj+y0ZWty zsp+V!WN=3wFK-J%-GToOK6_;r9etE)*X%(=G-gaaT=H@cDpclcdvMO2UYk{@Trbe6 z5oWFFsFOO&NvUeO-n-+4n|q(>dttFnyKr{MGKGaL7U$tRGKv_@X^bX`zOp< z!KgI({<)re!W>M{)otDrwAHpOl*x$$Q5UuF13G{YHlWuDV4-*S=6c4nSnzi{gMU^> zJ-LS(uPm#k+BC=&)$KDd&=vx86hF%Xi~g9;o`cM?V1>@D)HBrmO5p7v@Zl=hpi)(7 z0$3(Tlv7$cDk1FNVfHQx-qgah*I%1I{e^m+M|!nI)G}|1>90jKan?TDV@vc z1Pv9ZZue2Iwdof_FyE*uH{T3Clmkv{XsfLP<)b+DYzGdE21ncQ$g=LJ6J_Y_e+Ct| z7Hrcgm@c6$#~0;L1m&-fjZ6W)QkL3Q$}ZGb6~<8)K{cJ=v`OG)6=q&*Ok2%sAaN>f z(}#kN9$;1nuu`|s^;~*wSAykoPL=DA-{Z3_HB+64|$!s@ff|j=CCaA3F^w3|F zggaxdR3;Z519qMT4=#YCqZo4O5$d1*1;@dfn2R>?i7E9^>+jLgw+irYO0TsQYJ>vG ztTh;@LEYz47l##N+r4puPQ`B@Pki8m|aRK83K-eo_?gvgNnxg-K zOa7SMRkN4PK>6roKI-tw$|Yv$WJxVv>E1pH`IMi|I7_@r!`m{hUu$MyuAgCl@Kn* zpqCfst90P6U!ZRZpl#!6a9D2-xn+Q{k|}Z`SZfR1j)47<;M^DR_5?%r-#``Ay>LuL zAxvrCZwKnoVDL$28LM3QrS(0|M`b@oHPg)hbb}qM4cYw72T(!F{Fup>3%3LV-WvhBo+B+d8C`R=x~|F9oHS1AAp&!CQQ6v@VRx zis$-@*qT>mst68Kfb6M4;{4YRvqm90g8flfbf77*^tNe;n)MHaU&hST0kqRve63J( zd!iB*8(Ve0*-lL5qCCH^X!7cWvXRyDaM0_C*_ya)$@s;9GOq8dA*g3h8+b+lD=btJfhS9)&lCg9cqcxQvq zccA_ork}Bvj}6x=`^I^+y;%f`3;`c3K&ZT%)eSXVG1Q?hJ2EYdILMkJ+qfvk5my0hkPd!4p<)UgA zK}}ci-xVp8?@9f5JKfED>IGj3_KK=n_7cnh3Spg^dDx>F?%d1Iu&!- zA<$nhS^wUky3PmTI>Ecwz=1I!OO+;eA8Ly?>XWWxOJCICWYmik5GhA={D5jU4UE>u zHWjDMUWqeh1?X^>wz1mQt6?q|NDoO7kKjiUu+Kl^A5U>TLs$3_HRa;Y3TSa@fw_vDpH76RlDQNnd zfNWE+N7IjK4{GXFa$6&mLp~~?7#O4TJ=qP6%mY^ydcQT5-(pZi?^g!1QSORPznh?f z!Z9lrRJjL|^_AeWB$SzgW{|R{xF&d{rM-IuEI!dTN2TS|B}|V!pp<$itp@MA&@pr} z>W2sDszZ+7$)w{|Hs`j(3_XE*W`b&OM@N!MO9#zzX9gJi4@}chSjRA=iI%%mKDfIJ zOx8ZW_6J=}>0PS*#%fg~KY&g1X)_#*I<7;W?*&%X0e=<6UFFWgwRz-DOU7NW1<86x zf1{(FXiM)iRU|uwPoS#V9-Z`(L@?BYkDciT`ZmWjS_(EOO@kxB)i%IcMJ7m&eQOE+ z>X2_}t7e~orT)C~`*qY!E!<8WCtCmi58~P@te>v}Uh?1*-4WJu%Jpz?QjyxE4Q+!L zgJ?ak$#ay63dD-GmxcIA8D(nIY{pYX!>N*IH?@t(dR%=Cs5H^O{_{yddW1^O%EGLi;43_Wu8~*XX^sjJ8KUv>nuS zT~N-6mb+)#fj4Kt>nGsYaC(oHLRl+>?P~%b{heZ<>V<_u>DU9{qIxm51lSjgdAcjO zY!5yk1W^Wb%-n(s8iks!5GksFY@zi{EP#2d3(810lIK>Gza#h&1iI^>@)g_tCStC! z2BQMNwLIDyA3zP&N@rBW?5G8`P@Nhh7oS(jyKx4Uo&{Vq*y=oOcE`YQeZ^GmFm3Ji zvB`n7ZR>~Hr&XmY7Mm(69rga;uA}f!2vm;&K}zlJ{@|UqYO6#zr44>lgq@NT?e!Wn zObO#IMC(52upBH>%m%3rxF~$uDx?BF0yAA{HFcn8=FofF8T1~2=|7bKS>uWNtGzAM z{SvEjB~=zaDapg-tGBvP8jJ^l+T}8(-5s4}6J_Qlh2vf2N?se3!8|aeG3H2JU+bP> zmQ^u0TNU%2>PlO^E_Mh99!i7X-{`H;7S&(Aa{r52M%Tkh-QyoCVm{T7Vc#%&)kD?Y zgL)W-TC1NTQeS}1`tE7c0+grTmtytVoyw@Wx*m$Hr{lPs=sX!Savv(%3hY$8Jl1j# zD#8xw%(qMjTkJ)fcCN;HK_k_Zf_q=U7p z$;&~Y!Ztz&`b;N%XczDZW|n5kkJc0D$eRjwXt@(~wRFh=F_|D<#W_f2)gyx5VhWnB z_TZBOGo>yVqBHug6|AlU{RObPFqTCRD=oWbqZK%A2CXo zYAQx`RF>Y>!JMN@KSn!BO9!C}i(y*EU`0urHz>PzsKwJ!5${o*G}REL_}u_-L%}sx zzJHd4`9i+$HW2t621EQnxf*nQRbGyZ15@SQ7+s}Koq)$&%thLf*Im$8Z^3&MYn?Rn zmr%?XuTbM^f{)6Nqxz<`lP>8Qz4`1)M{wT()AGAi5)FN5$kC6{wy%yvRsk)q%Fh1HeK{%&VJ$^-cBK)8_gJ z)m#OjxGs@w6@~dusB5~5{~H1(XJN)#G5tg(;(=RWks-)Q1DiBKTSrh(Njy`*dhR{= zm`vOCx4?KlsIOVtDmF?cfx3H`&qbHl=t-c<5^&`>`1S>uGy|qhn5FYW)Io))(?u{x zU$dR|LEY7we;&lVDs#|NaB~NEucx`|7;9)q$RV&_&mB8b^C{3r9tN*<)RTWzu$qF4DX;MxvokD z<5dbOlmg4N(k=q zqn)SgvtBxFTeNU<1I!oqK>Y`pgH++FsWy#M*1F4UUlhg9R-wAB0M2@NyIG)$wt7Xo zJoa1|1G)w=_?67I8nXBeSgs0JN}KMY2%DlnS}(th3j~MnfiBA07JBRJ*9#xCb45+L zPKTW;%@S)i2T<)5$e78H@l8-oSA&GUV2Fz9KNaNJs=$%e z!3mW<55?75eW|j%3aWPkZEcT$rR~9G#i`|85Urp&FcDnQ_A8g8_slia^PXVkG_dD1 zZP!$CPZ)zcJ3*ugZTHrp+W3Nh3wY48d9-a;=3R0_#S8$&9${K&)9cQm27CptbjXc$ zv?Jxoe!<{}!ttrnZ)X`WOSN;Ag7BW6n{WdBYKWQm1J!aFXr=7QKMxjXfMQwn<|Uyr zjZvPCD6ga7mKA1=>8MVMlDGuaJe}pnhG3^5a0vz16e=DAQDyZ94Lh{U-2=c5h3IQ# zW6i$cM>OVldAIW-%%yw5d(HQLGN@Jq^z;GESAr2byczl})sZud^Q#0b6jJVQ!E|}o zQZpCOS#DSihA9#oC@}BpK5A7P72Oim<07i^IF>e7Rp7}!U}_H9=;0>%{r^FQ#qr+^ zHdJoSRPAh99MydYYI8-F(PR@UT@H&@AbmT8*h5s+u84^#GK6>=2k_4a|KReB+z~ zZX;%*BF8)c%sc{a@1(b}HW+Xc?ADp5nxH(wP;2yR_4qO7-z}(rT8o>?;f*=8Rf$EN z(i!zt?8YwuDH}jZ1>u>Y^sd*^s*DHrqd+C?WBgz6ZZp00?xLCrITJAbY*2-Df~MNr zz=h!TC^~xRcB$`z`Sc;k)Ku%!z+e@@1jUeR6w0nSxY-@^N_kK>1Uy!f*pC6mZSjGx z0_jp8%<*qf3*Ujer7#VYRuvQ~e%eBX7+@F%%r$P8Hq%oz=aa6s(JBvR6;kCCL;DBO z_EOh-%L0r$dkb~T5!G%Usz42ti=4erU&Gu}#q`&?)l+>rrp-*z$$ZsTSL=}nbrg;^ zn5T7y*K7f`u1=CR&jiYum}T=M4^ z>a8kV+xnPmMuJXS-vk|Z$}n(sKfRYagD%-%Ru9^atpM};V|ppfdd;gUy!hH3M zZ7tO^JU`MF)&q660V-Ij`&r9aa}{+-C9Ssu*e;)TZ;bLUh6+W$g1Yh-2 zuX#J~$W#iNGQ0=2Y-XWsNaS&fR*(O&NZtaaJ^Q=Fb2 z4%~D+YkWY%oghlN|Lq#6bsW^t>(=q9sH1ADpk(S-jJCHqsJIl690FG8KnLW4th2yC zPy3+6nWTfCSQ?mWzmW>%b$S;to(l|=5ZA7to+|DS=+>BY8?~qjs<}KqU>2%_QmCCj zs>@~6+u|tmR;ZDRm(aPO>_2c&xpmV5q`t-*7Xle~&H(jC?@fo46>Tz6l@)c_Rp=OP ziz+@H>`*#)(;d*F5SX}{!8SV8zHLE4Wk47CV6a~J!moi*R+z>eL7>9ou+sk4GjMPj zW|v{8eG0;?E-3HjD0ev`V;p836`6wn{r{V|Acfwt^N3AgwF2l+;v7 zx{(@h1XY!-12vzCGA_72YJV2WTpj%sF?DZZ);@*${6e4je<&#*@74kJ6>Sc;KyZ16 zl+iOLDO}HN2G&aLe>&Hh$zb0nnY+PBJ?)6@l7T7^k&&pL+QJGQUmyMd8Cnd$Jf`2U zzbk>-mIvzV2iR-+tlp^zFdjwdNN?SAi%Byby%x()Y)8yDh{nS~n1|J(g4Q1m4`YY$7wGU@oI{GVi zx*B1+m;*=M@5ozkGQOHtzrlO6a`J45^@#zO27l z@l$Vgo$A3pAW6yAyc4QILlCbN+k22Ua}^TjNnqkrQ1k^@q&#!e7HpKziK;|<6iuIX zgX~d9xnEL$P|c!H-S(l9K7w`$m^XD4#;S_W^67%AIOmC8KTF7y8A?hgRhT?^!_Wv6 zbH@zVEH?&V{%HrMngRp;%y%vWRizKGZov?5J-5#m;BuR`xyps`*5I5cJ8z_`{-Vml z?*8CWHdwA3bFZ8oHyC8OfdbWNTN;E4)&zNFP)CM?VlOd!#DPd-%nWmorih3g4}N5V z|3biZZE*7~P*Tx(W&$u-1Quz7`7&J<&%I`YUrsD7X${KSi{99~nBSG>HHB>(Kndk# zuEJ-W4yu|8c8}k{P49Rs4)d|eA3)I&nEOIeJv-8S+6m=52308#bk*t$SEOx%qBD6b zW*HmMM8V(S7;0~Qu;vE15lh>{98`rHC~pPL#cg0^In0()M-|kMG}UDfa7gRBppKqS zpt8=qmcqhYz2kLI(^ScusLe_XI^~ISRyzNB0A|O66&q;F)Lk-k8>*I<)IyZ8{Opj3 z>hc*C)CN_pBdC88(=Z8DwG#MY1yc9Ymh&7`I}M_H0M9{S+j8JD7+kyu`fK~%I2h1CfSbJzn9CcpR-#V1pyoY9nfwJ^ z6wmWJ)7HZdWqcMGt-|zZ2>g%oppEIkKr78k0^js<(0U0d)|Me&KB$k{Or{bn*&8(1 znk^MHL5CPJ+W=HmIKGpIj+CKexc(LWhbPSZr97BkosLl(Q6qHl)m5%f-bWej2b~&Y zh95>{n4#wAjbqnQkgBROsV{9qwxd?IXM%ZAC=*M4LiM1Iiur&9)MmM)t`a+71t=jO zcq;Ally6TvfLIljzKS8&i>Rq9nXhRr)N%E0v_j1lTl) z*V49W`<2Io;^#4cF97B$rKNQ63yy$(zL>4076+k5tNyi1M19OhomMbd)c0t=EY`k3fi?R>l!D(D@E24BS70ih-c9_Ip(w+f^Q>YYP^&Fz1g&y;gYFYlE7q zSBSN8?CI;6Tb0BuYJfBwuug@{A)k&Gp2R_oBdBZEV2O5A+=1SQi&5Riq84lCzf4em z+G-0A@L6XWm5q830S4T_{8SS4_W`J`qrIZ7ny7kz(JUrIFv}D|`RZ2++qPjYjKK6! z=`+`6t|{b8s}5BZrfWxIrhOPi;11Ru=D9_W(J@`GJ)c#iZ$|;&G_ds&ZBL3K-K(@wof|M5`!@7 z8Gu_#we|W-8aw4yOFcYQ*?1@n6wd&6RUYbYr=v$*)S}Jc*eBpo9DF`chmU$2>(#&N zJ8(<&VEb`U!Uw$6;aOe*#pR(@ijoYqJ=7MS%Ip&c_9#R9YycIs=AnB~K~3qn=M9nz zg7vFt%htby{x_HMyPRaL~b5Or+P;G~U&AvP`a5il}nu8}B zX=|^nc%-awR$9#u#SB%&yj=%#WGbr02~^EU3fmAC;Wzo$>QB6(~EURY($O|DBFC`ljKXHhoxmZvO)F zin6h{T(>2Ww(VL~&@Rjkx-TuxWA1E&@*M)k+JTE-XbY83zp2pv+KAexwui3ZNH1_% z(?{u-Ru&4gNfuzmKg>mKP?^&Cr}?g1208lSZCCv z0l-CV-7nLY{1#;D9b{Y$+I%)K{YlmA|C(Zs)}}Yl!mK$R99Kr=xiF-CKh#a_$b1c| zgCj6H0K#{I7lsV!T>wPt)gW;R_<0DpPocNGHTZiFRMvqeDRs+fgT{)3IR!vn{c)wC z3cy$SzJ{{G;0!AF7g(x84z{Ij$TXSn85fj=`O6Y`*wL1+ux+heD8CF0eL}}Um5jFv z+u7D&f|j=F{~l6;jn~5;ePc+xoLE938o3vBd@ibt{_%jJ)O{V#3`aUby-~e2{UB}n z)=ltKv34&OWayB~DhRud0gk$1tF8od^oh-XP_ExmD;4*Hf-y_ze0>$2*`Am+LeKK--D{9m+&{wg$R4Ei<3yk&1 zcm>1QVvKWBmf8M)N5@fXby~kK(GhHk>NE@#GGY4$RcYI+WKTOyn`1Xrf^PBRshCGK zedH%#SAn(yH^ChpkFPc}S-rL$K`~Q0%B=yn^~i(-@O%Qetu0J6N2Of@^R&pbHEG+@ zkRLOw_wN)RiqKm!G(5Um=fY|pxX3`y;uG- z(!T??*@tS`1H8%rpH?$uv5#LF`IykB_1+RT;0<+pNdT1 zLWO6S>T|aKCT09%%!SIM!g1h$Trypka9S>APle-GEiJGksHem0s*E2d$G%k5?bLg0 z4P|4=FSIpMtQCm?|MG#qrr#O`EP8?!hK#ek3zo^9cS+{H=R~LT{iKWV1>^2ofBB>%@zh$Lrs*Mrcs*t-!%juX1Jx&{oYw{Q^CAo6tK|; zYqv%Hr%ep04?;7TVu6yHt0jg6B_}d6)`uy1aJI3Eb6=_UbYUSO+$!617s4+a5w?WulHN*;Z^p zRaN~-k?Sn=s@ZK3>a{BGMK^H36|;njRVQ5@%?-h=#lW}@ZO?Q7tF?~-)}WRAH+LP_ zpkI8Cn1cFKm?5pwSY+IJnU6pdtu*%*@Kk-QqMZMB5>%3h_A0U`>&>|04E5^1KhY2v zkQ}a2`YyH0c7|M>iJI^ptkHYM#T&HUHUTw?f=@2M>@gjeW};T;66|5jGCt`%iv0u& zB0*P`ij^v`TU87SJwat{0_#=T4346{I{+`8>JaVnRu0&xRBPWFJTwL6VrknOfpXUE zvs{tWSfRYN8jqa0p0Zet-!RO?;izT@fK?73GgBysC zFWcJSQ_rh(%xXbLyz;2OviAKh5S0%ub)=(2FVM&r({2Q+*HqA36KvIyJy#AM=m!cK zU>40p*&abvkpIlInXzL~2}?jXx&5LWDs~mfR_NvGx!ZLyPEo{GeF9#pW)A)cHuPjj zf)~oa1M2H&*1RtoRU(zP7J*>vd{Fy1`uccb>}4Pi9?EqP zDxxpy$2Zh-Csx|~0%o&LpovnW?H(SvWGuaDJwenT+J+Ycmy3es3Wn7=sI8j*YE#t3 z2vh@2x~Lbbd3)3l#i^0PY>-Z&ntXLlm0`p|+FVrXk2eNC6+Y8UR z7_20otMFN;bQ!47ix|lI!pCF2RYsM!2gxd%bv5LTJL;fnyNS+x><5scQ2i>u-Z5InbDgD; zLST4z;M526lor0$kxwM3sw@=7D1Rq7fYuYi^r4`D4IS2Hz=+nEL8rmPnjonom_443 zrSiSOBFrJ5K(3Ori;nS*PTzYe*r_V@O>SD<8<@@o&EA1(4?$6V?2B}W&XADDn48Z6(}kdr9@)bZq}6AL-xgE}&GKOi z*i=Uy7eNyhqpT?K$Cgtj_^JAWxGJi1|~DUe1y1f}$L(Oh1u6b>8}od*>MpS70d zTj_Pbhnlb#L{G-7qmvn{)ZN>FHe++}Uo}i)L)0eajF~PkXQfrqXxc(TP}4i3%4l1; za(k@uZTM5#d^G8uPN;f{?0v^UDJ>&^0a&c?eyU5U)LAfNHEkIqz!n|%d>wrHFVtB_ za4!QqRY}{WVqS4Ruq+Ph)CDK>ax(D)c57PG6sG#Gd*e6p@Ei_-&4qi>j9LQ!6)P{#*?%?E(xblQw{9rv1ma*<=V4WOf? zPW8|kFzhMjq)MP~GoJ-z76+P%}I9v$-C$n{t5)@L0e~o4f;f=?!ob!P#aEyoWYnz z`WB^K)x84CSBv@^N?N~R;uvq*SVEU1Cyh{Y#qhxxgb&{_s|a1^35m*J;=Q+YH4$3>G=wD zT2I@Tbs$r#N|7Um{{$bZg53)FV@l`vgQ!?@J`tmGb7&%P`UpJc(EGX)s-PmV-b{vM zD||YAq9apZ16EMosHiAT(LR>n1kLV)413zHR$xd}UCgmHQRNglFI5?WAJZ14pXr+) zL*40*`m23}zXiv2P+q4|qaLChw9@4|w`SvLvok_f*7Tmd&88fkMFL zDQfaOmOh~3}q^dy6F<^rOra^7+Zy6}3s&_FEwd4ru(;CoUzpWgl zh^VCXwNq~+y)L{v3d)3n%8eM3EO+L81>@y|6kQI}l~xTESGN_S{mO%V+v!M9&cvyD z=QIWv`e5Ggi0b$NM5ux^)x~n)GU~+&V37#+4+Z~bfpIDYeaskga~Fs<01e84&;-!7 z5jf)s-kLJ5fpX@u%Av;u)HoG=w^88uUY^!^G0LeS9Tl{eC}&L1Bj8jFsFw>O_k&>-$n2 z0h%BlbwIle(4m}tLYuLE5~(>Kb7Uv*#TYcJLEF@h;EhUY$BL-I^}wkjpr-DRV$)GC zHEF#!m=jb*PiighOTpvGz+4yZ!$sif8^%Q$gB)$OqYuc*2V0x5)rtL41Lef<^Wbq) z#(h_A*()$x4FJ#e?al34C~K9LT8g2U-NAdETdq$3rV8GSPvC@3>s%#1u|=+%t#^w` z@~)E>-p>|f%CU#5Gj5^MV4o9%(^OA4D;wil?hw_l>8<{Xf49rTzAK9&O}Cz;tYm?4E#=0=5sG2XyfDY@t^Dp-Hi@>g~8pZqsZ zN!MLLI7g+~_!uzPfo@V>`e=hs+hNZ5iwdwp9kvDUL%`XIv{^g{XZJD7W)=9J3Ysm7 zjjH-8=V=yddl0yy33gcXu_CHrTXKM9U(8UI$p6}aT5@(N#p%o!pk)mvaGj2Npi_Nz z1|({henq^nvVrm!;GJgx*CTX-53 z5j59rwR{0+Gy<3^q{^M3trIwiU1A4pKdM zEx$P1{r{V|zIsZweook(4^}DJ+|xj7-L~7up-w4ScHaT-Phlo*M`i1P9_vS^qB}6F zZv{O(z{#(4v{50hIUWoihS_c=IR1;lOQ)c=B+(J1kefCawW>Voly;ZD0kdNPV65nH z)3#e&0Tq(@Y=G{%4G&SHPoo}HV#p9V{({c+*ilfXA(*<4wnRfzzI^1MU)fC6g}fsH zywHn<+egsvHfG8~uvDJ$mE%7uNXzy`tyMy2w+B@<&S^QSmcqJIC(N=AD8nn@cwNk0 za`*B{JZOXlzj+7xR+icfoZUfh-9w2H;6fs3Bo~)`0IU>uAy0svUMIflaO(^LnYzcD zs;JcvRx5-ptATC1zz}8E&WET+a#-aMR26HmTANumf;I;6BOR_5SE586)X3QF<- zKlSiaDxtgQfq$Cx>myLsl8S9>bZh1PEV_<)5`k`w(X&9t*!^Bny4UM$h+jVaVo?kw*yz* zwh!dk0&$>_8;I)uf=>Brr_1t9L(eX%aYut~V40wBpwreLqXPy2aXWCMx$inii4Kxz&d-(l&7c;dZfP>s-xU=;RNbJ zD(c5+RB6rEL@!rk^FZ80ux~JJ9|oX~$_KH&pvGD7S8ken0adFoYLsr^HuAWct}o~D zV7AV3L0444TVU7}%)Etcre#4ebPH|k9e}kaSgA#h(`H_u0WorR?O0%?NyjFG09Ap# zx^i=#p#pVFxhZn4mO^FNFzK>7sHZaPsY1U!O|PvfxT7-X{z2u|<3{6j~!9^|hVM|+i#`(02C6eY2p`6>IM z_Et@Kv?ZPn4;_@5!fZ$z&`;U(?lGvR3fEV++VWITz!CG}UX;DY%_L?v%tt%&GE_r>fq}(x6@_ZH0XqGWith zqhj)uJQS%L)niDs_AI0qgr=I?SfG zxuSU1Fxm#GUOm%)ji7>J_Fm;;po2KJ~eik$H-sOQJP6kRdhl2P-ug<>~Q zRpgi5^3ZhcZRa%9wVh00t(s`7!1Sv{5Khnv?w+IVo?@+84C?wTR4aE7xB<+QC*u`_ zCUVKBfnak@+8Q)O4VN;HL3xLP`Ykc*D5RnsFzc$M%~dFm{|#y@d!{Kvqx9d(SQ?M| zZwf=!Eg(xv@<-BfS6T7mE(p;J>D98p zKZ@Rl^7!@Z;QK|8R*jA(+U2^gz*fiDN5#lWj)-^%e!d32dW|ZjUC#AG?baiU>S!lw zQh$xBr&T4D1Pw+2A6-fj4?(~=dY_j9;}jA9#-Z-20Nl_7!Glo++ko?mzYE@AjXd5h z5Y$)o$<`yAsJwd;Y;qitoSqHgU3d-i}f&1qY( z6g5rB`RfIEpa)s32PO)dy7sgc)THCJjL^5BmHv%-zK(3M0yw1}LptghH<)4i{{*cy zi{*6M#>g8f+E%_Hri*^ixN#ZfxP!J>MfM$)mR*71MLkSMWlxi*sHMYEF7jl!A1eJi zSgbPVt`z^O9W7Roxvp_TbYulp4(sm%gV%vQn$)-|k6ix-HO&#&XbT(0fJ_U_61vs0 zc4JzoTG&;_9H~juTe8b4A8FgIqEPz;Dp(;uS_@x33Y_T+%IPBArMH_7I>ACon7#8* zv*pv3`IyVIK}h-)yggFbZ~YMh}5=T z={(NQ08e!&F%?0p_Vf-Z#`fbfFxzVSOPcxM89J70xw|%i#nUiNC!-C;Jc))wl>LxIB>;<6Ftz8yH;1mlJQt4~bdUrA@By?xc) z?N&?bJDBeVx*TH2*$~uf9kRzl5TMW2T11Cg1jHxV=Mm~aDpHv(g{`s3T_ zwN(+U*o3u&d!igy()LAB5~=f8_8(@hqUoWsvBWvhPnq|-6`!be53{La@`t8xyp=Xv zz5C2nL@X%`Cdtn^W$5^#Q%y<43{+)!s_DbD!AR}xroM}*+lP+2iuMhIz}nZC@z+tV z_Mo+D;-jr#k1ZIca~rQ*xOEsLgn>vsw~c0584EmnFr=kiJXM$LRju?=FEHaIW-(QP zRg-z{wh5?!sdVg7x?EEkZvP&*cEW5i9hfK%mK>$6if#yRJ;U_>TgauOd{JOgfVRt8 z{Sd`pvoEMkst5OrVLmeg1NBll?FenYIlx?R>*pPquT5jjdS00Q<5BHoCU}6G!C+)L zVsg}0)Hhd#g#G{PsoAK#LA3q5gc{Zn-1rXe9H6a3CDcllAP=2t{65qX#b3F4JT1x^ zGc*Q#>;YQ2(9tgj%r6T{%ZUMdP`^}+ZaaX;t6=vMaKIZF%>xUTf!}MuwZp(H54b6# z8tw<_4S3K$Ws0@jSxlbv=m&higS{Pr_dReyE?H9n7`5jU3+1)y+QNM;+)MroQ7G5f zGd_Jm_0z`!^`K{}5ntrQD4jyyZBVKlv#ffAvQgnq4@ISKKz*u;Dy}=~R8e&-MJ1># zomWtgQXq9w9vzmSZ;Zs;cmdTYA8c#H0pygSExtbHn%+EPNNdb$`WoM3JgVSZu+@uR z8%@<|>B1R>%COL$NhSHIQF=>fBONF!zl?bx=q>xd=9=0Ox%mZ3VsS z^>yaH{+MODVY=-GEfrFAf>6CwM%L>Y7fnH?V)AJm@Rv^)Gyo0L8CR+^>Z`7p@p@fY zq?)sE00?ad-syJ()$1`NjR@m!;&OFfW#s^qnIL!;c%UC)d@rF|l>lQk&lDe&i5aSh z-chc~6^*s@CECuk9)ey)Y%@`RTB7PJ=Xl9UTu!6xAr&iV;F5V1yL4h ztgBmLV5>Zvs!L&$R&Y!2jA^N0vw)vs*Rx)-)WobPa6-br}71ArD^&o;RiA zt=4Sqj%lrA`>TX0zYf*E1{nDRJSYwB>3HJ$0-rE&s|GViuScEK;HnDEF|#oDyhfR} z1@-b6GF7+y!Lyjwin|wKv^l;*<*M}DdWCYdM@>@+xG)~`Y%O4^hgZ}FpEm;TFF_Hl zB|?8h`bcr`wj8E;7O1Ho%A9tg+*Mq*>df7X@}QYINf)T>)e*i#$0p-OgaJjF9EldYE7S`?#K~kl$0??`Gm10W|B(n zHoY0oxDVc6q$64T?WM>*qSwU@qft%0P-PE*^`*gpR=`>JOTc@2PwAI6n2I(w=lruSs zjojhj)qT+NJ+p-9j;-+rv-v>~t{VJkGpf8+V6z;AsK~7F0{vcrJ9@@W{csub0hJ|( z*}L$uHcBfe9a+o(l$kfGpVs1~4fa-m%*(;-u7^Kc3NFbJ15crjDCv64L3Ppw`)&n` z^=4&XH$WT9Q)x8_^7Ww%G#hB>pQR6%I@U#!2LOBFIVf(bf6#d}b zUB4g?Xofk^k*T_l!Au&5x;%ik{lTcC%HPE+!N)To^tDtV$#$;(3scy>e4$h3IE{kY1U#yE>>7irpxs(3Xj)$vVr6buo7sp%SVvu2>){ zQIqa`21>`#_Fc|da0AR6&fpt*QHcx(cNBG&qd~JZm;rrJ?dPL{lwhS7qFR0jQ@Udw z7ziE~0IOTD(w6_|s9PNKy9!weEvQEW%r<(l2+;Y~*WcNHRdTjJ4hnvvEy)};SKB|g z7c;{LRBQ((>P;d+xv<(8btnimTp^mm#qFAU5OjD2`sf5N9c1Q|O{h*kL3ka^$9iJyntHSE25VL^bIF{*%|*bppXd8P`EuXrVYLq?2yDl(t=dAm#}8 ztDltpl*EViHnRUZs-P1Xa~ac68_fCtK`A229K~#+2ene~^TJ?yG-kHEW};|nItbHo z2K%DND0f9*mATxPm9QGD)p00}xEONHE$dh~yG2b<-EbBe6LLr}Z4)&YvAi;9j{ zTTm^hqfRUBQvARfxwc0I+U}PF9Xo=4J|Is1?cM|&R#97_Z1}Gz*rM0_)MLQ3KA)Xh z4K-Tlzg>A|q*vhL6X-aqH)rbyD2EM9V5GtxrMhx!A{{X|PzSG}B2`waD{HnXIm`xQ z8mjnN=?$SsS=!1T0_(NNv2DQJwV2D~)&0tvRDJfY4y~p>)?*23gxs`vCb&HqbT|vV z66N&kcTtIu}oirH9Ub2J*9(6uyGWhPIF&`m$Ew9TX=M=7>o zE^V#_QMWdLqh~Nn3m$snr0?Z`2(O%A*p@L+tu&G=MOkG6V4f*_;;@nvN7$N6vkm-|# z`gtB@G?)bq&@#+ds!iE4b{A-=9o4=LBJ?w;ot)hK4rT?tf;2M(&d#)bbwb@r1Xn*} zmTn1VXy;*y?V>6ITYG}Dy8NDaXozmvI(oR*VnMadE|QMkZ7Gu{^q{=H;HjQ*OJ7{v z*WI6V2o<4H_c0&Sd_AhcY1;BPV7^%lPHN$CBk3@>gt}%6%v9TQRXVe@DsvSxcRTP< z&nT>K5L?Bg#wuU0s4`ct4l-LXc)vBOwmg}qGG62jW{6HVZpER{fz*}wKMo~9X$@FUv7~smxjYiVpnTmNqZzRwAfhF>NfE{hMy@W5oNd@+TCYYz& z$wp7RS_~Dhz^tm3mNW%xx-jVvMdFyDpy5W$^(vgniJ+s@BVAF^s^5Q|F}<>YiTo0* zA;#~(umH^GE~qC@!C{rWygtCNC^&Bh4$r0|;w$L8fM>MQDLDFKj+=l=8in#x4w@^> zF4v~5kt$LHQ`F#jC}+)lzXE2Z3aAxssN=nvs+P*bfUdL^Q316(1Kj1rdJXBQy#-wS zi}`ddYOf|JKL;}-43%*TwO1Q-6UHdZB9uMdwX~OdsX8GwSfSUx4_Kw=Cab<=?*jD{ zwkEAmL*JsFenj=vj_&mYzZ8Ta+QLJvzLf%Q{a)a?3M^1a`F8;Cdo$!?DC)cdvsD!M zlm))uqOHO~@WL2$yaZ-62Yp_G@+yb3RHcHnzEFJ;=a7J!ItEnN4OhPe>eG8vLSqo$ z7d#pO5_Kr?x4^=ie603*#+7UYB3IG&btowAglX^)Y}f=oYlFTDpJzkpEgXyLt-Z}u z96UY>F75%P1AtK#Ixg!U=tioJS6c|q=F(hgGKQD+m zYYD2T61Jz-d|Lq$@d%XE)n>SZw!4brBzx4+DX7NgsIt3J#XF&n%moKj3RWed7ODt( zwga_v3Qu&utQ``Sm|Ah2KIvs9(;_IO}?fR*N?($QQ8HSHQ0rTgA> z5WNGU!5yvHAQR=NXUuMoGEqgEr-$3Al&1dx1N_0HwxG4@MmsHhvO?b88FW1dJeq;) z3f4VEWRB-S_dhfE=6uXmmrS0Q!JcZ_M<;t)i26xe|w|yL{n|@k(uRF(e zB}ga-8p#JsH1m^uut3SXojADpbJ|pdX$q z$>T%xHLZhU$4XlmIRJE4EZ$VwJ+lU%Ldupm z^}+Ia;FKP}XEPmDCZSsB9o69vX8-D_52b*omYMGfzE8&-c^t&81v&k}IURkVW*(sA z`KDZYF$tVh3T7yW|K0&DjA%Q*6yzxNe;o@u(}P6rFIj{g}f8QH~G5b?xqe zJTp;?{HJd%%F0`B+k#$-Pt)zF6?5tM;|Kg}(bn6Fwg;+}EmTv3deGtV|LtothZSB$ z-=mHxG|hD2vzGyXGZ1-=k1aQ1$VEd`F=bNCN?@xpr13dAHtOM73jehu_(a@5)S`IQ zm1$s7dCU%SY#rU{qo&hV>I=xI3}OZ`K^=Yfd+Q9n16I;@Ov(G|1n?>i>|%t$VD~$E z$0~^|UV=eWY5T6CTw4`r_6{)Y4Ja+=Z2S$r>E+r=PkSoYm1zP3*Mm6|!4;j>pH-+N zLsZ4tD34TBjgqL&S6NlBi?13tyH1|qcMzP8`CtV2srQ60)7wP#V&*s6 z>gr=3hl2Xb^n9(LqC42303NsxJkvhP>V+{~Cv!qU>!JK)KLMUznXZ zjry|-Y?AxT(GL!8Rz;=Vpw>WN%RC9f+_DAqc?C8*(!^J;=eHc>oCBAq(C(?$%Iq3w z*_|en^C;`0>HE8YHVRnNj?{M1+&y(w!e`d@{$9WOW?Pxw_)|*ggu7C@g)>#E{!3|U#Ysb)1l*OWt zV5ZLmb^I|aC{xyyOBHxQ+0lNeKhIJ7mVt!|jT|)|t3f{2JRT&`RkU_>R~%&r$D{7u z1SVSS3)(zGIpz+n)plJi77j)I(@Ks~GTNi_>YSXvlPXMga~Y=iICB{Fv>2+S8LHVQ z;HzD2qEltOBM2)`?GSlgC#}_Sz37t07d(~PSQnNgzz5S_&$dyjdOV26OZriELkWB8 z0+1B}&THoLH2TAinD2Eqm6V^_3<3MKgTG`>K1v5qSD}W=55hgb7QSto>MPS#;b+wi zOuPWbZ2;d@wqL$`tTXLeyP*czQ&vwu{5&NuJ||BsqXX}#JF0<#{go!u-ySp{foVS% z<#P*FdK#+WQq*p_cg{($p)98L3@VnWzsfC9F;zgIJSVO*Wo6_R-3MSU(pWx!!0e$h z_fV!WKZe@Z7o-%Vzuv!474&=gr1#V|>k0<`rtF+v{&pS8^PDPnpmzDAOuwN%Xl~K+ zx&`vJLUJjWL!fOGC^DG+sP2VYr12fmHYPp*@ntc;I8pm>D(dG%-g{d;S8a;87h8ps(UHIJqawCiIB9@vA9GKY=<;Zjv~h!oTg9@pi5=@QiX zXv(e@0=M%p=W5FaD(Rn20-qG!K}lfFC1Bo#$6|G(JfUD(dlC$iyrkglf2wvV+>07u{5wN=1D+a6MfEE(L%v#bq5$ zYrpc^Ywd3hdBm&Zm|qH@9(#h1ahMUxO>PTO&*jC-m741tQkL``RjMy#+m)N5)~ZPn zD&{EjPxu7Pwo!IP!wt~10&FRZ?u#1Q8g*A|u<9}DYiW9UCXevbRAaUKQTH%Y_Ji78 z!4ri`v;XH*9yAWln?D^KjN#8XfCV6X>B zKF)AEE1}ep%MWP|erx*ax>TlUu^%dzWb8s2E6wG;z#ObxJXlVX8USu;ESV=jMUAih zLr`2!v&j-%)wG^3e__x^QLXDCNm*>gtm^{Z|HjtxDO% zdZ=vuC1aJ`d+r0w^c}$21+%dNVxyL>n0#`W!mp+d@Wg$XX4>u?OU#n;rddi9^_8!R z=A%LtAFE4&zmeenPs$zy0^7Tog%o~K4m7^p6mx<#_^iF06$;Mur#7`0xY!f3y54r9 z5}2eZ4AaiM(w^_X3MP0{)=;sKau&0;qOtciRAtS`UH`YZs`@XPx7HFjQf=mWD$MkK zKtC;A%p9BWr1qRH<^k0n%98J4a`AhZx!2S+Y?8~HVZxm{N2@tQ?H@r;k8TtJfZT#*b zVCZrx{y2gwQ@~Iq{l0s^KTkTyECn(Y*w4a2md>}PrBO?)P)n4b#~Y*aub{r2r*WJ2 zs0RAkg!fp~ZSB@bjWksw9pHls*@eok2qF}h<8+=+iv@+;K<5z9`!QImpt~?lUHwLN z(Ay^KYo9f9F$WI=9{NVFQ~@e}9mE{!jQM5*s#gb4ME4xCb10{oV7xE*mJX(r09lcs zvITHc&!2Um#e4#Vwc?wU1&nMlhjc+X9RXeIVV=_XK81nd3dHXdsTfh8_wH7>?0b*O zQPw-9ELGDTShm1i`wvxq0tl*z*?bK!+k_daToR(}^FS%`z&T7i6EI~b=9O0TH%}Y- zcQIz6j+jGrDcWm-A;o@ZIs(|RHMICd{P*=XtBpAR{QIUow$v%ze_;l2bgVj z{<>_$%+OUWP@{i!8YI`HVp|1N1-b2ZCHTGrQ9p+QOHKcp9Qe=-R5vA$+j{Kmmj8bZ zS4XF9rW~#I3g9Alb=11W90p^j0AFp@DJ6}MI;A$*f+yOR4Z}fzJ*edeVij0bm49;O z?@x7Jz12e5FQe?MUerh9>Z5C=Stu1fj(}pzKy8iScN}o&Miaw4R7gCklD1`#I>^!7 zA1PG?KL#HsVOG_?cDe`bdQp~;g<3s>?yq0QytEoMs5)hB6jL+2P%Gs{wLLIvw$u}& zL3|8l0h+?sKfp8xWGjc{1*5#D(90dY14t zpwdQxb{8=xb|n+Fut#}hP-gfP4ADsc-Ugd=++13X+Uo)`HPSkApbRbhl%^=J7N{FC z$2|iTpM#qUF@O18MWu?K5twIpf~iViQyox8_5#mS;J4o9;|q**0h#OzoE$)c*0iVG zIz)}1YH_A1ZM_)Is0KbmxyMtsMN6_++4E{LYV0rICC}P?iL%)HsAFSL{yO2dH{;oU znx&6ow9ZlRSaW+V%!;60IgMqdQg^;~f4m)-u2-gYM1{+TCT4@HJHRH5potEJ{xv|R zMlh`ejk6YFR*_HsmUA_lM#U;+gp3BPxL-NST(4rb(%mC(9|&y&j+CeD#U|9kL12}p z|8EayS%6MWwMU2FfY}?s{^K<1r%@GBw0bCqgfBpu^Z@a4+a4!@(@V9}S8DzW1B>pM z-L>rb>aU<9Snv|O*6165qtynT5H6*Iqsk-KH?04BZFSbv%Opbxc03@~SSQ}O5w%3Ax; zYAhI})qSW62ZhV(eju?ESbG=PEv8~pJ(R&ARID2qrp!CI6lJj*_|u1|xL}l-(%V`S zFtiF~6Y8Umsh7~@pm}+QQRzKp$F*v^E`o-$sd%7OTiBG^YI2p0N^bMjK}Ig>VOj9$ z59T^+R4oNbMIDD`TFH?S;LAUrEp!UCNK;4%LOpLnS%NM!Yxjf7@{+dN(4z|CO4{=p znz@S_ulNp5E0Hy?z+*8>P~Vk^dvpc^=3ySoqoV5uOz$|%?Q-Q1rJF=`I_@hdDhKIu z1$0!;DfuAqF8C)u9iV4tD3Q(Av=;sZ!;}dZ_5nqdG7@!>|1le7t|#^^QWIxXSzSfE z`vUt@m>1`v)`xbkELHCT&-Ty(KS>_}quZg( zU(mRtb}+m&!QMpc5~-uZ=RB(LWYinwrWGptdylfCEkFuQB5hRL5djRqxtfYVB^e{}Yglb^;FLxo48 zOf|uyU%=}%z+NA3n`o->Uulx8PBX@X$$G-V9=z0ya??Sx0+_ormNM$#R~Tlo!!nb> z8eK3dexPi=IanD0iYtxeD<7EGrS|7I5Ts!gQzTc`^<$Mju6P=Qyt|b7=;*zsCAp`h z|Gf?spOr-$EW|uD1LyK@gPNirn8Zac{<2nX?&{ttBdU8JN0)iW^#p(F!YrD9Y?6p|pv(whdkfqO1YX;yo!bS})_xq93yf4akJNddrN<_81!mL0PHn|wz0yO|%G->} za6;|djAJ%$oy%A@_@R>3`1E|R?Gm*nLs0G!s24L)<8o1Z`=c_o`?Zu4H_CKaqOJ;~*5-k$ ziabmG5O=6ldu7{eK~%hy-+#IeE@yz!`Y-wJn?h~CH?TDTJk^Ze?xgmBJ<4`FaM8v) z=7S4I!A<#9tLikly9za763DHEIZ~4zpv=0yDtM#={DQu;9dZ@*>o&EK1|Ui2ucch7 z>nzZ%8Caq}$&776#U}Z4VL3xxof?lvQoGe8-*cCg!7kT9LHLyCnqa?J1#n13{?N^`)6i{Q9ct&KmA{g4mE z$(!2f{?gq9RjoXTegPJ=rtGjj3>=c9KmUI_^>U~lczlbp%lb&Z^9ibjrjXG9^MNNS zPbtGx$@2JRaCZl0aA%Mycl@9nTeK35JLh2b(&3fW0yF3TQ&8gxslcrbSdtA|%Yow$ zgV~wjp)PV`l`UTP1*dM(r0G$Vr_w{LGbnX}vi_RKLB(phS(vL@V>+%wEqnm7)V*gz z$`(9CUDDy|Y6O1yg2~#7>pG%8%I_-|$83BJ<*mHyIT&?N5&E|x=%DzRDPJ4b7@XI_ z8p^Ls@<5Y5z~U5`qXcD@j_RXWXe3`V)A?c76;;z8m8)Cs3Ln(_iQuWyNKc*OvmH^( zTImUY;G6`$>T8%PI_`|reWkL%e=#s!&J#^^Nw{YZY&F#{Yr!!MsI7M4jrQogw!5Wj z^Gbt_=fOdph+D=9m8p$h0Xojp6E7)C_u*}mCSdL!in&IP-a-edb6YUnj57CMs2~dv zrWegJ16I1eW$9$Mu7EOD?B9NYIp{R1uQu=f7|j35pjt+tQuLp>=y3saQZdwZd2!Rt zR21He^6bqpE-2`NH8gK^P%#F$Jp%i+WfP}?kJ|GaW;CwS8MRA+eN??Pn66dRHvZ8y zue8c4D3VVP2NMs`?m#fAkItTV3dz_&RHPDspE8J{wr8;q<|Qq0p!VqZ2|C?qg6SLt z9?5qT_3yBAY^W`@7_8L34LuHe$(-K^HD58~t2@Y~!@ygAC@QN^i&0b*kiX4mWuAVTEwrK`59%Ea+YAc9$RlkS&pKjmoIA22$Xw!5LFg)k3wUS1=#fsj2KGU z;GHPfAE*?KukCl>sT1t2mgLh0%p|3ZH##u-d<8T0-n3&NI~KJ5&A_`VK2nrpSGNN% z^$Do*SkU?tu*e2A(rHppXH@0-?8hZ}SOIzGt>)ml)@q3#IHF9`P{H(BIU-j}JYffF zr()~MYSi-~V9inBDTmAdg)-2`rSBTStpQ-$d=R;iq4m=AqqTm4=RxW)+PQ1@TPP~p zH|9n8MwFF42o@+Bi*5z=wVa&?QdUBjj=oDUH+4Z7T?NM#JpsQ#$uXFj;b5W%Z#y}g zGS@qpZKr}Z5vn~vStA_|k1|n}8iTr;LUDC!q~zwVt^M>6R8yA9QA!JMiP=07Rn{8J z-c0xQdfTsRRMdlRqsihhGc^j=U*%YA7h7^)PoW+_Nlro5*FRyPatt~_R!-Z5BTR2EXm zPVY$V_Ylk!dB-iColPF1(k@bKH4b$`kL~pbpS0#lmNap04Bp5Mi^@O8>fnx7PI_$% zmg{8oQ(nHU`$(RA@%9frtFq+(@1gz^BIL?1zs!tuBw8XseA5&7|>XGuc_iJ*^4J;MpO1oY2lu>%3&P%tjGS0 z0%7to8%G+){{_~i!1L`qwxT^1o_j#DCY>*jE-@dNe84QFJTOTiVK)RAXmMWjqs&$7 zTp|{9OQa%yChDlVACv+11%TTBPipd$P)+c+lKnr;Xs^t=x|god&Uj2lJ-djM9*5?=)*^?%Ta{7?Zzu$~QXe zE6zWCQOh5rnlwR;E{L*Ha{erz^ixpQERGo&OvQ_-piC%bUFBx$9s{FoV5PF%3x!FM ze&Evpp6GS~wXhkgnm%gxl+(C$V&m&9LJgmVnt6&QtF?%szfi8aa2=G757g-xq$h^y z?lI61^U`&2p$LyP^gvlfFqWYasDFyv`o`e2BBlO6l(!}mrr7&(4lLD@L~fzX-4 z9=((cFH8rYwK%4_FvKdUMV>)TQ$Y7U1LBnoPQOF>nu0GCz>MRR-Ax90a=1>q6&^Q5 z1!=hJ2ce9Wb$0v#?m8pRt_LsbQ){rA#!J-SDmlZDR=`sCo7lCW$z9CvL8w$^S^E*F zyoIPu4}i~N%sRVJQCeqnb-%h6uu;!Fw}H3Ho*lJEH#CLGT7%q*sFhCOn=<7?Ijh%J zD*mZcw-c0omq&cmMdj)O$_i=UjFfq6W}t5A9ywNrR>Pf?{qhEP71*W2f#YoOp%G1r z@25$J!uALs7+dX?=RrTZp=A)QThcCc9pX2 za>vn~=zipQ%)4VTgK|+qgwH;CoxB!0A@|V+~FWWtDB{aR7e#g`x2SKUW{YGGIDa6Q`>SoEgivs`{wL0rJT3u;XV$~w59D$fNIwTK-xswuNjo*KrcOPDUJ zF_R*|>PO(BmadZmwxTY&ZET|uE{=d zwlnZMz4eZB-9hMlI=C)pC~|-%*UV8hqCl0xR9uQh#VWbkYXtT5*i|`o ztwEI4`G~6B3k>uC1(YIZ)Z?*bgHii5@V4K;IR&iQ9Q7i<+TH+la}qGtt;<|1UPwN4 zsuzeJiJ7gkv0BL}Z}4dgW|%JH5lNT_%)y>MprT?Sx&-RFd?P0e{I&rtbU_dQ2FhyV z{WPF68$kFb)jmTFER7nY36AJW&*^(HyX(}bI1l_<4))4HRw|8jeu)~Yz^Sa0R^4qy}=sBe&xF18jG8H z8U7eV=)FlA{TMlVUp?EZBj^|ajAl?e~^o0zB)dUEQTM zFwDk`*$M7F1=r;aHERN=L|{E0gwIx)^2=;%n)G~#>c1H^+<~EOP)ggO)6ZX7Z;+zm zlh!_`I&Yh)t^KKA*4@_szts09W~e*(IEE(s7NWN3y;tP6r<4jxoyDwo8B~b_+mzgT zYptAhPIt(ms{}vVCAop)wJ5vY10+wtT(TLQ)k3U00tQ-vbj_`y-WIIXQd|xkq?EQ~ z2|g`KbQExHL_C>0Eq$G&L- zUf!m5g*lU+schkVm9iEJ#O{jZ`||cl%4-E|XlE4$#;*a_%1~BU1OK8p|DpgJuK^jW z!eKD#r{>Xn70M$EtkvH~%yy#YdZRKDP;ceg0otw2dTfxg$`Ivt6Q%W^icrr`P{oZsg4P>Hrk70feQwSo%q+WO+g&xNx7&rqSt^4|(! zZd?a`KBCDz1)ZJdu~Kh~l_%ymN4ds=s9%`1KLRtk;~f17rOQc_uUs^~GEEL2mC}NB zeU7@i7i_ek-G*G$lIExp6R2G`9+Y}R*=Nmd;R#@?tXKFksH9CPv<>x0_sJ@@s6H8} zYgkzXB1r8ZVa)>DnoxH_9$UMqfG)9R9n z+NEUf`3V$JGP3y#+WAvEr3|XR7CSuzlzRedbOW8VOlI?F(o|_={s2^1OAw*O4pEl! zS8D0`k+K*=;G!ri-w*h8$1JK~YF`8xs>#lE4Dx}pp0Ql7b_LK&Yg&3MYOg(Gp8WuG zhhDyTCAj$qwAV)cil<3UFVv4Ws26FVlztK&C(k*lo7OM6ca*aC;uq8wEkJ)QwxI55 z!P=>-oC}z~ZeZ4K%-&-_QU>sFr_8%Q@cIn?%GcZ!VC(0A6?S0!b`UTW9Q6V5@t}qN zWmmHZp4hH?yZv0sOqOCk`+~Ck46?P29g-+>h(p~`J~)|$8JrB}XjF%b^K7zIzz*<6 zOL9+d3ttLi0>R~Fz;QJ2+zHCm0D1R-sVnGr2mDbOI95jm$csZmH8kB19Cd}TR;P2q zF)f@>ZFK$Enn{z)A(&U+f^4-LWl2Q=B|HzsW%2@GJ_>VKNpSHP=o~~@g!-H7iP>{F zuv3^Gze-szdDtrX&<&L}Xv#a*wnlx^XVbUZo&*2D2t{KPZSB?9z+N#}X)|T_4ZtO( zxv-~{Weh}>QCMA6<{GLv3Xt3GQ<7dIcXYTz&(Eu(Y|4WLYLd7C3;KBy<$?ZIY^enuQ+zZJ02iui1)3gf^l z9Velh$LD&OAO1u2(87kF1+V&oxj%r3y!b&UnwZJ!d_6IZrh|vOFr#&&ovEp&%8{mN zaq=vAe==73jpe_H2EOYQ!1rHnHxF$?I!_hg0m zF1>9+B<7-4pj1IHMq@dsok__D{>y-$GFQHy2?ju*e-kSk!wpE!E*y2RHQNF-ISLcRND9lnDmc6<9yy)+Lmu?6Xid6Ir}U zb*ZT1ff=G5S@8vgD(~4xf^l;|=c%B$6%|kAsqq^9)nTZ|FF<>pFIA?2JRKgRYoLD3 z16Q;t?sEF$%8LH;K^N`P$)${7nf@ur52dnEdLmw_B3KE`s6VwUwLzu3pbF@Tow`zu zC_(M|+o&V@IwZFa>c7d9&6|Yj<&J8&2efpiVzx4orBYA-)1a7Q>Rk&ej1@m`_kklm zpo6^pmEPg3{_ZygP5f!xUCZ=MXVX}1bN)`fLlN?~1WkP869;rTy?=wwJ6gIZ7#cnqgWtUk4S zj>LREn%bGeS-K!~A5$5$D@*OhT$H}ff^~K<$+{|b$NdL{V*LALiZo{mnC0?qz1?|V& zaRoSQ<4JYb&9CFTE9enAN4qoim!I4L>tsn zQz{DYMt#>dRyG5+b%C3f#Nr6(I26;c6zXX^;G*5SuB2N=BQQ-v*&ITpT}FBJM|EEf zF6Mz|^0jL1QLRs)mcIhqb+{RK2f6b07h3EhnV7+f%Noi)({wNG-3qgl(s{@M%$WmG zhWaYrRzBGx7&BIb415W?L{o8eEoEnvmRu*IjCB=hV1rp$E4f~so^qw4iqb>&RZRQV zU|=l}r#$pf{`XM{_HYWYvH&yXAkM{5+tt+=M^IA{)lywG{Dv}C{7yfNS!6n>Vh`+; z(_iafO?K7_)m5g6aY7Z4znoE&h5ZAj?P%hu==rX7_S41ZrtS)zZlMP256~mcF-t06 zHB-v?s!zaQzoGu6f|k0x9DEGEv;fIxDO;djIH|Mg?@AD+&~2tM$N#1_`8DvCBeksu zip<7*pi?}rs0W`=?d(wHo`5GyL84~)Oqb`; z%C_nC!OPF!tz3TBeh{z|46+7$beCBm7p<4kc@3DnhCrYcL7&;-kA!5(Q% z-|A4RXol%j0StMAIe!M~=1(yEEjX&{`+K?k5i3*)rIu~uL0mLt5r(W)<+Z55VIa~J zbkn-LoC5yn!%+eK{LkA56(2zdFO+>c>c(4EKG{z1y|9d0|5d21TDl3Dz)YSvK|kP( zR=bluz>r8VN@X*Zntc=>L5lO_R8+SzsD?vOo>jq)PPD6cg0d&t6*#ok59(C3REN{zj=O|Aa*1@diNIN4rmzlh{hO&j3IxVWjZl$FgrizyJK?yw( z@5K`)CYV*jz&s`C3g@V3UKHF{lRFB7!j(ay8|IaKRQgd=MK7>B3H07UFE+POofYvP zK7bW&w9C;^{<#%q9T(8t4kV;ecH=p{(8gT3ZwF5SxoOMUC z_QfpM7StF;llxlJ)?0!9OYl|Gf7%b2KcY#xGJ5w=&_su;v%+Q8Bh+)HG-DkTK2^Y! z5p0V6Vbo>iQ>W)NNt27NQV^#psW$43datw@tuW0n0*8ITj~q2_hWa)QEUpN;>e$(# zd}Qkv8Z1M3C}#T0eO`a2=X9auKx!?6DcgAhWibv^?+6?}QZ_IU6{?td zt4N+U16)(j9TgvC#-K7LqxNWgFIs};M=0wmzYo>Hx7L+1o9(E#)p%QgcJ=Zz@HZWJ zX;cN0X;Q2Ss)8bAm;O#0&MA~Uvw8jV1@-1fM(v5?#% zuL>P(Yyjq!#ysIp#nUgq-4wH&oMEjqwdtEEtEIhkQJIe;Jr7gVKB_~Rg)Vp2QJ}w$ z)T$pqSaoo2CC?@*3s_$Q1DArR@>I;S1ObOJ{fB^OTEqs5_}%i;^oN+HO7)$z;{E4R zW~w;fx*KzfGL6qy%nM4OF^f>$s6gLTeSN;V#g>;#sKZ{xu4`o&@aWws|vAv4$vTBf9D) zxBa;j{ICF)=Ae#F@z~cOCIHhw0}4>`t*1k&YBdl&71(-HHf|xk)SCrt)yvVx;NM>m za|l$?;ym9CY~*WpilfEXX>6x#8?Gf@G!mH0n+D7WTc1*KMxh&TfU>!Ra=i)6SE@qk zVUbe7W2M6{v7o>e%*1kZS~48+Ns<2Gt70%fBfZxSe9>6ymq5+dcevJDQDFlpTU`v(Q8_kRdE??2%sw^P zfMXhIZX3$(8)G`eVqVwU7xxD#$3P$5ZZ>Ek);s`bHL5>K1r4^hr36(>0UM=txi8#RHjC&>lcr6<4mtY$DX82m zl%IBbXClaxPaafG{B#0kc>vYN31u`MOwbDbivSi1;v8SpOnHRMUfw%53DZ~SpzSg+ zR2_t_qHKrWQA#~G*BzD`&W@o{MW&8y5wU zk)T0e$_(y--AW?~gIVW(+RNhE;LHUuJPth2Wyf6UdR!Qf4N*d_><6+F!BtK5og8UI z8VD~$nc+{=rE8$AHmbTh$de;AR!+>=Pucifa6t=pVi^dL1Ao>pgZ#Im-YDK?X=@Y1 zc_Mr~>WdF>=mfe2QD&)53${j0);)WC8Pu+lV7JbF3%-|~OAO@WO4FbY}la6gut@xwkH0h{Ycw!w;tP^Ny1|DgA zvj?KO?339M^Xz6CkD7GSoWpDO0ks@i5aEy%}pDX zT#J>w>P}gUGvG;E@ZmTWP1}N=N+_)~qmf$J&zfLrm;ZkgcSJ+qq!1gI3C=2NDrw>8 zDOcaoMmp<4eQ^`!219UP0X_FQX!jqrky@ESrBKPoz@EF91+`=*^D!@9Mg>NoO7B4x z&Ib#NFtLt5P?>UJYsI7Q3)JvAV8J6$R^J*HRD>i)fgbC@K5a%^GT2|5C+=uEGqsy1 zl>%%gVD{67cNUI2g0QvVixzpi9oR7e(?s()*8$x54mxZErdz0;Q3d6qto^$urh5X) zL0%rB9iAwkUGy3>3k8NLpq>M@kv&j#o}niEKO^YFQB*U^wz+`ggMjfG%DQR#KXi5Y zC{JBrjoCq7v}g{sMdc2*irXLsU^Po%VnBucVU)4*&-q56(<#gj%~7kTp<*@2ZTB%- znSgNyBy0C^60R_*2kxxN!E#iAyRE~PNt66?Li0ZZmEa?s!Dy3v; zQ>M?P*3l0Hufp7`h+ESQ)SZf%QUNtj9-Vdw1j&7j6@?FKfDPf8AJnO_#uuu?x2aZg zhIZ?`R%7xg%*A@grdO!H<-iKLUc(ubxx7Wi??ugM&ScJ)2A`cMs}ckfln{^pKy6!v z>gfv%+k>(?!WT59ardE^zTdzuH_G}dFFzZGxoJD<%@Ufp%m!O^Z{841**^K?J_}G) zUm}&Bu_jsO;6lL)vrs%euby4j{1voi-s!OFc1|u4%PG<>X+7epl%!| zK2SDpA!gSBsHsBVS5(Zwj26(W~vr6rj*3#@!hyJ8B6j+*6J2ULMiV7$WA zTlcR-ohk;wpksBgQ3D^MMI4-r*+?JBzq~;e8VvlVg3KXc)mSPT`qOTu0_>+T_@Jy^ zQkf{O9cEIZ8mpIkH!$BW1zmQ4{KAwqUJrII0QdV-wmSgTRn8T?g`T&{fh%d|S094L znoMz>aJjnatWc=sX)o6;!|bR0Qbk_!Yc}erJ*u!Xh`bB-$<2PGqn63<#%!W5g63)TMeCqG$DwxKq#{WBd+Yx$FcWp` zqbjVah+Pf3b7V|)4yLT`D^$C6sDN51-?HF*Pt1xlK-i_75ZZV;fY=%Vwlk#eH5yfbSgs-{kyn|dN@7D(6Oa8mf$)2vvo%-rG^}5jp~usF|12 z*SvpRP%D*g$`zn?Ph)V-26L&xs(M|Tbkq&&pj5t`@S_ideEo>B71J>*DZ^du2QKJ| zyH`mkRy@A{AS+3Q}e; z8`RMUPBU%j=wL8Hw^6J8sNq4t-w1r@L0R^4Fz+fzEW{IO+R#Oc+Cj=R%@$BrIUF3- zaa`>eWn(&{CMndm%0WW0DWS&G3J z$sFLd%}7_;{(gxvJ-)diH_#ca)swbr?AB07~8j*0-rJZwhSPz*+sx zF5n~;zQr+14adxtxBt{d^QET0a}3y_LB2Q)hAZg&^$v6GU`tb;SZ+d@q2}u)UrSg) z#aPYbZY?m(in4dwyzE|>KWtG3`$2?mRR`6}wr2FQ>?^9BC-BonWQT%joF-Vvn%V+d z=k2#_NSg=47Y}A@2<>fE`Rsvh?QB)~ZQJr8%5czM+1O`54Bd?QPCPk*M`g}L9t+{?JoTsY@JKR z!N#ZrEm%>7?uMb5+q9DPI)mc3dE%Ke&Dz=^+<+!&O1bNIfnjPAl!yAQH5h&Xb6HQ? zISs?CG7htdPUlq`^XqbyeOwG~W`Mx|C@U^c-2DsXr-e0F_*Jg~VvVV&Wrpgl!|Qh} zSflx{d-%zntdGfQy{Aw2Xr$0v+tNT9&V7{g`;sGjHY3_v% zsz1t@@8l&vcid^gCs}f>8(N zq1OMUgY*vIWI@VS9ihxiyPx_Pb@>q$2l}h=H_V!Ws0H#XcLh#PBsiK2j_E_lBo}IZ z6nO{bGy^p73HPa3v>fHEG`IX1YI0Gq$BuR_Dr8cj{D3C6fFE9iIDj8LfqemSF(>0Gpx}5aUU8?XRR4;2(=~`f~Kb_jhYkVFl;M;C$D_EdbYnES|V2;qU|1=Lj-9bj{d$sk7 z%hvXo+fz|_#X+g}ysgl1)a!Dfpwis=yEN%J0Ci8eya6n|1qPZ@@jetaQX_TNE{u_j zwlD$(6?9Q@nu;GWJ+-yH<;5drqKr48mPGP4HznHS9bmPZ*emkRYgC46l6{pXmj!?aWbi4uPKPbn_3e)Ke8BK}tK&CXvUw1kq%Qt{>~veKmiOD?hEQ z%S4OvH1Sub3*%_g^B?MrE2@YwDoq~dqK)^MkJ(9UdO{iGi}GZzE~r*LQ5)rTk;75V z%Agu3M|AT- zAZabQqD0Y6;gVGhv%fQFn2C8Y7F9!Wc|Qtt(g{26ASx#TgejqZ)PoU20F z5bfLkD;~ z9%DLQ0OPchSvu8T{{p3C{!->YwFoq?&gkPFpt|3uqDen6A`T?Wf#0nG*D^rVK>v==3sC^&raK($=I*@Kh_^QQr1c6~mR6 zr)&i^wBaT>pu6_^sa$Tb!p^x5s_0CR_Kz2B`HI@3qbg)OD6J;-)}hYp{|x>_lWx+P zGN*r_RBy~q7eHOL+cyf8d>Vvr1Fc)q-@Oe~YTrke}ujczNcT~W1kC2)&G?a{qzYBw-vDP=+OKo28e-Vk$wLh;E2 z%mRZkWA>r0Yd_d{C zDLbldj8ItRmZtH+mtcTiG+E2(brQVQRis}8>UIRme+e-7h3T#dI_f-a>WDfw2~|oH zY_wO*IHnK3BW z-(ZzSaG?Wbu5#f14=@+&9UhLT1SN&7fxP^cg6Z2uOdHKSWd*9+Q`Ay@1pMiS8Cp+` zb!DFMhl<8sFo(;thx?%hbOH&d!9VT(+QU>t=nKmQ$558bK%ehm#u9M8s=V_Y%6=k^ z-|Mn5X$NNG1z^BROsAWu_(ae_)3VY?=jb*t-vIO63s9>(X4e?-&;_&ERa6&6%30;k z^*=$%IPmW?Wz%|s=8D<_o~W+MH1p-6x2K}cRtFY}^U@_jme%y04e-?QwXvgmNx?iZ zl6JM^GzoF2?Mf62hJ%v--^NRn{hN;Is*hst6ioN3g3<-3NU;RkeI3J~U zuKxT|cm$@CoYk*B>hK$|Efdpn7;0KL$XY?Wk6$S>DTmoZE3`l<=wVARwlQV48f2P2 zP3~Vs z2JULbvpv8dcRF|~({~S8t^7A=0A&%{qiOk=6*b7RIxB)Spc_7@d8@!Coju(&(wW<- z=pz{J!mQjHb-NB~h4yGyAc+3}#=N28bP3?0$pl+U$rJsqpvK8T+TFt(Q5!VYm``e! zQ#4ZZPGGv+;=X>|aZNtiU<~G^onWo52^-c?mZlA@sSTZ})o4@$^`IGOlnoA@rqeYF zt8!mZ#vZ84cWCFUy}YGiBJ8)`N8>bRGi*`x~@Mv8!Ni6nqfxk0ADi=Og~52y%V58Rm^*GhT6(BCOd#nGFa|U z#kY50v^8j^6}Qz1+p9RZ)CYLq0#EX2ys#C@zd9;+KI+|6RI1Lr{(TwMReNxv6sC!m zJ$wQx$QU)hJIY!6TS)out&aQxcR~6G@bL`DKTkyu?a@kI%a;6qySrn)kvle4xXhC` z_0;I?G}2khYZaI9%DKuG$=ZOs(O&G%0L{8lZ#ad?Czn8o`X_IL&%p zt=`HUZvqnZ$~(7FUZqh3)Io`-AW=W9sI362uhku0o5vO^8c%EE!&9g@bpdRjLD?~- z+_0B~)n(RJ;0MvF6)J*Pek|lJS1PdL0$7GnBIR(`wRz>L(&;`qVU`A- zquBD8fr^en4YffHlVg6;nEm}x6V1U3jjDVHP*mTmo&SXT-kBz?cY_4og4T6MC5KUQ zwHWHNKALP8fQmapS!okgek!WN9#msh1gUJyDbVQ=6&E$!qFS{l;b4t7Wq}Ha)f$kU zcJQnxxS&6MosxTh?8DMU&qdh{rtF=1anx@NoDDF)AIF^1f!YC%sAQ#rgfUcHYDd`z zB@aKn?b-mI81NTWzY(=BI-&~5n+_=}_wvIu(7%s;_!u=u&z4bIO4KVm{iDf9x#-xM zC`81D*}Gy$8GzV22=S*gitA23_y zvr(W&47jgNnXL2NOX(&>wO59qM(UN@%YZ?ZF~`J#vgI*dn}SYZVA5pDtagJ1pFuHw zE}J9gFY$odvPHnXX5f>)39dU8wL`-=ro*Q3c#x@1FI1=Ewl{dI%UvH^Fxi?XY;@Jw zp#lBULA7K$TUIHVvVz)=b_-E`oxp){ppCL#Tf@&*$0bg|` z***#MJqQMAxK|XvdHZR6N8x<&5LluaHL>8?K;_A=I>8$BMLm^A^u2{yLkQI&7cc;| zSVuy?XP~?h=672v7Hgeb8i0kCAh{Q1AJsTbWp)mz9*@~) z1nP}4^=#D+*MfO`r_4=5TN()JC>E^DDSNaC+)(;zq5q!dLG5LXa#Q(e;HMMf_&3x9 zIfI{4csczb>Zdw*I2+WhMw3w^!NaPcv>rR}1v>r0942pitApyOdbzK#A9EEm<|}H{ zd@yYjxTb}zp)?ZE1;lDb1J%nKZLP7QHtIi+9YsZvnxLyr*wpQ)he{(Wl-BRvz})E$ zzH0XaHI`>HnO31_#_V(rG*CJ;YfY1uinri4s6B>YzE;Q~2{)C+dl~m;D>y8K0QPJAu zrq-Z*8fI_+YJ|LLYX+G70MysTp{2sv?FcYfPFdzs5E}#nw8Wm}z%%)2p=FfaQ%3sz ziN`uAQYJW{s%B98PR>6$i?X?!L9mXU=jxzfKj5Kbai3;+Nh9^u|7c{mUb$V3k2gW> z(7G6o0h3l?KJN=E$>Az30*4!78jVDm<)A*vX>MxEu7!btAyiy?4+4}9*L(mSk6}97 z{r@*{^GzujyaW7Hk7sIwKeI9C-U4m49*&*B&R4)icfp^^XQ$J^C2eH3^2(jks1@^> zn2AQ%RgN)!1jwC&`9X2}^ciTHjrmG`vSBw^wvaL#WoePF70!tG~d;%){KE@wpxcmCdQh zQxn??z-=P9RhhDg2dJdcsBP|`r(AQ@YcN-VH8U7A(hhgj-!VEDr*YZGms$$CuY$S&HI`%Ia&PRBJlRMg&1S-VAu{Kn{>%X3 zO=$AW2=!Jk4{-nva+S+k$vRyz7et{P?t?>xSc947lvP&>H7JUD-3%Oz#2leLO4C2J zEw~%=v7+nPE>x1-V&gkdSbn- zC3-(NttM0TC(=clk-=ijVQ(=5f1}n;0(}&yhid@ycEHpF)b3Hjsin_AD>S}BU#Yku)u;|DS?>bo#cbNyYkz;sH~#De+bl8t{i$uH{mp+% zS-RqU&H!*#2U)f@&tMO=r*r`cYXHu+#GIrgSwbthMU#247Q`L_C3jLW_b2LGH!wLI zI4c#5F$3R~&tkOkQS#lEr7@>>24yy4=ISCDz(Hn`c{eHn5A|2i6Ew{Ql?zf9{u_j}r*Yvl$~Mmj zZIt)6CV}xpIpT#%QLuYW1uxQgVx9wPshghdM3cv={jN)U$^^^}%fNywl&!sv z>UaY6p%JiCZt^LFs-gKN=#VKo3N^wH6!;I*#Tpf>X&uzFZP)RRc8bs*`pU(0GVfS0 z95wMHI1vqADk{3@9vK$^9x6xFk$YDTLtRV!7pk8UDH?)3@HT|#&^w&VU>UkZ^QCjkmawvq_n}_P(m?judZXBIu@vYjT!(sGgsxiatgU8@xhDiORq?x0J@3|Dj+U1UlACS52a2zv!d#b=eVLez6e;lv z*m}xq)(X1%O~81$N~1$yp5o(Lca*_$y07;bB3@NZA~Z~{*DgoUQJJGSa+ywTjOMX64%6f!>WgBbZ5K>yeJb{|Laot( zkzIz0E+0_a3_#RXOz&wlsi6ok)Q5mpdr(Q+z#ngL^&FU>3tzBC-=h&Q{Q)k8g2Dai z1^_nb%?wIHtr{ zHW-{u!R)sk6xDLBFHG4LYsRu995qkDG+U{!l)g^#Ie{6o9@M!C{tcyU%YUd*2f(8Z zJdrvHJTU>P5TtKaS2jF2^p6<5u>j z?2(X}6*3}wl_+GZ%!Cpdl}aVD6&WchD>Ga6rp(Z?Nirj3kN5j~|M`A?*SXGp-{(H( zx~_Ac=gIqSvgfkwiI{sXU>?xd1N&1jBkEy(`hn`G5;QRibIVoKwy_LtTv?Q1YuZ}W zMMWG&mA(m1Ynq&=qkc96Yg&L-8rAi`z;^9_>QWG_?bEy@ zuu%4->fKVC({HM3tp5-&@FW6_|VLW1cbty;srZs~VA!g8I1$G}TV>=Ot~Oqfyg)qjvsAti z)DU0PD{Wbs4Ke#_^}UorVfuZpUO&_f?apIHqMoae9aJbk?u>eH9Sn#EA9dQisOq!S z26aHsU8Y3|*JVwrfvMWrFZ-YZbc3&FL8#K;c>s>)s@V?}nD#mfdFi!U>)J5=cYK1D zqRbVYSGCzxT7bHI1QctHqj4WFOv!#y%d(auh7l za|6t{ecVvg{TZ~?(G+K>M5g2iwW9IbDI4D{17<71BWoO)y8Y?$pn_Ir&L_}Ye@!`Z z5vrL=`20n9*Q;8zxd1Nd^$Q9Q^&TI7gYxI;@@z6{+YXRD2zbeR`T#eWtrg7F9$=@6 zxv&n7$2wq4wgyMSK|RIk8%tCvg_)O53VT%H?rj058i9vbL2eshrCd1v0&MOAPRs>s z0zfTQ2BQ@`a`*9gGXt!ZO|kJC{3+BLDCT5 zsc`J1N*LRZyX;mmud73TC5<2>4#$$AsC*fy#p-vnEBHJZ95uvo&KT9q6`auuc2aR0 zr5M`ofqAzU%6d8o7zo}x2G06OF;^3NUq5stZ=kKJUcZro;l?0PU@zW=F{sXpXYb;e zhxPDX%Gyp1=zO#>%0cJdIMu(QL8vv#nV>pgSSs*U#q5{|lJwcMr;>P9A=Ii+5U7~E zqCnq0T8@?|lar|RZ&7c;!DwyUBl@D;({WVX4aRT8v^B<2WGG1OftjlSS*Y{)YL&<@ zcQNA?_dh;@yg#&6P;z=`CZl;ce-rmk`raE5I}jKh0y~wD`&G8`mjON2V^%EBQ+%sn z_MVJ#(BS-4B`o!n%X;V)?XeY|@Mh@S7I$5?TzOVv464f&)H2O}b6wW3Jf@Svp+`5= zpXZ?PJ5W-~ceosQqC-x5m7Xb@o{p8dbBtE*lP;?>j<&|9L4P~Ux;j|2R9>7MjvAq9 zY^P(4-$Tq| z+Lhbt92q!@wu{G6^L1#lZ3fOOTTOn__Qw%iQ7BbR0KN1f%0Mw|FBRgC8oL_xvMs7? zL!M?a47Dg1^i-K%pqQwTNSA!AQG;wz4vRtEznH%I>EyL$@`9dQy)gJ@f;sUUs_Y)r zv?x?1ecifAd)OfrgDrY~-e?h<5Q&9seq0)My=GuXJv+3ulfa|DA zo}j2qQO2c~z_it$9)&5u3u_YF=F#S%Iasy?<^Du%9;lnD)j#T?z9<-?j{-Z@5QB24 zWlG-ey4Cyxv?cEY?%y%%YK?+6;SFtqN>gw}4*@+jS0QVFsfzeQCEz=E(A6HZ)E893 zLe#M=?()eJ^TBPfSKq$oS5gk_g4b#?>a%V?OTXA}RlPm*60^6mu)7`t1dny{ zbX0N4(Nc6#Z9T7`F^dJcHEBDcIas42{!J-4Q*n@>$zBtV>Y|OOjm`jmS`>Q+R7zKH zcpAv_1aT_e%@l+Qny}f&Xse|W*!=<*b=Zj494yvzBY)v7ZUYjwftWzr7ET1WiZRk$ z)spaZ9BKNQByTt8Hz@YCv|=P$t$q@~g_t^GvXN9Bp^C|C#Gc??<;$V^kg{ zx`Nxrcy|}avGWtEd-X*S`YfM3Eb84c&?_+{VZyUW_OKLt@a%Vz1M5-@hy(F zT|pteZ)ObYV+7c&@x`hFe{9Uq_O8S9R#n;l9lTV{J}?i|EDs9JrC+?N-k8Fex0<2m zj0S@hb>%d)quoKNMxcQ*ueEmK_xnMiZMuP0`rC5M3Y#!P2Y`;nF;6c8SN*{e4-lze zCpsJBU7*_D`5CIJzMpnJhbpb_7glNR3x5L-?C5exj~t;hR6pIoPFvfDs;F!gGIM9q-Ya1ss)}O!{Gi{LrK%O?BUz)YjH-JMXD507?sT|m-Aj~%lm6ZY>%iGx!6y6H1>xy$T zag6Xo?M?x6_4;4mfp3*`1NE~}hwB?;ISP@Zomp=^uXI!!P-J$QQi|}rmwIot9IVL57OU)BfW6k)j|H6FQ!`% z7}bilOq~TB^t4YphNDE2L*TfoKr01d-+UlN@#m&d#asucws6H@OVCkgz*O_^WQz*PI$fq6WBwri$I}inU`+FujvO zxq_gpX3|2rFw6(DytcbH_b_+7K>b#%b&f*C=%(o=VC!tWE~8QX)Hz8ft<({;#TFwb zmusaXm9U?+(y{J1p1srkw7VSphFY$g(^D_)qa-Nin67K9cjj7`bZ{aJbAq0+ZVR}ox17+F8?@IT zjjv#SRm4ueOk09(^;e-cNn?&w`kmL)BK7ImSw$fy3>2sfE@_`0c9Sb|R6(liANB8> zg_@_JDOwiC;5w*(Z%{3FqMDuscXj9K)}YW-9KD~S461=uDq2Sr?dxWsW{p9$&(gJO zTclKbt+=m|hMJ*$YeG0GuPLgv(?)t#-@O}aI(>xN+E=G2O1!3FZXJZOP$YKKBtBEXtvv>rlmI0x!OoSX_0?7 z#N4Hq?xq0Vq0k#M1~Xh`q`eaHyNYGY_S}A?g4I>$#0n}<0o_5kZWVbCM~oXPx;E;d zD{7MB?}=vDNacE3CsaG-%pwJKmkA(hH`wn$TgYqR(+6{aw%L{iL91NM#dg5>190s? zoBaeH`Ry7Qp=Yc;^Z&n2HEE2ifvV!iiQtH)J9#8+*1Bey{)KypYT@cfTv${q*FwkH zTFb%mRXFCgKy}f&Hr1>y(f#&l^R*}kmS~d0l)OzeTUI`_`Q%6KQ*>1O2#RR}PASEX zG(lZx%_C>1&aW*=n~mbhEC)Q-Oy^S^SK5u^_*okx7;8u^H_u#HypH6FkgR! z+P?vOsD|m>3*0J9zmkei7X?d~ilB~W>!5a!pgEZDQ&3Ub7@c(O!-pU#5$x3h1>10K zVQnZ4Lc!9dv@J764bZ#QaR47IfRh3(pg8Ei7qhMs+Cn9Ck8bbS4-{L6>9iX39>J(Q zYoScu;%K3g9HZ5IISG85j~REB=UOD7o@+-+x5BY774@tnYD|4p6Q$>)Y}929GAb3M zDI08dfrl;euGAL3tta@Q?Q5(e-;Qy1mhR&7_oF-_RR{ap662r=|Lf` zsN%}`hy@^@#@s>w4f_JqQ0q#gI#xzyE(Z5hdGnNK8x&mDE_f|e?Ha~m&eaSxs)7oS zKs9ZI>Zpf5(Mp$7!S-4P76xFJR(My}L8_=$x^FR5={F2*h)SrXKE_44;;^`c=~e?3 ze1WzZB{1KoVLm;Fs(lI-Fbg%u3gxQR|8*U8u>_q5wgvHPFsFy0tW=#!H3dG}@7t_F zg{cJistgX&>hIB<9&iRxHkhXRg8RKTqpMngq&_&ZJW)>-0s$K7hedR;m;svGVRo7g zYAAeWt3n?;sWvk@dwHY2ID-32K=OOqs%q-eT4BCZfps2?S-AkWa+r(xb0+4MS15mN z1zp3z0VUli1=m8AjIJ8SJe84)^Khgp60hp(-~w6?A8i0Hbr7vK2=(kOn05uTrWQHm z3lAEahlKC?<<~${7pgKiQ74I&jp@?%7iwWu z)S5jww&;)@s)^n86rAaY!@3>H?lU-|!$DbnujZx8f;QsKeSu?Vdz6o2s9;YJtQ8E_ z{YJ#1wj4(tIYt+!vzSe4p!O-aUYMdI; z1330A0XMDz`;oxm7LIn&psvEZq*kk)vf^cNRNH6ZbOX%VTKyjVxYd5GOy+1z8=Y2O z^##jRe8Y6~Pt^^QG_m_z0t>CtDpk0gTd2+2RNIuI-^s7242@u0A7Io4^VliS>Ih~j zjb+DJ)PeTki>4`FA!?_hFt{wrK?z&xGG@B2C}ECz@dUN`8#tT=de5ir_79#`LSZ&Q zsn$~~JwWLkq@W3%2pT`dF+pkSsR6CjH@rV|IDNkbbN_72a;kdedIQ5om|;qx+51sO zcfbK3%z1|3<~y#~uK0WU50uo=VMRyOz0#<)!%lLEb*_MJLn;ddqclPz^0Xt^@HrQ?HP&P&uc{Rb>%)t?1mO^b4BG zNbBikUg)=#s}E^=aGq;@b!f_`oSv(%c@48@vn~MEdV)I}@z#==so4lGPnVI)Q9fV6 z5(nU?*BTZGUTO7*sX*qy?RE_wlTK85DFPjVkH3Fx6w6(c_s z?$>NF=4Mp}qgCL9ZW_HD??vVGXoann@}r*aTv&POyb|+<=4wen%p%vo57nVp*J-E&$;saa)KNm1@1(7Xu1!`Z zKl=@u*Tpeb`+~I!)Comwuo>#Jz8UDHcp0V8tDxfR(F=#gd(5zt;L=$zShF^;8IJ0j z1841*CRe}=h5VAAV65uoCY8CV9YN(VU{#0v{jvwU*U+W29NRX4lnIz_IvTvF36AR% z!%y0-?(I=#}96U+`SB)<(Y!71W!@sC*sy1LjZ9EZZ+@*I@VWDO-nSIkfnFK`5d%G3755qxyx z6()bAEqyI!y5^wdcsjQ(fl5;j)~<(nLtkgw8e=XELYZ^}<6UJc4&n}=zK@_S#{)H> z395Dq%Bm_zR?%8f15D8h-cU^T)NB+}EipWVs-;y;_5rVY&~{vb^mIC~oB=GZ1J8DN zKgEMv-?-HaeZs7^7snC{+7`V8MIO-BRv+EID3Iz|qdKWRyS>5N`vs^u7_*N$msip) z97LBzio~&sx_=tld`;}yp|m~G{JCnR8{BF0k3+532u7*y_O_;NN;%L*sWC!{GyDQr zs@a{@inbu-uVXsuvtGZOf@`~;dt7ZrH-Q1CX>0izbW**_uSZ_jfR-!Fa&CgRDz9-j z!L9GyrI(K9eTHBjO2%7IT|zYxpVy#zDh`a5ziBG}(JtV%-ZxK~JU1LT72yVc3VwGT zVj^{`f$Kr$cKS7UL)}*%g{WAbRyka!oJr6LYPkhh_-moUtuTL`LRB3NB2_W_O`m>zlWs{2|UXf$w3BD@0nkWsnX(G0|02fVD-7O$OCDKw0 z^~oN`CVi9HP}S_8{*7T|QOu5dt(`WgBU-3Yu^>(ZI{AQpRjbf1Mn8EZH>7QW(x9`x z+OV#Os;k^z^ayjQ%>E-mfXc(A7Qj!-ZDWjg(hiY(s9)OdoV4x4tCmzz zpoc4&)>qRNcQBjlh|~Bs=1B!tas^O8-)`L^ou)2%nkM@gut~AoRYlcZ`_|KjsLhIv zRZlRRDqboo%$zG@`nN;P)`Qm6R+kK59KeH~uBYv-)@VXURA(JEE@~LN7lNYOz&VYe zz$&~!-BBF^QA1Ds|2J{>uAq}u>}QPt6Lkcd`VpK~?Xo`yY(IfM6}as%1%a`)s=}pd zTak;}*#fjsO1$rhickstSr_bk!Qh4+Lyi3orsx&#DbsHsrgNhMsBsHWS5|{PDy!BV zKuRv=aK&~=Uv6M$g86qk$j}-FX5&az+O-ifZ(*A51#_l@1RWpBDU*H%@+9o$zW zH24BWod#!%(C?3~eW5B*S~afbd&~klTzydxl-0unlqQyX_|AtoobG|*TIRW@P&-^@lnky-^JnV`mipfeMTv*FhOovHo>XpY=2GaDA81N2l8w9`v(H11`rgou2{= zrJYfKx|BPLqx*ZXY&UI5I>4FexmT2hJNMJpr6%fF2W1Fqoj2wUJ?&QkP;)kI zpH;u36#@bCK?U7q=~Ym1D`vr=-1*%)%ulL6+f|ePr~(><&^BQjuv892HwQVvAox6p zJxaejDon4ncOGtuSy$g=m(u~sd?#j_E{j(_R#I5!??LCP!%$s9aV$}$5AX%`KVupc zL#684{j)$j1=5q^!2K(x&rQ@Uoxeuu1zRnmZB8=yu3@b4MOD8GdTG;NEA^ooxT5l# z_ZgHNgIQM*TQHZq zv`sMK&Ze5;(GO_bA!Jtp85eZzYmoi}bX0{-SJs*}!`xg7wL~M>IR#8nksPF<9XACY zuV`DNI+UQJ&1u!!wl#1J_Cuu{qI1nfm_1ekXB`tJD~h94#ItpBPpl8#scszZg~MGr z^GW^c=Ynqvq%#WOMB##vskS|u4g0Cw-cNrswM_xMS3z@3wdtg8zg@>27wt{ye^E2S zz}CwkF_X3jzqu?f0QE}VcX{BKR`t7v(I^Sr(VLgq4$_sx3Ho~Z%p>|8TZZ{u8DJKO zs-oidO{HbB;(3xXpuIi_I$SDIsk^Z2H>eYu~z*6U% zXnjtN)E?m%2Xg$mwyi$Ont5YJTA=PKnSOTwJryNyHTVA%-feV1zoz42+9p(HVN{f6 zV~uv!Ge5zlA>3feQm{~$dCsEku9k$-%sQ5|tuH zpr-x360DOd>v!!!AD5!uJ^*tn@r*1h@ZcThX1&bTk$U(l)QACeK9_{ruJ27pC>+15 zR2k?bk*!HIP{|E)#c|#k1i6EQN}SrN4BelDcbcXZ8vQ~Q)xd2aLkThE63V75%GQQ{ z37bJat>w>X@JDO8^$KdO<}dm<=syv2k}s=(*XqHUa}sizjN+%-^7#VE8dZ5aywmrub8P0oPr zC_8tsL8EFQ$2@(@9T5-qf5oh(0mZ6c?SEi(9Ol){s7;YzZc8xZHb|HQ944~>wNx3Z z@5Vej3T3Dn@+gTqt!Q`B>igaY<5jBW^gzWom$wzDpn2}&1{`(!J>$V&?fWe?_v3D0 zHhT+3Ibr&ZVvtFSoUY?Q6Gch>`CznSt+Y96#&?wMWMH}sBCU(*|0PiTWg!Pt_-VA8qr~zy@u6qb|_a?i~25Si8G`extN$o-2ep_zmTH z8Z1#pIXKYv;Xe4Q@X7v2+d)-<{r6C>+u~SX5oLZBq^igay8}8Lrpsj=D?aMO)=LxG zsu#yBH3+p(xj#uC8{CwG1$C(W9zomwMIcoRU%et&orl@wJ>Fys%nQ3gTLo)ZIa)aY z`-Pxn2fD;6uBt0ATd!F-cFaTHEA1WhH0cS?41a{YGOT-fw!V*nzHPg0&|x3iVZ4S zFO?8gRM%#hamBfAAWf6AbRKQiPT;fV)S)ttM(u&GDpJW~s6JY)X$quuBSGkU@NER% zdav9iL>DXlje+AkR1F<*vYvx>o$xNah&nJ6tWn7rp}N~PjBA}W z#h3IqvUz&_CEsx5>_XW|h3osR_|Dwa;~;H4qG`+4Jh$42N>RqwP{G@%x)JmY)Gvdh zd~GoIA-Mj9wt+67gDS(+%e39ufErR3W$p=PZUeWn!CB>Wff2w%fth)Re)daHZ?yp1 z)%lx0-t?oGWnDqvZlIH1W=S^chX%BJD&{Ly?~p;DU;?OC8g$(R+*B zL$ws4C%N`kNgNqPFnfOoFOq0mr(o#u231PSW1~~$Ab^ zS9A&3L|Yq2d6f|Ld*JA)O{uq{Jw`8Ra2}YeNUzm2^&1OzYT>&o)~u_82qj&t;;Q^3 zRDX93T#vNK$D&vtMon0Q*F_Uys)3hLM67ZLfAsK&lW41&3}&_iZ)VaKF$CP=6m$fCd z)Q1K;#pFLd*C&@Qrgc#VrlXFkPL5lTIvxw|rhsG>sEq}2+|;Jo(FN5c7hJLix2-^u zc8J)GcvlQX9o88xUf*WaiAR0jjKgsX>brIg^In*RK7$;Y!)wv6gGRNhA#HCoSG#qC z!`hw46+n641u+`hj5ylTs_D)nFzaiz3|oNMcpSyFS@+G)0(dH?n>7dNy})bbWfz6s zL@ml~ZN~*NX{+T28kVJPsQPtU2af8SsdHM|Mk*A2bee0SoHi{D(p0$~>66?~C)BZd zbQ$#)beJ8P&}`^g|a-tSi&4J8>@~_>jKs&)|TD`sTy0QCO^lC%^#ErEf`TpfF`)q*Q3Ykm7@^GYcS z$|=FF=>>P`_9+DzfkRbPszTskCJ(=%X?ki8wv?l7u+Ak@Qv_GM_1B`ZB5|}E0P+TN zgZ;Z{I~;}S^%ynT17vGxl}>-%0RO9kc7bIkeo7{)dIRv4;n_VySY^UQE8)k(ppEhwXMJ=+~MOYs*ONx!{% zqpEvpt0ugD3V!QpS#CHE9{}Ytz>|JpyVg8QAG$8}U&&nOOdHYEiA+cfIFg1^5T8O|Ej@z!Jx#1E@=hpj~6k>YB2?i%@$f(z)MU)U_X= zmkM1S{pI%V8z@@^-#{x=_G|F%8Rl}Gwd{1$4cp~Cg=s$uTrlFY1nqFvsvH-U9D9C( z?!lO*x{Kpr5TL&$^xuQ>osW0;9n{b=sH!?NCFmekt}2)|gtmtjzy!t9>msyO)uym8 zQf(oiyvksZ_L4U{P-nM-wxz%lRi_ZGzo80PGkr_(SNo*nYOqrqW4;gIUL1TrpqCYc~_s?H*YD6Z1lMyqW7z$tt1Kb(mbN zkh9SYg=i+nXu*RzgBF@FQzum0#V8MrszghWPvJWHI{2%4Hbpn6t)Yd^05xSy3j6ivR+ z0d?aTSUU$eCGs_x{s#_{(`~+m|0Nd61U^^aOQNyUHS18yY-LX)z;}HnsDB^jy)J=dMPoWwk? zy>pq44wEO+R#uyvSzm7I*Aw$?B<6aRT8Ao_mzIFxdM#HKuzG5HqXR>wmB9NxW?{XX z?^3Wq=s$^Dx$76=T$P?V`q&zx$R76@6{fGT3|0I*m0P{EMp;29<6+>hygRhWtxkh} z-SK|P0rhk!u~VfC^g~(brfxMc&*}BE@1pAIGN&7uz2xY47WMWQNPC1C@&L?K9>pti z>~uuCsY?D=Rjf%O_cK#mEz-&9<5N`NFVv!as489{zCY&Jt|)T_aHbt*t((Bh0P|>T z)Cm{VbA|F(1=28u{ND-Od9!vJ7bDC*?NHXGXuA@R3Rf~&q=B~U@qXC@997dF9!ITy z1}?q>p87YH%eJ5jW&?Xo&U6*To8!PF6@Zu_z+cfhIRmU#MJ?No%bFa*F?TBF5EaS1 zW}vIiRT;OzA>H(r32M!5P&EWtX->@)?N+l;`5aJbby42h%mX)}tQE182vLlemBVy8uk|q%<*sVcPq8*mQ+#6*Dmg}1d;+%r&*Tc)!k1%a zwnJsAZqy%-dT^JJ$NWkAmv!Oh|Tg41js%7`FiIm;}tdz~{<%hik&zG>Oyn`ujEaJ=@bZOy`@wnzi=Y z^b=GQ+kQmd*LyV3xi767*xn7t(Xq4*RH~V3|8SFfa{^U07uD<({rrP52PiOO+n~0D zf#xc?*1lkK1I&_&zk=E;23msQdYX@psV*aNOi{?==LSBgADWztI`b?rqRYrt;NWLF)c4V6qd_S+%q5 z9}pD{%6sED*__)?O~yQ}GUu&a7^AsAZ3$eIGu<=r8g~S#ioaUQeV^~3;St*2FGT%# z0p^?mqke+Est1ND>;3d@?bo2jEkf1Ogq>7r`P%{vtq5*vxX*hsj5^7{RRL!git2cl z&c-@3^wN7Awm`j~0g8;p?C*>U)A{DcY0$|N^V$Mb2eqxgkJ&mJ)k?pot@Y8mEF4RWP|u%NP{uQrT|S)je<;OZb$y<(`{g}^pVU8k)eDF$;&dsHKR zJG@?3%u^XIl>ib?0pnxfyfUSG7w|-(oUX}vr~*~H80I}i*j@`vYrXHMo2V?^evG2z zPBn13H*KS*fs5L=rZ+;h(>e0bP}EIF+IrLj<&_$)dd7Am)IH5hwC1Igs%X(}1oh~d zn8mh%B+bxCeVjk0Dpf_?vBUj8u}? zx5d2p7}Qc_7;zJHo(!y8f{~ZORjul18_-dKRMQugpsd)Yi8bwqDieZoQc>8b>Jz;l z(?E03@-okusY8)P9A@*PjLL2WYTG!vxZTB3UYBjw;+0aooK_w+*Ni(Df)!SvvKfx` zdZbMTSF}^0Z_^yuYl@?^ZVe*AlK;y{LAvBzrAv!DwCz+#4byqosR8EKRM1dKGE%!* zS*7?HeGB!m7HX^F;Q2XJ|I47^8!-1TZ9bazqaK)HXXyOc8P&+0wr%=H8lx2g&RXQo ziqo|hQQZoIac1DVLaM&z%DEp1&IT`3u7^AW9qxhn;ow&sj=9Q@A~~2o&v;N(1&Cz^ zIHBsZP_^V-PjKurNSzPfp2G2KD;O2a6@z=w=AH!Bn}euYj4#m!NBx6zxv7bbE(tnT z0cBN!o~*+AN)fSTDOcQ90N;oLr}u)cikAsGo?q6c{!ewhuWIp|AYk|aWd5aX-E`FN zp}^K0)BQW>RtXHaNn0tE$i22;W=rsWKKC1=EkAq&n5PrP-2OPSv;anZP`7m!So<3D z?;&8?9rPVc+qyJRHVyM@Z;;%PYhP+qqkT}XRM*D%fI`hcH@#c;pQzpan22uL%cA?! zHq!-Vbr5w?D|12r53*;fbv3lequjV6BNFAU0P)hEd`-bnL}kfg2>7Vvto|FsX%!}R zpzZ5SaH$J7ZS#b-%^{#gd+r=r07nZw*H0ViC*7dTHZbrl=9T(%@tc5|lPK>%kgj2r z(sOM#fUPG$QzI~AhWaUCt-7PS3B@$hK|MfSZDXYdq6U@+_eOxLYr&Kq;J4PTQGSMT zP3v)6A==CsR8bYUmJBv-1QWHO&lH5aazX3bV8A2LEFQ=GSX7_J+~tiQh|zoO*Z|Dx z;7E0lxfcXf#vH1E8>xv%T>uJZV%F>h`W*wk6>uJ-K-dycYYccQZ;(pRSOxX7-C*N= zP}&lNZsUOW3bk~S$*<%*^%9k=fcv6S@V++cnZETsUllc1 zNwO@7`!!R6YFD4OLi#(jzp8bX$~Vj2V2z6EXFHThBfLr4Dj#YW3RL8*Qohxnf{Hf* zFH3`1WyJzb?Aw*7fx6YRfm|EohsxgD+4 zsEe7P^?0Jx%~AO>zleER=2=y}MVl~xHbxn$t?)FSR#fR{KMh1x!VFa847xnr^ms(q#&c!aEoK@jQYCm`H3tA|YOX>B)i-PTI zKsim*pXaE#w?Tv|W|=T<&{uV6+%2%-CtWgit13-VRf18&Jy7>_S&vbuOWKe2X+Rb# zOE0}K;}kE`&w@32g_(+jMAhdXi%_2$g0=COetqd&L7%(p_|ulX1yoS{jn_xULg}bK zhiEIVTrHy;OwjtCSNOPT7(Z1-T_#|DKaUxzSFP->emc#0DJD&wF=yyyKD+>p?ZNjC zIP&Y?8tzqPHPkZBdbOlhG_?@6AElpa@Rb- zF?cF!ghpD{8uN?duj*J-dlRm(&WB1@Slmj*Q8yFJsEBE(7$2|QZ@uE6uIgX#V$7la zKoM0vgF>j8J-N$gC(ONVF^6l7$}FU9!Bte-6yVqiM}d7H)&W@S%%ACvqqerTavL$< zYG+@dpI_$7^wBUfC!sd(LRI(&N~wbQtKcmU2X?xjlNPG1LfLO8-ktBkMZIOnSJZKx z6s{>hcKV|xd;n%D4=YvN4rv6{RKg2re9LEG)|-sluE}xGWrmu`BYvQZ#$uWE|2J`# zuW_wDNyA00`p9kgO?AGhq1U$1f1c{~KO7|!LAw6E*+DJKa&vHSGF`r@k{4F$oPP?; zO>lJozl2uD8>^y`8wcL&p@++WGM(s>;EpP{7S(zc$~>LUJ#;kebCI^fC&8tAI7+Cv zm}LSlZOz8z=<-|J+$B}i0F{}?+9&h9!W*Ex2+=F<&>Ggb0w$@D47v%Z*U~!#f+MZLvj$+0cDQXSV9{xy>2gd1UsN?ko3E-#(Fr`< zP;8`{#noOJ58`RLnsML{o8!BO1X#bn0&#o7h^RAkl zANnf5Zvo!^s)g^HfM(jRU#W=KDMaVBQM4Vq0P09xQnof$Yz&?SvK0bZ`*BoOZ1-!A zYBCsgPhst)9VGH6xUd`3M@4ta6cDHyvRCVNQe$5K9rL2rsFLRXZY?lPGam5&;Z*TH zq7#L>PIYVs9esA%u3x7?upK5+@&TiSCxwI_xtNfK1G1E*px(ZnujkN2~# zxS=;1uX672kG7>cKD|o@85&DFEx=O;%xk~oXhpxT&uO!Nj#*Q&8>I~@zz_^A3AQ!@ zFD`-So}iS{DykQkJ=LNVQ4$}ofZ1Pfeq1koOjjf;RNS=FEL9a46^;5Ff=Wt4UDHoH z(={c*O0_A$nEs={iH4ZBVsTtjuny5%p4G~qF;o@Djc7v zU&WqypIPH*rvv5-Ps~5641e@8^%5|fX`1>eR6Z-@3+h3wzT&NFhI#NK>hxRM99==I zO5}xypo~WKR;kcJXS^y98*XWsK6DV-=GZcVPa#51Q&@lAl7Q*i4j({uU)y zum3CttkGKjQf#Enri-CI3GCD6@pU9^Jyc{oRCxO2M1G8RBfu*0!NuSAVeRHpBDgz)*xUo zZ5wnLdiw&k{uX$oT&Ud_bzU!MRfK-cPhhsp1Bst#>!bDks@i#NGpdmVD7F+-umrU% zar9F-hWy4nwt*WANkR>OMcXVb-m>eM>r8;BmhtXFu&M^QUWLxyye|)h46kAi6A$PU)zN z2SI?o`8m@EgzH%J)C^UpFv#A9`R6KkF5-ncqq(oT1f15xhbU`DzX44K(w21zRY)Uk z)Eo2jEU;dcfA9_3!tbEI+kxZy)0vlJQM0xCy;9VTt4mvJUvMvn&e#9Z*5@N|Z36D; z6^?2*n5p$xsI$yam4d}emly7IsqcewRxRlgf@z~)@9u0xt(^j56T$Xhc)M*xb-qJq zcYSr#LizDk1+7`NC6-|N4 z>5S#5W~J#jR$p!Tk@dd9c^w_fd5A5&<{3Iv9~F}K`C?TG_nTJHSSfI(x1VWGEt(3NM5RzG*G z(G=Bot1+PdSg=iXV}YLGk0=?4^nL z=7HLyrD&~+WL%vqM(OxoU19c0J6*26a`v5r`7R9HQ6N=sLR(B@yq|i22d8QKwhKJe zr~(y}^_qj;3eoJsbiO?RRMDwwigLAr7mn~GltCjZqBE z*+{>s8s7!w(F!HD^E%Ym?l@LW$Gojo*r&`hnM>Q%Y*a55qu$y?CLE>nw(qEJn#4k? z0#`Kp>cPNe04SysK2Qnqeh6mIj=*pkn7ElX7X@Y)YgC3ZzPu~gp>4LpAC$dD6{q{v zSqhv7GlJ`_c%zgvI6{;GBaCniCx zHz-(ps9Zb!f2*x{&pyZWRsl_{2f9TAYo*_bPhjE>x_o#7CPrc&QZnsQ9v#usE~lbm zlqqlKVQ$F)5C4ED1Mq4PNZ$y)YOX?m0OK8W9uNlRE02!r&~Z$|*r!wODwV!VSzyFd z9AmeD>7zmZvfzUD!7X|tr;*^i3Fdh%z-E=wM&(ftHHp2BfKR$}z89eLL;5A^wayNw z-|DxhEt62QbVb37V7sc++~Xj-DCU_6)M$BoXhC0EfpQwS@ldd70T`*-*zrdL`c3Bt zsvFN$$h;?@N-1J{cBV_bJt#i`BnHw}VHNnITrg>Xa()eF^aV+`xOSgbf4w8#E7~;* z>f|;?Az!a1ZDZSEp4M1;Y4oFYZg*A4FH@lZy9cZkr#lo88}(tzrx++@23Bj!57HLh zK?!T2sux`hc<7|nMAghDA6<^aQ-vlL9!=~8-dyT4&eo*q%tSz$v z6*_QPFMZ`_qyIYBjS$ST$H7a@P*WYembSwz^iJ1yM-6pB*|bE}tA}zhKzTLw!Je6_RhRB6e6jQLSh zyvzVIWD)AZdsI;m)bmHEQAJP*FHn1Rrmky^Ib9_vd>zWInqEsq!Kykatn+v&-MN)E z&GPF}w~|o*R9UT*?7jSHo1-~({2b;0^2c#923 zee@S@fSJv??2ZC1Ss6856{+i0l=ozmQ3fV_XVdmvb-a9Q9KJeee*Fqe^wQUQgGQSBs0*O938Qa) zlFn%=$mP$0u1C1bXPpzTYt!7VdLOG1?Cpdy*IZ@n0UoN^5h}TrR8*&p#2li}J>wM0 zO?Lvbn%us>zK_4^j4GExKlAqBmuhU#L}0xDbEO{iqXee;S>UhTzUU}$>H&_pNU%f; zFvc15>cssfYQL=12COImMrasmPf_a?mJuG_yLNYP=Ul4^Sg&F*t0c9eGPa;h}x4QLC{7atkgNhVwa zEsujNSGqK51~zK`W-mq+YJfZ0JXT?_wMyLihn zs0xa!>YiNo?kiV>*1;U5Nv!_?vxTnh>#F-{+x}^dx%oTSt|*Urt{$dWQ_T8Ws00P8 zn<6JkRj=n>Oy?lbSqFmK0koMe!7QxH_NsXFT?wi-1qso>(U&g%s`s8M(hoIj-CCg% z|36!d$4pRZ?x%A2Mj;>7k2{BI?*BRR3IR`P+of94T5sv6+Sym1CG8VY>-vGjAj~9H zZ`(I?ZZ#BhZzoK@qnJna)k{4G)OiiE!vA~nS=v%msx0DYJ5(8jsscCI3WCql`I9o) zTthQe37V*Bf1s@+NvBfl8Nftep1CFAeZscL-^8_3kXB8k!CnCwBP=J*rw29M>PCu4rvaYd%`21Qb;w zG*_*@b&AeGTGuysK!zruV=$eQXQ6zR6v0>_2CH*59{N`j74Kmi@3+T6tv5{hY?g6XCt3ek4sq4j^J63|Htc|ij* zj>R-T4JQ3x_7%c5I@*jkz&mCY*lC985(5GTgX4q14i_BWpHQ{;f$ln>*HFy%Q2nve zY`oOod0($EZ7e9I3cW-_vs2NH(thCk6ReK`UdwP?Jc^3b?%hPiz#s(ERDTQHNQVt4 z?LK2|!3Lc!YN;me&=wS=3cXOTkiG=i>YKB%Z&9^0b+at#cTe+|cLTHeD6l;WbJIY1 zqd+^oYX2WR@<1O{PrcjOL6|MZqh9KaawiM5QakYT|2wM=Tvb>X?MU0J8K{4nh>}|| z3x$J#c(7L`pj$x(RMrVqekMp;44!`kx7LEX8hElbohvCOPrU_wmET$Af&CV+W)36R zs$%amjLrr+O{Ho>nWjAJr;o-fRFVx3p+;yKhffDrQ!y`F0dvKgXARoCe}dfqZ~u$7 z{rcRSq<`S^L52O!L%bm+!DuD#rE8$>WDut9rjn}I2<;YKA92~R+nBeN23_q?EA)fn z!~J+aX}2wP3pCz{8Le9#HA0=pL*>`Q=gmP~slgR(^_I)E=BYY;J9Gf8RD?>ogCi=$ zo~ja!C=in?O~UMN0-Art{O5t%u289*g85J%AjbEgZHFpRl-B6DuDIw)m#l@D2Tuai zeYC~d(6(2rpEDja-3|QC54vX1wsbWx%fT!kMZdxAQTMxoc2{wXls87v`SA?+H5xNS z%eZwKrdb^7vL0lkE^~A?+O1`rwE|_X1lu(k^P@g?8S1}Hv`0~QNo#aXg~IMSU94_` zqIwyxL#WYOp8b|waZyS4_!DN*e2}6!t);p8pjR#19JR?EwRb1VLj#Z3QVh5UYAHki z=`HK;!%S4B7oep?bIcfhWn~?x z&f3Fr6dNu|i2hpcBinFnSc@8e0_CqAY29a(Lm@89cMi4k88Fg9wKoLQ^&Z=l#H&;f zhUk8s^j8o`DX6Y0bLYzncR{QI^Y$}T*@B>@-tAlhZG)3QyIsIi3uUec)i(i?igT+v z2kB>01{BaUz8(fgK4RLcWLRaOX6RHiPDAtDin&6a7ikwNW(!(Md3UF6tv0Fz#kg%f z@L3~Rr_O~VLA+x8sLbvCdEf1-{ACm`9nXWRe!xPj^+d7JW(-5~YKH1!MB7#kt%>TS zo5H7}Doq1#5Otrncm5zF6qM~x+b@MmxOS!oiL{M=0`l@ezh5}=%|M+Ck+(X^RWn&? z8z|5Y1n4+BGzV|AN=8!^%bn#hm+D8R(idn8)K>pVAuu2Z(@&LVmg=s8e+ zi)hqDFFH?D`jzMj_VmRpdRg&3y#pwQHQ#g%8y~%vN}ygMe5xOPY21G$)WYZ z0L5B41<3qJ&`!VFR5^!ZZ6h3qTVnp!;&q#Zsue(&8w)YplmokJ)5TZ)N_EH4*@d=& z!64fevrZ})uA`={P_7}4&=@drBIb}RkWa?)1kP`Dd2&+l+n5B*EsM~1-dzXE2?Y4|q_eH`=SQPu&dM_RHPs`A;&h1`~4wbFF+QdGCm;QAb} zuoj)a|3rP%&=#hnJaoUe3enXHxUX87x(`qjly3!pfHQMxOCAeOHO2J!gEG_S)H|A& zG>xxT435e5K%sw_y{DoMP65>)f+w@U$xUG3eXx2jaQ_4TDkihE{}#>$aVojK`Xb=*TTFU7x8g768>W+%Y;7bt;Rwa0IAvms`~{N99+ZAN>S==h7u*05DC(+am;( zrlEQ3q;U8G=&BU&u41{kF}PnJbXD$qjY6%^(z*yDm3eO3kGg#aLo{KL8hDg9XwwH&Sw~yi zHB^Z;sDEnPuma_-qW^dwXssDqsPo3D*`T-neP?_90dZ+1&M-w{KaJk$G|EVsl3g0) zSHKPpl<8+2MR3{ zL96v(x8Cxn79dMOb1EEIY9HJZLt8`ya8v;AZNpvSf>7I3a(}9%y|>0Zp!~R}BDh=V zFcf$s12Zk2r>e!ZQkaJqfrwGyd@^lDJwSx2MQ{dfA?{$A=E^{cIKdSh)}qAe@VV(twEm!-<+Kv3KV$G)!I#dj@c_qpJ;4pi}* zxh(M@Nd1a=eka&n33Hdm*Ics%iqLYuY^cagw314od<2g+vhIk z!f+hj^u88;U`z>cNyR8nk!Y`*`p*O16^`D0Y5S!!SNIiBM4za;R^|qQ+N~O@XdTe( zc1cI|)^ZQgx$d$e!tn^^cw^M#2Ov-%jnWhc5A>FQw1Nc{S2a}E%*TSwnxTREzB^w{ zOs9&Vks;HhCsBc>H0{by76@*dMY0L9LZT^VkouW8b%j2k{OR2@6zTWNLWANlT zD6cJ{SzF-x4AWFs+!%}criaIN10IUg4b{L+eIWm(+t=9v612%Vd4Rve>DT8Z>Pb1e zTu?T)Iz`)jMRsmWFfp69%PN*rHTub4KAQNF5S>-5bw;Ww zwL+_vz6D1gmGD(HF?}Y2@f|R)=&!KvR>Qnik1Jl)p>4Fb?RCmB3+;LB$AhQWL8Le6 z^&6ZD25uYackcj~EmdwkeG9yGOzFCVwl$iF;acfGLuvD9h$_60wp6|J^7EjAhFeTq z<*v(Mq!PCHNI~@~v^IFDuM54UwklL!D=U`$0Tw-hv8Jxz2vkW0zw1hHMN@3A!rfS} z8nXEfsIM)-EIr&{J^e0z086y0X3AA7RjGojxbq$b^{2O(tBwNSXP5~~P=$-4 ze8zx#^XYe0nX+6l-cO|}TkFez8iqxF2nuWNH>*Ux?Ez{h()LT`@Qo8HRMX_D2`jJ! z98wb7=zWi?czD%Ez1IiIW^*vNf5tTH17_~{|GyJAOG9^3^!8B+h|#CSJ#Hx5k2s!OJjL9uci(LTju)ZLym zRVpfH;VmO`kR~j7tfnag^RTK@f0d&bhd`K8Vul_*O=U1kb=lnlmF|t>k9NnxO1ou) zF%N6!+NXs676xK;`_vbxkE+4pPM953$$zV+C(fkv4$WVyA(-A1@ID9x+go7fC=5p` zNGA;jeR|O^`V6p@IZRu&6q2n?K%yZtxx5Q1I1)@r2RrTow;Oc!Kf-fw=A%pG zU)mCWfucG-o!7(dRS*X$%GYbB8Qq??M1AwT)E={1F-#BD2HOIdd-Z{HMi7XJ0G&F~ z=CKxh>JGMi0`V(>fwty2B8v+hmsR{7IH_qS{%Sfm(t-@>OIi^5!)4xZ@N&KUyh7P>;G zq~B9fcFCxw{;2a+z&C|*4SUq{u3)A%iflX7g9kX?-$6xbPFLQ-bWy?Sm5C~>G!7_7 zXM;wl+N$`KM*#yx=cp3EOdI@CrJA8aWnT@#KMx#ef)Z9Eq{0 z>%~xaKA_&J8hdAAmY7TDbT3qc<+S}&`7QY$nDP&_P$`?R1guxkyqWOrAHQWa1Y@=#y3{nt*$Jfo!;s}gyq6X>M{XfX!-C=6`cgR>6c zhJHHXz6NyBT9&y8vh=;dU{#uV`eq;_gtoTYa_66;?T}6!{q*lXq(7l;W*N*28nm%q z8#b>2_jP}@9s##13=pU2Jf4qgrH{1r!{PT8(@4+O<38x8Ik>IZ2>k;Fr(&k*r*?rJ zm;)Npxu&Xxld62Z=D=wIX4rX9+zfm;OP7&v!O$$cZ?t4J{20JQKh&^SR#^Mc&#*p7 zIEfj16qTm^{!R|&qdd%aeNp|5QLR)b-|MY-p(;qcBEnA}e*TQwW`iMDz<15_%`otI zFy7+w)@va21NV#3_DluzvEn&iUzi{Lg84{Q`LMFg*$>l7KO%J)fN8o4v+h%1sEqHY zOsS@1I=2%1r>P5l2Hs8rqugm*A|zd9b4f8NM)3-CSu=r(6Jh3v%9D-g&1_DzJQvmDc+3lp$MC5 zfx0{#Ra6WAL-nA6JF4P9a8G3}+6I)<6-~8~4%i7s>D2Xl1bC4Ee4lCn<%~r>u+zI- zBgO6<)!o6}fbUcs0j0s&f1ubgP+MWqSCd#-mvz_F9aL zSKaP|>mVSCE_2*?whM}Tw;SNNB{(+-$16qCP&2&aW}@!tUjEu)-fxS#-4sOj0(o)_ z-wpoh{1Tpnsx$`m`!IN~3TLbQFslR#%>m{6;264?q0-Nz1}~zmUkYZM>8L5Czz&Tv zw+C&Dl^+4;=(oZ|>JTXZ8C=#TylW$lHLAPq0#JJ*z_lWny;q@13SSO=A1Qw0%@4&r)4$ptHrGu^?R;;9Zxt%Bo@Yr=tE#=dxZ3 z^m*FL%8WxfbOM`I9>S8qVcqjpbNbB=M0s67J?oBotjW%f<1%OU8+;mkRPnv@25i^x zhT(W0E6nai00VWgoj{v$II2K@)ICd(R0q>dAJnQJ<_i_5iQ6$3YEF+-MENQH#wmb3 zS~3xXeZWE8P^nh5oyh|^dXC|VsOP4@SF37V1B7dlzyD*Xf|`T+`lkQDeN?b7j_Gc| zL*EC)wg=mFLNV6LSUc0jatkQ%12eb;xVRT{o( zFJyr5_Lwot!RR7fF)Rc1wHYXP2h&TDxKu-((Hf0Z8r0I7ciaa0slwgUS!J3YF!mo9 z(gb+sf#VlJzTUIam9YJmVxHBK`HulfTfv#uI2sRT_=i7GqsP-W`weQSO3OT*hMfw4 zmU}?DvNlx*76(FXohB+n8{I|q(`qeJ zaLqKvbO-_0-ZMZaEycbWz(JwB+zr&t#v4%`99#?@PNA)QU+`rCru|UVgGs3C3cWMh zPOL|x*8PXNHwySD^A>AQ8S@j&(~C*p7}{P~fSzk;GjpY_aYxK6pFxDC_+>fp^f6wK z;iyy2bb08A+TI!@q=E?=pq_qtyZBc6b=75cMu52r?;`G8QBD!DD;l#&7I z@OrhW4%v66i|Jg{kse@)wv)IAcn$Q+Sr??19YW2O**g|^VmYjv^qqV%d0f)s$R6%V7zctzSwG@V)z;zy-ZzyLBHEZL>qwcH9 zFHs%;suI~!yT;#HnE5(IT1JEYKD0eotmSBVVhx#MyDzBduVA-I!ALDY!^)tq31;eG zRAnEob=QG(Q)kQ(N~WkrT)U*0`uXDBvXHiaRl!FU`1is~EqquIs`3-mvu2=zMy~6} z6|Yru3QYtlT7ZShTH8?|O|@y+b&z-f+*GPvOhLsc%&P13RZY1tR@E^;r7E@}=8x^D zz4w5{ZN|I09(Ae`*ru}gE{H=pr5SEGW1K+azJCGA563}BvLreZEu<~gg1&iVuHxq>D7Qfj{LIX(;X zv!bcfG|U-SP~$Z1%gTfPewYb6z?j{br*z}B%^BHTC1bR1=(e))wgRqBC$Q}iBM*&0 zZS97N)01C{1H~V4#o~piI{iR9Jz)4%RHs|0B27^#4q&qC^Relu&)vW?JzEVW*bY~) z=NKqtNtd}DPzhW?|~1rEjx*7rwp~9ifO86yRZz^ViPdFgCo5vZGBraISvZZ zT_u5!etO)>5fz|GT=X5dT4R>YM&0X+TBG!{jRDUzSECY3`WI3j_nkWq`NtV4^lqOKtFh|3KJI%m!bjR?(%8mcE0Yt-au)t;)w3NBx$l(b`_KRFbPH zM{^#c)`fzabAXl7sgsV2_x-?9?L&*|p)M=E3mP~UZ^4(eZBj|O(FjMw;-LC{%wlioVy**CPn8Nw9Z&qV`V$rOON!%lXovYy zQMbhqjJ^T-7X!_P;B8g_tkQH=nZO6xH^i}CDf^)+$WcZ8t9v=78S1E`+)k}lGrj(_ zRzgSX^t0xyy7WYyRRCvbFK)4%wm~{-dg)G!q+$lu0bdV*h03^tmvL-4iW;m<=9bp& ztg_4GHL8iy^Kt?8D-A|X0uCj>XszXLz1gPdd$1hc(BZ#yey*w8V@lipXjG+zD6bBv zIt5X0bnUd!sFphRZn=r0R73DY@%%m>Wu_9~bRS$$N$H(V+x%6i!A-!}J($)@QSTLS z59XqxADEAh~SJlaChssgb&Wgm0R{HI*15Xt>=NwW0S%C$L zgWO+WW;#e#zZF~QQbnIJL95z8b)&1YEJDlZqQCL7>Wq0T7xR*iz23p7P5Q3#mmZ;7 zJuq%Aju3Oya3ySwb#&?J0G?`5Z1j$RsknJDX=)={Z%d(_BS5HlA%(=O_u;7`*k*d9RTTY;1Q zm<3fq?6ed|T7Zzs;Ib$9dK^ctHp{s#+~0yXsKK>xtZ2s#tsRL9)iJ@x4@dqh)I;sX zWt!5t+hE!nyakPS(Y9TL_AW0`dz8c>sxP&a5S=Y)`#vAFQ+3T#(>_)| zHr=%XWC-0yAs8ehSupIvlhPL$%gJrz_9{lxj|T@{`|ba~%(M zYR1h~OQytOUQIwP*+$#SC#du{sN{PfIt{Oj9M2TMg(jggK7sGG>9+TFF)I3&5vb%bpoMKs9%8 zKMC(F#n8#esGDw}=?%=5%77}qjCVwfl6nSYX3%D)Y4hfJHlb!0#VuOYMPKL_xDufo`FY zudZpIsXuPk5v>7u0r+7LY3&jr{$|;EVV#ARb_pyEj3M-RoBM%PiuJ~2XmoH zP+ncs@(%Rtq!2xs2Cgs0QB%wKYz=CX_RuVC#MTTN{CT<)M;APh*Y|m zD+uFtO8fE{m7}K|p^UfDDE~C=Q{RIwTGewNj8ZQXyfguAgJ`?06#Aga?&pAMq}tv` zr~W)eL@}+U?*x!DU0zMyzC>_x3SA1TD9r4Mxj?nkA{4Wejz{lCg8NNq+dK%hTB(~F z0#@$hvNhUbMnr(aU%(Xo#nDl%)-n@td>UPjYJ;>>;f`MgTvYY)^|>W;ft`M!dD{+k z$e97+wu5(?ml?HiEUSTXlUZ6%G)84^dq=RM0cfuh^g05SRvhd-&9xTZz*rISUgxm$ zDn`2(p=SQY(SIK1N7c0=`%rZ&<4CEGdNPr=2a3PCUqM1CMo!S2KGkz1M}ocW=u%Bz z(%jMSt~ZIq>^TC*IQ_b9{kE8AuVPm3j;hiW)n7?xs7yJy2Mp6f4N&B4ZvadaXsf#q zUHKA-cpCbC%5APf&)fP$%P2wPvEq zNAls8XHmt!fM~_;4OI}s@eFnR1pQWIV>VIboGe4zycpEasqo7N4ft-bM;vv?|%f9wg{Cr6;-kW%19HIrpvZ!yIZOA z&`KQ^7x$yf{akP{95Y&L{wxIZt9D{D9TKe9f)cmD7Cq6ElHkEuOgklU`Jb_J2XZty1GScm3_z{hnCHf!a$P{j)?k*--r-w8+j5v2ThQg&Ow1Tf)3bWC z?NV~u%|&g~3FYh`)TP3p>2Y9ghc_n})kFuS3B~DhPB~pc89LLICCeI)S${4FS1EAX z3wGtvZ_!@bmNh^Xi$X2$4bE!rn<)-vJE9`o@ZOz-I=zCnQf*K_6?OZAPz8)ppY$S8 z)d}UcjJ8_JZjV2-b^3-fjs%DFsN=Me8U%pBipi<#Q3d+|lks#uKTOxo#@w+0#3={M z`Ox+w4%0y2vwzTz_*%nv(08HAZSQWNn#(a>)81A4LTVq-U3I*!g4O&J>bD}o;VNcz)l<84lACvtAucmtUxFDg}LSfEStw<6fZ22fQUmaT_U4sD(y&cWd+7x&bUyG*ur@zoq~G z-dSrIsmYlzf-73+Va)X{$?1*2=LwF6`tbGrby*VX^&Rj{@$7kqwpC6bNN-QezN11f zfOoEplB?s^pR$-$6)HtcP+x|D$ErTL$7tK$lFN?&#H^+_;ZsXdyEKXQ6+Yz@gk@Dm zuAc{C4KeNiAK8kW1qVRlZ`xicFwZqcEz`9QA3$>@U1Up;tNm@hw&P*FfmbpZ_>#`s z{_&CSB~YJKOHS(kOjJfL>7Ki^22G9VQtJg6XNl=q6xH@Momc3|J+*>i3hIXXB|=9< zUBULKp#%Q^P24fX$t!g~{TUU%1=q>FsKak*`_TlPEJ#~q3T-83pptjfHg-B#uVER639C48rwb&9x3EuG8h@B$R_H!f8v)yeg<+ zx^}4cuq|V_Hd7}e;|v_>dettZ^V|A;kc)z`Wpa-YrU*jf=Gq` zacv`|wXQ1zF*{uYU$y^r@S<(tHZWre=6yZZ4XwlEIb3mGiMrH*wtSU^4AqN36(RqU z;JH%bS}I-k?EtL?>Y*)w?-oo8rAbqL#(mYjgCjxyDBAMlL95!}x)z}0U6j=<)az(e zDLas^g8k_yZISx+@XQ@lPFvbs=A-;|OjxaWH&c=~XhWB7`c0a}I(7`!F{`->#71p+ z2lXx9Ozo`6?{LiM2U=?6Ygr&E9#}mCCSSovP3Kjeuu5-5^_O>WG5>dk?y--HdWoJ)5L{b1s5wEig;fMRjk+6|v<} zXBB_5mx0g9!oA7hh$>}tWza_f*F*b3XARZqA$X&YY;y)xSLLY0AJnh~C=2EM>zW`` zU%^hP2hM7HJ^ufAxr>>jxGL9@&WCS2;@ET({Cb4hL~lc_^wWV9<>lS6w5^zf z`fN$tOO@Z0+O&n~UX~05|H5f2rnUTW1apcOCFMQ1q+?r6t!hVS)EJFttb)^Bg|1x} zRFbM#$}V7{E8e`P?Xl|A;6s=`y1ywKF{|n}R;spk9tEB%?L(3ow45vI?m@6=HF&-V zBq;>uYbgwV0ONrm+MD<@TZ77b1hyuDa}84XaqP8oH+@mg7rB$$K0J3#diq^jw zabghWb48uM3icnZhmR?a&3kaXw8vaE5+pAIOJ0ECaX5VUq1ucCt2be~>in9oKsr$b zv+8)%v>~XL6~LS)m@B`4EZtRmJpw?}x-WQWoFdwR_G?D6a5I9+3M(c#NK_|+oD?y$1 znC>clHaal$*bn?4;^?~#l~)zVOPxo8C!#9omqdM3Zpwebyb=l`m6BI9yXGq4hoZpR zM_}PO+TwL6j#`45TnKeP2iV48nks;==!lW7HFx`sx}fdkj2`BqN>ElL7?^?MPkB&! zJ7yhgP{I!s(Q=;*r*l7VP*eqZ$xGCP(KsHfKvi9jIaF5^FaRa>Fss}12-XUk+liQM zv~zBI4px+4fEqeR=cM9jshK>bLVH@@e|&0#IXDHx>UG}AdmbMQh*@@pqJ zpmkfJvr(rs%zwh>)X4-4VwxR7)y1csk?BS?0(O`xbjw!=X z+p|HgHlQy0zGrwV%&o=29p&m`-I{j>W|C^eF$K+Y%~dmPUO8EyaerV^1;?%+9Og>N zFPcQprkLN_;m9up-st;}k2a_(ngfT^sM<&A5^DjfDQ61kcDs(i4D3diaOIYP9@=9Z z*s85}`fXIUN=xtY!0!7(ZG>p1EQjtYS>37|zH7;%xdpSr8JN`td1L5E*5-V}x2K7H=Tp}=Ak z<_g`AS8=>UKcQY;rtML4RH8yY z`AgnLzs$9m$7bqU1>qY#;8>;Afjk^WiimwW6K4EE9bb>vPQ%aCNh?+FHn*#S^qzQ= z)$jWU)LNzKa+UQ;%EsSoQ5hyE#}JTdMZY)tCMj5D&aEcuU=P$MmCZ7`q0l3!I?4s3 zo1mq>5i9@yTCDPVRzHVw*CrRDEZZ{!*sP(8kABKLS}W61t94MzbD}i^EOWvfp>Mty z&d02N3-hjW|9uALe=AXDiqq-Im=UT?MOD@(sU{9kJ?I#VvQ$c1*n;4Bm>1rHzB=JV*YKMcfFfEqA3fj^ZT>I5p(-d|$~*#Yy}9;MQ?OR&jkXH! zTb8KV`gYw$6YF#a)8;T}q?79YFKW}bc*`qdmWT!ahJqUpK=Ec^;A-Hjy}R^D`W@H2 zWb0)meLrfT4^>gw*uw;j&_`Nm z+x8xecf7XV8(OF|odiqhuX9|iQTF=F(J5M^>=&3lI|4H=%wng&b8Wb-*MNC?7h0s~ z+;A21Y)|l|17?F0;C?|&0~M53lfeev)hl}(ew~1U)+0rkH$cI^zY!SN7(7;$+N>p8 zxfNX3Nuf|Zlz%p=kpt+E4gwUmu7z-fPRF#d21^TImUhEYa2?9}BWUkseScA8Lg8H+;jZ?XzhuT&jL9JzrUUZqI+O+W>IHrX^rX+r^?+CoK@24vVeRRTeR+vrEA+^4j&1At54Bu9}i=R22ErL;P`|(8PtuVJ+VLn`hT6q?DR>quu0TgrO zvQb*;@@AMmrNFdFAR~dcQ9D5q&938mus|`MbQf=GCK#wq&Uh{kn*fxl@+eGGGF7Gi zdO4KeEmXP(_@t^5sb@P-hf(5H$8(%PeU%9KDY*%Hm)x?zBmE@z8n;I=}3vi|28 z8>8s*S0}ew-7pu7$I(xZV5%~*QXiQ;2GrBmu{H+Bq@Sp+iilEyIR0tdi8}zCwH+^Z z0PV|TcGX9ou7Ekk5A#ta%(q3P^wO|Rqx4k)H9rMP>Zks7o6&jN6>vw<9$FQQR9e;4 zx;3~1?rjArHr(l+jW}#4Vn%DS19e08S82Oi3rw9xTiS4tteK3~1A1%*n^Yo0^#4;j ztJr9uGPmn9jsTU&7=_Oq-P-b(sCh>Z_vx+WehVr82ZUm&#*qnh%l`Ls1GEql2Kn($8GxsEar}!coiCfML%u z4P~A(2gk;(p6NL@sjfLWV18PQGE!cise_uQ zv%pM$5VwW47?t(birtS*Knb1KOjRv%V=#XT#Wn!{zqHk@g4)*_l(>LtdmFek;WGv) zQ%*m|(ReyA9t7q_&~`lnuYr{J`TzfQYOtnfjy^v2FD_H%t^Yp!&-#K3`kCnIFSM24 zh1sbOkN8c~IBG0y73$*MsPa*KEogd&w#KHYmhZr`KfqZZ6{ITys)I86$zTa>@bxCs z`IjokP0f~#Hn+EWe|oHho~;AOTy4@-l2DaL;h3Za|DfqUtcqYZ2i15I>W>b}A=gpQ zp3s)N5oFK8T&u_KsYUyseQ21?PEiHhljTA)&E zW(vk@LoTeEK3<#ooL{IGr%^uID2!Ez%hv_-!{`^Lds)#N)vhCL0~|5m&jT?^v2EQ! zM_+JpDcJ2wzZ1hzj(6#@{vyg){bnk^8>~jH(HCpSTVy;$D1!{(#>06!- zSHZq?%<0OhdzZmnE!jN%biRiNo&9HE&es-{ULJL;5Lj>=99F^E-WN5h1*7zFM74QC z+ugog8+MDfmrBZ+ih~#hZsKg(Od4Vq4g??Uz| zFKr9D14k9f6P~F0s;xd#FuReDzOl<`Gtyn9zd$vO1E(|*BR`?KdZXNGJoJ*&j|(*UegLNuO2+oI|qXaYFs0_?Ts!3RK{pA0aq z6Us@I$jk=izXgQp#z#HI>!u7?rVTG6kG9l)sAy*c8qOGN{GC9^5+=>SCv~#^x`nA!lxvK`3K8)I?M>Y6{ z+Ne7%w+PcyH)(1Dmj8bNrb~TifRFk}6JjWUpZCkNEh0w{XlJ2Ox{%)`KQ(YIs;`N4jO&{ z!wlrT#$_Q22CK)kUDHtSj)C2KXbV@BckhOJp@U;9P1s>QOtJx&{nY@~wPcIxph`YN zl~X9M8in_=rug$v%yoJ-?yT|}q}SVZuW75I&+yjq&ax!Rwv^OYa4`h4gE{KWDpaKs zs0=Nrk%G`K67@)xFlR4ARz41c|W{s(MJyiOYL)2s|RfS57b*t z+ba)nd;sQy3aAWqHarZX?ZGR()!kAsJZl5`xYDJShBDCUvACu)Na^Q02D7YYZRj@8 z>^^Oc3xasv!CS56_wlF_DxjTKgC*KX9}PnNI)gWQKIZlyP`fj28>WKK?{Fkr&^9|4 zl=h}=^-S8X4?zvwPh0he;Fs>eTETT85p;YHHtCzu*i;;Dy3;9|x@-EN8ez0G)JFQ^ zH!#Tux%v`rmogx&EU3^2M5*86UwHTKKowaBZl1^VR!WBGoVHUZ^7E#c*~+(rKT+Fs z+2E_{qT|9PW%qX-UA?PdKGpEC1yEyqF~AP(t5;Xi*8L-Rt#xx!WR;thCwSz6x+~2nawwZL99ErDZET+BQnKKpg zgKnbcPe3_uz+1~7vylp8N3G?rsi^Zh8a(mAo1qYGqaXRtI*pps1gv<7!^I1ARAF&e zj~bwPJ~Ry#r{x)zLKo*ssLTgAx@sxr?4ZqDL2X_IM=NcWEA&JoH8~$1VNP8R@-^9^ zZE1@bhZ?9FdsKU9O%0!+y>`+}l(QdqWwjD@`4QggisIs}!8Vnz#X57}FAHvIRez+R zMi=ASq3u!KowznzG2}c2Fq}%0u7ksFre+oecK& z!kqgNW%LQJQ6{F17P+cUK^H7=RQ`xrK^Z?T{Cz_$Y zYhK3e!u+O_dDlK*UOU>BD=(KRM30?Cm9@js*$?HVm)}R4(~xnX-B>U!4wO|gz1G}6 z)*PhW2iF|HU~SP&l(psbls`9s_GYMENMZ3qRwE zPTKu?7s9Nx3G>Zv%%1wRGOBf-OVQ@u67T8h;H%PLqNe?MFC10OY1@^G`k<;ZI26-B zyV_xONzxM?*TRq0SN1XgUpEbJxPZ1nlTfox0Mo*lEk^){E%ZC8%Gzq9pnc!EDHxjo zB7cI+2;e@8eg`U|UT7o88i{#gF?giO3Do+w)~Y_t13pTo=|jQW47{^7Ku1+{+jW?+ z*D;F+fw;4@O)iR>ul>keb;zVKYTE!DtMw)DxsI5(6kI!o<2|k1a?x9-;SkJ~n){a1 zFbgYk0!E;E-2hH2KumA&pK4S1GrYxAkPA0t&|Jmj84bF`65Okbc|g;dc?*=!0=Eu= zqCbGIKFv{CW}FPX6~#;S8KVbs*~oj~vg-H_3r05c!t^+fSwtV?u?MqPLBhgUFK4^g z0&DH2{zLJeI0ue|W18KjUk4?28_h=T+MuCoN$?clq6Hn_4&|v)Lf?RZ2ed_}qrB>% zRw|tzDU|Oh1NK>gJ*6>A>ae}}4oKAJx*P(pRc%1 zW4uRIrE-HYU+7+vdgC3`iME64yzUOFS7p#z$JOjUAWZ$n+R=7Gr@20xL1IbFE~-f0 zdYEYoz_{tOSt;r=Ga1y>p0>iTF(b;NqK|@XRXB4MymAsm@7ZJ z>xved-B}7uCvD(?|F4tAs5dIUGhTqk+NhT2fQnndFMY_V*X&h<#4!5r^tFIV3sx2m3Kb;8H8R?Wx1szlv3tRz%^tQct8*SEcn3?9N zU^#|N$8q;1ST~&UGW2%mwGqdQZ*(c6nsYr9bGRzV^`jtDD>(2iZSysJui}_9FQRU( zMitLRxht}-Y8g}QfrZxc!xU5jKU8I{ey3D$U8jP#Dl&C+9%`aM+SC>G%b0tq_XF?i z;lNFAcNKJ3Daw7zF_@E8>g%g~HJ^p!d>@pPFPM1(T>ea#|Nfusolu398fANefr<^Q zxpXm}3jS@x>!$mgeH9q&1F`*a+;9OQBQQIw^{(Lm98{6tGn8x0qj&GHm*cf^P;U;E!5<7ApRX#-JZ50<4_fv(Jw!-b)cjA413zeOMV}^cx$z>rbOLuzsBi_KusP1i0wcSx0PohRN25-{;|4rO1 ztxacrz*yz{c^xcH3;P_di3x?^ZnIHAGdnp_Lt3YT#R>MAIy{UfTKR+W;DoAMt#hu&GR#;zX80{^VWKgMGv?HT+QR$}YXVPERvHzs3_Q3GYAP23G&zrr!S(u} za!Cfb|A5ZXDk!c8K%yg#CC@;+5_kg@NTn1sO*AhLn}M!cRYxtisWzawI@8Ag!aS%v za{q_2JcDDu7Ro~7ncMQ=#b%+bUIP0SU{zPJKpW#kB~#JqAfYh*e(DtWcnSDyM4N4E zMln+9+j1N;qA03Z0aR60?^;TT9G&`q>+wgQ2JU}oyRB_8IE;SdlThz9C3{<9*4Dgi zI)~XnwdvD;m?M^ed=;68UBSj9cptt3<1KJ_X;t%-rVY%1_X%}Q1~0YUT?+w;Djxm{ z+tqJDN1c9J&jN3B@@%bQ>AeGUn;iYL*Iw0UwCRImjm}0Jw1R6jRITf@^(%<7Qj|Qp zPrvPJfbR?7JeIcjaFE;^d{kQPxQe5vZnCI;M0x)|##J4wE1uI; z&D<27-6nxQntSI}sGM}r$py^VMVp}w{o3q7nb!gf75q(%Y0Ff>i~Ns%hE*}w97Y92 z06(SG2KBp|f$6IG3wQ{!KhW=)X3b3dW!>6f@)}U)IQ`lwCKGH>lZVsqfHLLxQraxt zP$#tiK3;@5OJ#0!36w`oRFmCcZ)f16_3wH+kkc z<_v90m3D!~y4~eU;_;y%T|Y9aUJ8|>-!Z;r3EXw3k)uI)Dsam8f{Jg;we?j%m(4?sQ3&)ai{q1SXwFGYf0Y(9J#-tDxdys}$Et*>I&&rH z*1mnh%sq+<*KQDyjoPJ9o}k0d;{m8E6L8qJK()QA&Kl~gN@O8jG0qFsN%=8F`MX6o z9(D_4#?$s$CpR-qos&>a2iA?va14pW47!B+_ntQ2m6&^)f^}M+zfK^y9;RUk-dif+ zM?6s*9s$P{m@AEd*K^>bT(C5yv-?$WYAncA?%&rQ6<87!SWlPJI`$NqgLzBlFnxwq zWz1qfP>w24F+;(UsYii&JojXP#0B3EHC5mP{z+!p$(df`RFo^ z8v27ow^-UHE~f24P0U|fo;1x%-@QS*)b0E(V&LP#*FiHX|ftbEX0vIpSD$sjU4@^*?c)(pTP{+33h6V zeSWI5GIUIHt}rTxxhw&A1c5|Op$0w#85(NjHq;-5%F5TM6uri^--&tnIOd+> zJVNgmv<=X6L}h~KZoncJ{MJ^PUjy|98{@FwAE9lOkV(sy#t|Z!KSTTvFJ0(r7q~KxUw|@j>>@M z+TR>!fZ}$T?j~Sx8fGa4O{7NN=Zo5?jq1_}%q8PM^FNrrdi*ngFte2V?pMGbJ@3V7 zpl%lspf$gK3K)%}b9?|d>EjPp=V2B|$1(XLs_i!or7fY7=H6{KU8-s;8ngfmR;YX( zgUaj#rj)^SSqChpfLr?3+(OxSMLS8oFLcS!TAtIi&zOMOLWj269;kz=8*4A&7=9MB zg67_#5vZc-=;#5q>M{$(?k~NLtey^{J;3FyVCFe4JG_~G4-CM&gP5;XmZmCQhE@RA zRgkNX0qttDJh^eSS$WeXPvLXP8DuM`E6CxbB(BgEHAmI#fbV*&9$L3+OTnkXn5*MZ zK{}wBM5?nPFw>b~mM5^+roKN2Z-x%IyEIpoHQ6&&zTzj-_Om8xNg>crU1~SM`%5*) zG#S|H!PA;7vZ_^iXzi*Yjb*J1rUQGq$M)m7!H+K9F>gZZG7379F}L0i31eRiYm zjskAKD%VRz*l4}-7~7zpwnz1;%1}R4K@!h_^ZJodf-38Wr}_*RFlwnBN{H>cm-ljH zs(=pGQL=n1Oz$ST14UR}AI$7Ic-sV{YHDS&bOtHilD3EQFoU$Az00O;U^i5*4ii^& zSF_zg^g!Cm=|~r&kh<_1ZyO!T_wNJdny{mzakSEjC%hrJ(;RcSPD`OGWOWMAwn7_U zhh>-s&p`ema7vwnpV04}idIKk%vxK(cO%+7zN028U5xMIEvbWuw=cKR>H}@Xb(;HG zmbQ8y)g>9Uc~8IBsi0H<=F+8jJ6u4m(|1{wHK%*tNco}`D3sraf)D!fP;h6|0Ux}# zbz&^m4YRt2Dy}QWPr*#mVXRjpP*`i^r0sKz_TTC+!PVa&R~hg;1ociQ?(DyqZI!hh zRrzNOL%r38mZ@y4{}LYLh#v>8O#+8>*Hsh~b~2CHV{TIonXN>)?uxpi z39#yk3Lk+gs5#oAJ;z45ytoUi-O-j| zr7CtuTX-FL%S2&T8wv`AVh%6LwSD|C{S?PBimch%rCL4%5d}eQ?G}}_LFFju55@u$ z9n5~-26l?~0lA>BPF*(MsG4RdV?z*s9PGbATl{`dv@vF@t6cV2RrZO_rDxiJrn;+W z?SK1iK!=@lF;(ZCit;CmFdvRXb<`nyPaw!tV!eC}Iu^qbVT~%H^V}qDGFOjcS{Q?w zt3Z4(ZNqM%ZtVtdlR)>rz*^tBTK+?&bqCD?>F28GP1N&-X!y<=IZ9iaWfhR(2DV%T zVe7ank4%)+3RG47V_h9o3%iyBzczvGF<`C*=&fG}SYd=pR)9ZN4gR2o8gDAE4yShQ zK;Rb~jg(H;dvL|}%BcEAw1scMe0dS|`8{nf^fJBl6Kb21ci=Tt6W>^ zl+YJd?XFEn&DPx?(An+QCa|I{FzruUTLs8EMZ{J|%y6Aro9X^;YF?Hf#o?|q{3xBP zZtB)Huf-gukgurS@x2D{w*qVHW8TppE`CuE-rr8=TMnq4|8RIK4wfreJ7m%3tS7&u zvN~M9DO^y$8C_Uc%+*8;%L9Wu;f+wNnbg4hRp;=o`T}o{M!7!~-1z@j5a;RAPg`l! zH`+!fpc?q2?kMi-y#fyhV&<#v<$7cG(BA2)GmmQr+N$daX}CV zQpNPWz8+|Bp0;VKqu2bwes9`NX%Zcj2A}o5_*uV6GeJAjD}U7QinN{BhZ!{hc$J{v znF#P89*0FY+SZN1d>#*GDl5*l1UFQA%o?D2Yh;UB;Ff~xzN$)wjt(ZLL1rD`t_}W< z@;5=THcn+fyCkUWh`B+h;LXa=@bR?u7)|GBCDV`xp!saf8*5NquAx>aX!h#U{1n;A zPf;WL0&5+LYu7<7Uj~Al7;lfVr4X~&===udb+zDD} zatw3;@ixZ{XbOy!moHj_Tk6-S1!$wg#xEVrI#fg1IHB%o6Lit%Hr~!C7xnJ&M%VUN zWeC=5u-QSB(^S;Yc68aSs@!xV*mx7igi$!W^zu7jIw?Sp6Q_jw8#%tpKs0t8KW>?Z9^Sz z2S!)I?D(6@Jaw(*B~W=Un05w7)pB&n(?mSd+~?~E^kf>|E|w@SofO|rL`_SepM&k}l zCJhz9y%jklH7_-_07+WBeJTKXD&{2~fgY-VTa-Obhu}@C4X*0}GxyNuteV(ENa~Ck ze*<(4#XJ@XqLrLYdx9Xl$61i2P%f{^dP-Sw{v`OVhZ)rn6{lp6RI&5Njc%F8N;xni|mr#dK) z?rMvkp-_3Nmzn?iWB!N-Pk#dg-FOLIab+#$Ooe>cIbhNfFi&B-LP)L&ezyhosdRoj z3EWlDTCX^D>V@M>H`F`roDmu&K#St6^_{pCHS88D{xj;lW@A=wFxY@AnoL3cOU8S5 zK5DAIpNZDCeL5O5Ow;b_L))F|D8I$P!3o^_|AHz?wyHchX|B@sfCdLaAH}Zac+{8@ zTsuKgyh>F*vms{rCn);_+G;lj6SZGUwX$$ngbP1=+c-bJnxP*oeE!gL173j=m_7=Bb1`yV(=bb|VA zgnFqT>90~mTvRPCrC?aB$*$*u@*9Eju8o?c8PC6b_bKS6+NuQP~97#`lwVL zt_n7PrENkQ>XW`axI7D0Ql+oJQOvJVnBiKKp06-#D^#}X>zWx;xV1W(uq3@)Y>xu% z4qy&FNWU}nK)@u-F?#VEuAJ_rC))iEwKf-wR~ZSHn$s0!R9Pd=fEzkToLmW-8PjEfW@yp~P(ksMtb98)h9_^Ov-diEhUaB)`3Wc! z3MO|1b5x|a6k&k*@t~SQ>X{Pub|X-w7Xy@Z#u2ILaL-IzU<0cVtr<22qMog>2SK{ah?7c_iD1+bSDFjQ;=HAmIg z@ay%S@^&evLv_@kDyUuB7Bh71vg3^6qbLcl4aV8gWnn!WCsg6i$ABVQ-zZh(z?Q%| z1?*8l&Qd8|?gw&=!7**+;g1-=N7?hr2DH^ggy<;l<%)Wty|H>t%rE+ICkxb{L@rD1 z4YoAK{G`IuPvJ8|1^$@IVW`reir}e;-5&{V48Y87jAOxUHuDIO$A*w8%}za z9u|P=G#y-dM!yc3sF(Wct)D(T*$yn!G!=?N9Ul$;o&j-jv;`<_n8WBiB^c8+CLi+J@_YK#`_1 zx1FNnk|r-BfPQmhFsta)xc1;12b%4wh68H3}k*8g%9)DcyQ2deWEvcVNyTTIJmZ_O1`(^3EF zv6nZ*FA zpAc|f^?Sn{aOwdF)3Y5i0=WrX(PAsg`!6b2F*{T<6bor8oYVj2B-`T)GAHHTOj`;;p2_dLL+BfD6!HhYLdDaUxc>s@Kt+<;o1{BNz zA(O#W&B0!c*GTKpaz41A9chC$0JjUM6Y6(Dqr`op?UJg_1iiY?QA#B0j8aCgc4^Ik zS2QTE&Aj(-9J@!+C9n*bmjI^xz)@TiQNJ@7(*pe7PTP2O*;W$V{R7%**3wi%+B`v( z`-Ljj4;A|zG*i~hQz9faN42aA+9`(eb;Q`BFMVFN2F7i`lM=LD*n;xXF{`|S!9>C8 zH4vO03wjp>VaxC?38vqaeAKZl+NNscOSa&r;?z{Pu~)%0Too(t7@f;E!BI#_;=YPD z@0+Oa&fvlpFfNI`Gz*8w$i4=`21*-;b5vX((zdu^Cm5TdP3YrU=$=UZoe@$J_SlagZfxS{2 z6r$f!z)zV!mBd5t0T&fN=MmtlR$+%Ww{7XD%6Gwr4q)I9u<i~q*uk8 zug*7hf2O*2rxQp}0r;ll?4!>5AcbD%`&FM%w7wbg2Gl^gDk1`u z`^IlDJ2pVoU5^^4&HRMswAgw&SJU?p6O}mOdTaWu-0!9BE?x^-*b~fd558T)JJb-z z7oF=9%G2g(2EIN7nKi(c%AkL7P(?F&Z#JIj(&~{vbDz6DEUIC0f0-7jPA{KyT9U*6Hu5!Xaetpc=KT%cBg4f!edlx{h zbpy{{Gt}5#sMceEpH5f{^`@7i)QDFtsjU*ea6GDM7V4X(&PM02r#dtxj|Oq2LF3b4 zBbmPtSX&Dt!T69#&p^^($>fu)O~{^U#nF!9P^w4B;OV_qC1E?iy0k^ zs(lc2xemrD8y%Ha=T%Kw7~Hs&`Q@JKiGRd-si6S%M$>{B@Qy{*oj=={rrwsWOX z&WllnhT!<6ds(X3=+hANwgpBDY3pj55Zxh%8*tHgjS+$!)&_PDoRf3t$2Sc;G>s? zE9+2ZJ{*(CT#H!P)o(*w-c(PA80Za9MOrfrk<@w8m9jeU?vo50zN6SSEk{uug!3`;xsD{ zwOpr`Dq6t~TDJ?Yz@9~5Yzi0`3%+l_TSd#*ax3cgCSYF|b8~&vzwM~eni7)-n6?!$ zW3T?CdzaJ*3rxvCCryotF+8G2$SDnu)|RH+dr^wwTBK-K5VYs~*~bl!0xeqS6n zGLlh5M)qEjl~6_{m59uU2t}l98QFVgBqJl)l*%kAt8B?mwld2IUn73+&+ni2>vQh8 z&${=VbMNz1-0g$1T7^2>9AwPJe5&{8aHZ7;-B1fp%pscTZ67ep>nT&(&{jc1Qc&+F zC$)I3)iPGb5o}e`EmO!}nhpXR(AIr4Dz7l;mx%eJ5-1vlxl-|0)e_~90PNR-8w$eV zr*S;iy5C7@m6{5I6;k7qP>DL?&?Qi`78t8n2^)ogz4mqGtWdT`!7=Un`fKgEeFZgL zRlZg`%&jVx#@|4eVrZ=e=z0;;(I3@Vx8d-FlU~yh?{UC9SO6RygE>=^{7r-N#~&44 z5d`SWD^*2j43_GNYOZ{X)NJ{0#T+AesEf4^j;6|^V}(G_Nz7Neu4!*jO4~B$H>i7o zpoR%%W^q*8MxeM#^Se&8O>d8KF#xj1ONk38i)Ub~X7!KW`PwbOVRapImuf^p zFsjdbP%sel=W$dA)!1=gIq9Emm}hkdt6PEhKQIG_;l0%c6{R)mvliyAy+CCJOD=^p9 z!91bWU}hHT``PN^v z@J!p8r^=ZRdbVsmLYrK$Otb2905wy!?z@&di(+*Ct59w^2<813N2a!KDVpwWg*kI4 zg+Sx-I0keCuL{sMcn<2F;%Z=PI@=YLSDV>LU9$Ccj#y9uv!_<}Uv)9>+{Y25)g@I^ zc2i5tdu?ZY8lo)!Uj()EI@ZJ-tDnes(Q4pb6?4~4P;NTt*9^pHqP}_n3%%kORuXqq z1qqsqs@NWNeIBZ|R;GIz`*AB#HS`0FiwZq2-PKI}I@jVEm~Q<+d#RT(AkmJKzS@oo z7>PQsap|KHdDe@=JT%1NzcI^|MRiww$yF8bZUGkF#SGQTVpyDI4(=vk7V<|8ze~UNitObhFb^!nVG;mR$6=n~H&r8SwR!hZmW|O2R?#5Z2cWjAjFeI^_{D-5$8dC3V7hCtJC_0Z8K9c7 zXH{j?O?3|Z4$3G98*M_>J%lP`iYm7Q)kX;stGCa3diA~3LQkp6wRR+3o-4S%sR|U> zjhU)5KUT$zcSeo>1FpJoL|j{x%~mjK4gCUiW;d0&+P6WIB^)tU^>on}%#QA$k1bvN zHC9Cyfxv9cM@w)#(_Wyy=54o__m=uvBH)Dko# zb9;cH$3fZdIEGH+i1M?*-gTJGhvNv=?Dy#dW`Dvw-41oc8`WYnC=`jgC6gmg>0b`n zq7Z$ru#JBWR_ULSY;%Wxhc%6RpP?!Qg5Se2KWX%(iKx!1i6xv+B^RRx>WPM`m>aAB>x*!Np%d!8))e^{VZoh5Ngall-VO3S9~#_TB8zXgGk-~ zKb3`ey-wB8owijupIIMu^ge3!4sc4-95s-$EWV3c@D@a>cA2+9<*QzlQnof!X8J9{ z;hlwwNkSFa56U#)SkrE_Rnu^<+2jhTGg&=Bxae;m=C*v{yo5fTVRM8hu!W2$|($gc++-I$NqZ`oIEl6s)TNT zLzgd#j_cYIRF`9wf;6!f*n1YoTI~S}sRnmZ&2%`8YNRAusqtHM2367+bz8M&`AtwK zfLpV1#gU`Lzp7CGnv6MnGsx`+&NiWKXEYe;f*FyBx}>@{0YN1U+&alv?Z zs(SwDfjV^(6}62nqxIzNU!m40Nm^;jjL)IQd(zMI9_qY;b+Klv*D!9wqJ5yJ|C3966ICa6&hPp%M;b@Zz{!@|Mw+S>jfa#QvnyhLO7J(V3`h9gT>UDS2 znF^>qTfrFB$uD z@1K<}qJA|)z1M!OjbiOmBM_#;OciTKZr~_#617Luz0?ww^&co52S!f<%Y!%~bTMj$ z9@_dc%0p9I{|d;~?S>SmZEgy1Q&zM}qpi7a_q!@Dfpf2cPs$4_a<$yJ7 zF<-p{zxDVA15gv2aG}!8QGe9Agd7n)QP-QGs;Opsb_7RMXnUyNepRkDx`Tq>z{7!{ zbqr`!le=I434ERaHmmc`Ibg>sj)*C%eywm!h{nv<(v~xhwuu@mZ#{IK+q9)BVjnA$ zQ?z4CQH*!qKwC-GgOGOM+jJ14GVFMmF2+2MXJ<;hNCPSfy4!vE?>Y!#r+=b+>I2m*?NsL)QWRbDKu5D zNi`PHWwBnOX8O=pN>jGi7BfZR__Y#k3p7H*72~OW!3?6z z*@8E}DXOjpyS1wK5N$-pcfefr6XogyA|8QxW58`cj*ZfWWndq=gq0&yZm&aG-=b}B zU)1t*ba~VOm9~;L8*7xsK$MrZLchBJ4@KRyVj!RZXygj6+JVm+jVg;dLFQ}Ju79*W z3q?&!5j8y6ifM`6>X+ zQ$Ob+v<+MaLP9{grm?|z9PeoUO(6Bt`>t2F3&z7`xRN0)P)p>$at)G^*;d+rURnk4T zK)vlvo0;lCWxc`KDxN(w#64ewg3EC{H3qSosKCKsfYRPt$=+XOxR5Itqycl(O%^Q$ zE`P*)8-W_4`53YtbF);WGS6xgc&d2rswKfjtwVSpl8le+IfrSZeU9=7T zZV7Dl3sJR=XRYm%w18wVmfHT7MA~>=dTnWL*~~3 zc-K||-tsPgh#FlS>>LYjD_9-DQ1B*}twXMCZ%JsE5YO>PheHgG<2wI;4wi@DUPQY2yI6-UP>oaP* z$oUStp_(eVo|gb?GC9J>9fyM!L&r_13cqliZwhAWhJ5PbIPZ(vtIcuuhnPY8z?R>% zg{suMj|KxZ-J5jD`ui~>b5Ps0!~}KWFw+C5(|VZ9;tbuGd9=kS{jR85Bq~Z=wf)Fb zEgr5ZGf~oI>qR!H{8N=KMt!iA5FFU0EzbHPH`ZauqK%lqC6D#=0p@FQ_K=SIPJj2r8Z6h~%4K zj%F}yGW{O)1zY~nc2haHM-dyTOb$_EkJ6Ve=f^15d*Fq}K5sbq&mClD1D`W=X{m{t zSD(YIU!%_Gp*!0F>+4|rT2NHcnV~dDTL?Pnd`WJosPU*tzc|(~3N&!U{7++0MEUVO z3iQ=fyj8B+*7RM zx@#m0C4wRyFz+dy7b{NBs1~nQ#=mR?`YC@S?NFQMg12`uhYdt!Y({-mJnz;H{(u${ zJN+a!?LI1hByG`ez_P=jw<59U5p}7Fxl^^+Qjc1E4{c{QqGmQljWS1#*$2#ufaU{$ zwRR8b6Tqlupp(kKqYC5vWDs$MOa5MmTIUFQD=RiAEDq^6pI9_iNVf)4^&)X-6v|-@CoP(aT3-sB)hhl8lph^c>w0U1@(-bQ6aw|;ffC7J zsfIXPcTiXl{ro-Zux52L!N6aqu5_cJPI<1fp)5EVgeyf=d!A~;9F?taiv0U4F(2s# z+ocEQHq|L_6`_L_QB(KgSX&+Crs?}p56ss+ICTQgH57+c5svCJkxgq3dr}ZH?G*^@ zz^(tV#9^ze&DFhx*x~pcf{M*Y{acE9uOjrl61dwP6xU5==-KzG9CbGX#g)9{71puZ zVVUkn4b%WEm_z3VV^C9u(XVziFwq_GZ!i<@6Y0EGFZ*4FVj8UjF^4cW=}jO`FNg*7 z&?9yN^VxW<&jZUd;G-pIbCWJ3m!d{!Wtcn{)Dk*rjR@4%HC^FVur6J`1c2jb!9``9 znMUolPC8ZjU3wR72NdANr=r3%^@p@+>hc`#+i=i+BW>+fOnvn7`{6j|c@@}{cA#5N z9O>G4S5~4rXh&XLZzVa}J>J)V*;EFvRXyF6qn&zz&0q2M)&kmaFGx$L?StZJtM*0< zHTDZ9g9TH;PVLy9Y)1{yH=E_jD9;PD9XSgu^i8RPZf(tAlvN|VJ~~0=CwQ-`CY65% zOvhrLIf}CBPUkNT<1ilRQ9q3!T+&@2Va-9lTbV&JI{ zUFP)ym)$Ts`ry4DhnlGieO!Pt9tMUDqst$EREhaGekg;TG-{_brdI-Kv))PDd1ZC3 z6Y9lC+CJ$0E>wGusgH0pwgs(CK}alZpFV@%?SR7(+D_I7k5oBozN4+GcCG(uOHfFW zeWnzunid78As{mu%=5)zr0P^fQ&vplVy!vfufo3c8aSY9B*=8vMrCSOyvh2>(I{1& z1ho~I0hX-5jMYfik)vliDt|U7jWVS3SS`|l6>tRUQ7^4Q4c3k$`KLst{-s%?Zpj8t%Pm^U#y8(rV^i4z*o7*>%c*4@Kxw{3w_(81v;@&{O#~L$$w4 zbI>de)YQxV7*CY7me*lgxc4Z$BUP8@s@iQ)Hv0ZRb=J`B9gq2RIcI*MDz>aJrt2(u zDP?0?{s9|QWqWH|lra%irx_3P^8artI!k^4XrY0<-Wb%!sS%L0#Ia z3LMhdk5>NfwV~~~647l5W|lSr>keRk&`f8y6kI{++O$oG1nsJD=Kqe;R>KTcEt|HF zM;v#QR

      +9F`o2)azJhMKO>JFJ1-*BXpe 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 -Eq=}yp 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%0DH@wH4QVJ7&+QLtw7TVUoZuqoc? zYdfHI9(22Gge#T-Li#bMj``ra&Y$8FY^rWiz9W#u2dbW!E8a7mW{X!{;*xZWP(NP zhA!?i*rDLSn`wxn=VKke3bx7123m?jSn^-!lS>D~;<-4rQzC9(51Sak6-j*k-4D>+ zT!!wTaUR6v5ydL>qdV5fTVb*74nM!bF!MX`y9i=lonhc`tc9PzLbYY^s#%DqB4V9f z8n%BM&^@R_E&+e*7BgM}MXV_U!f{zxuP7cD_LsM;t5XlJ1GMwN);Aqf?R*IPw*W)p z>P_uNAb$2$BiKqtcb&W3MjX};=&%^;V{_ARx2I`oCKzK6{Ktp<>SYJh0?Vvr=PF~p z69Fi93o)XboXtvd!5ExX320yn8s_7UP~2(1d(?%k|CTEjFF|aw0eItkymXTbxSSbE zVtpDL7CkJ3XY@wQIR+Nisa|#jZaqM(^$XV0PPK1L#FwVNUY^j(Wxx<)B)Y!;0?|Su z-YyRdoetKcF08$??4)`0`&Gum{Pw_1>74xMd~Fp-Z|PUHAd8t`!;l(4^YMAA3elMT|5D$j}c+Tm^`3r~1=Y zEshP)k>2Q57!cJ~!w%|>!4?6VhN7EW752qR%lkcItxI=2B=FxY#E<$~nC3v#WQ?|}`ffcFV@;hNsBsl|X}KFS7Z{kH2g-1XM=SUrh8fP6 zw*!#h#5l_Bo@zhzO0V0y7Tv=zuwuH(SK&=|#4qK52WFapH|UOAXYP7@$Y7ca^BXpD z4Td~PVS}au4Q3&3F3QdGEQXDJh;ET*i0;;-iYA`+*0+X!;_O|Fab4}!b9ZJ)7uh~f z%thSaBVx63U{dj-S#^yp6cxIMohKI;KI8iaVs{x3{d#Czd^-ot?)2F@Sz zRaNJ!unrcW?!P-g#UjAu)m%2R3oxk;Vz0_TC3kR^0oHy45ZY%BVr^Vvw%Bxe!Bqh{t2)=EzsIN>|F({kCy=hmm)4R z_6wUkqenxmnG*KfR6of&z2i96U^E^4Oayx`$g~n@<3Vryxdr0XzH|HbgIqZmh%4$!$6uTbwey7Lzq zJl}hq-i0{d;@i)UtLGxZLfcsEF;zUx3oBh5h-5j;H3D7yfk1#MueA;JzvB?Y6-7MN z6c&3XY@G$=L@{8^D|GK2Qd!;AlHB8(3p?`-Ft9RE{Sh!{Cs4^}32e%c*H*Z{bfvX- zU=3oy)|+`}=`ln2;M(T!Rv^4DliV~|&S2Yb08aOhq$1jVuhNAl)I&GLZLD1oHq8Um zFc)!veP74+TpOTAzcUo?z0~jkIAbEt|2Hhx3k;FVBBl(-wFz&)*13KYj{~b$0;xTd zrty$6F9(C4e_+Vjfj}!g^|oKe3l9b2xznL9p-bNZ7-s${Jr@*e*S1Mq6NE0FZYh@OKj+sPDUJFqh5tuyEaioUSBdq4==Np@F{sV7JC{ z{pvD?_4>kk0!#SiK-fi}DuxeP)H0m%IxOT2tXm%fcN+o`^_S+gfm*u}r(A&*@qH^SfsJnl zjJwEXbE*L6rz0kx1Pkj2t$Sw?cNYU<3gw>zMH4g29$oL{G+25Uu}}=ybk}98EqK~( zu${wz;p%$-1bXcS-krx<@;a>D3m}Hhkg*fc)Dz858<1jU5WiU4Z+K!T9hGsDjPAa< zVB1WMQ(U3+KVgO3-=So-HW4QSZM|>(6+p0jh<0*?|QN zt~C>Q?5C*xwsIXWBMz7k*>EiEHM5F;zSc;nN%ky zhwU&~PF)L>D21-rGoJL4Yro%++-HDIa?&H_-5$pDuWE=3eV|y8fv|p3yM7g2OPBbj zxhal2z2G4%wdtX!PddoU3JHx}jnpfFwUaRPcOjBi1!6P;UQPpE>j&q1sxul>wq$V5 z_OSfEYPEkcH1}>r_4}C*V5^;_t6S0AfT&XlIH6-EGZ$CT8QSHBEj$5?D+8SJr|3E+ zkMLiBekBke9Amz>^|&l$NFe4(47-zIXx1MwpE)+r$O~bz4e?k7Kgjh zVdXvB1m;ET+aIyxZdfyeJxwgcmrr4F-Z1H5^Fd#W!{7v5(RDnmnwfgB4MAJ$LUq6F z&2W3RjEAia4O{gaL#KU+pF$xPO$!{AW%OA*Q8K2bej0JJ`M2jN7{dv52)Nr+K5Y zLGsg`{=5yAYMhh0R@aQ~QLh;M-E=c(DPlo0b?0X2{xYz$E&?{24<;T1cC5#cIUKC9 zyFa2n)>5kwYkmjrSXX=7#VzU%o2x4)^yK*EE8?AJh%qC<_PZ(1D*&e+18>a0t9_Yp z4S}|Lao^{#ymw(4YH*`d%b8`hpBDZegW8;+BRi8X#?J1lWm?(Sc$!C{a)^h_e z&{=jKW`gZH{~yC;L=z?`XG!>I-q^ANDCyVw&n`}TyYv{@Vc&`ab^b=|^9vT>TjtIT zgmKlPe}rYp0A$PwlrZwLxTY!60R@eo?56N91z?pnI!h4@Z|#hWD;9R+Bien3am(Vn zB->nr^}5Qp`LMvbu=gcl4YB~QJ(XPd>0`M<1=4WE*^azcK?}?2#)v)30$=scb7qxy z!GUG&R&h(^xB7^u<}i5h6(F(ss$E8`ccQ^!yh8WY{$NoD*gc!i&S^2^=m<+rg}OfvF(yB``M`5YqY9 z%GR~On#?DClL?6W3V7!ljIn&4p8+iK9yvoX_?yZ1cokTygs}4FtF7KLtP56UD!L|q zGDz-wTu%vHu=ad6>@Q@8^)r`5G3bWti8XTpwYy@N))scNCU7S>VoTrhT^iteIpD}= zAffTm*LLfD16ZG>!0oPxxsPF8b`2O~B3sfLU18JQ2)(J=B_Ok}f7WE4!DTvTOgAiv zp>}C>t&+j+&xTF5%{yyRI&}|r?k(fS+A;o}0_dspkFXfltcBRQ1MoyYy>HSl?P9MD zgl(S$o2(1`bUCvxLDzmJ*Tyy}{EES&4fu`WxpjY_sc*AgMz_7_;x>c5?F?kS4V24- z^}1j7+UPl@{7`Vo4=5AMGdS=U@YQh}yj!XeSVMM$<-7xIm<#Ok-2%S=$BO}9&8%5w z!Q#7M?Tv~ki4Y4Kx_PSulYFi1u2p>7+9gR41HuE1b93K1hEPTy^1XR{O&4_EtHVxT z0OB=g+{hfTk}ZIqLS>yR@&MqO>#}qSliv4-lV)oW_s;>QxN5a6W1Z~lR-4v8%MRLx zE<6V0chx#HK-c#;@Xi-}?nyqYU1>TGnVUyoI5Zp>p!?MIzB_!Q6mJnnzUIF7OyTdf z4ze@4Y)pSo4{P}gU9t(VRvsFj`jb}E5Qr<<0Rdrvk=+;))jn*EVV^TDx>a7WaWI3E z8(SMbA#RGt1TU8(J`V+~%7JdEF2DL2;^7WhqgyoR#{x2&eNOrNL(xaDlI}+wLvno( z;EQ=JtVw#N2{gJ}wy!_%G%*m~4l0IwxqdfdgA~k?ZV7CsAGr!!Sk4~CT3Ksiv()Gx zu-%Fe%@K9{8Kl&F3}O6~ciTJ^%T#~jGf?Xku%s(+dlT@mr%%uch*tygxlPgav&_;- zS6*q)5Oxk?Z`0h9SirWUh&9*3I;*Q>9*^j2o&SI#W+B*xHo%woKw;}b^Q^E5=ImAR zU`edq&5W%^iDBc+79VA|4yybAr+8zbTY0WsX11v5yOl7R$FjI?&ISC5fNs6fU2h%N zPWH$c@(M7i5#lhj%G`}ukC=Vp!~}BI=dvK~#|EE%Z~(BN9z)_fRe1|@-x*A>*%TRT zHn86YEvk3hv5Fy&+reh~(!c)(`gl;R>J$8H7I+X0R`M?(svcW9IYY_?0((ubb*x|& zg=LIy8BdwIxQa^)rB32!vZ4g)V2ustM(M%NL0TiWte1>!dX5|l=F(G`Ev2Jz%R*npxyDc8BFiScAK zSpFZdG}h?=*M7cFP}I(&V-duvK6pBl$IO+m-|1k3h13TSpV~{MJcKx}7|>@wP$eIR z{1}e?7CLjU9*X zKRd;smX@$~I#Z7$mWTsf8-Z>_LfAgjOaY^{hckCHqYmoE%*TzcVYLtw+j?a(Id|R# zl(65-vIrJwJ8;$Ki+2mSe*(j4(?Uo6v!CCihPXH5%^a!CME@FvAN7R(M#yR-)RYfjxQvOSBdU8yRtn4Z|tZ>TQGVg+p%HO_e(XOtes>vcIABa&R!=egBCIQ(^YW*U~o-^);ESL4PwTt~Q8ne{2Av`hz-TNUxYTLkw zdj1J>(#M_X1{)@oebQs6figLOBDzl$`@=~y5px%2a7k15te%L=T3{`f8CEhEx`~@% z&2{zQV`2My1C>mJiI)Pk{nAy@fO&!Uwwd1%XlcJx{2HvSW$B0!7p@+<0hYAR(}8Lp z&U2lEg(wQkvkZ3Mb4RGsjO(%vT`Vit%PByXi0DeEfwdk3G;NHS!gFOOUwT&_*x?kg z^$z~t0jO@Zjk5u^DKmrH7XvPILrh`=vemE~XFxnW17xm>VgDLn>|DeY@nIK_z;=6( ztoQ$dk`3LP59p@dV}cg@U}28J_AZ7!3j$2M$B<#>$6O|>W!tds@S{ab-Me^ehRn8P z#Oa5)#zr~ezvxPgM)%1&biOEe8~Y8m!;f60w63s3*7Qm9`fnFL#D{G$VEeQLJ{@9Q zw#l%e=FH?jf$wz?TZdrqu3=cKzeG%09z#7NFOq$Dct4)rJqODaiE$acqVrau>U-dG zD`0a0V3`qL*cYsG6}D$GP~Kz}5DGTA6KsD(SnEVU(%`^0L!*T~)CV{8xZe$~HireB z2sF=u_3vir+O0-BSDVMEG9UPK9z)qJ=!%<>^67+G{j~MDJdi&Ty8fAfMxBB04Y79p z#AWGD1EcPvOH~CZRu{toeeKXz;8+55CvO8~1^^*VBkf$ep|OGJgMf5at~~ECRPKuy zMwd$HR$N_xp_~ibF`I!~Sq%HZK4}F#XLKB3uNkR+N8o|cGb|l2ATJPTFW7l0hG=~d z*O`Kno`GG@3cD2-h;NxI>7FeE`_}2C>#~ zptDE2^5(0*T*RxDVSgUOD*VmOHh9I)9w_XKD!~Asya~M3F6RpK(AU@gZD*u zXtz2SF;Wi18aCclPr_2HLbvV^tgGevhlwnXl{4Q?3~h|=RXZ@GG`ELMiW#uB1Fm%kKBfk~+g~>yfVE&k zSm%-GM*FHC^rmtlfpcHc1#agt=KEAH-QQ`J$~eaPQ}f2=E{JFRy42z2o9EUB zNrrgRXFeT5F(FW{6}sHU03rw**H zuiw=Ew2-fQ{5ZNuPte8mw2{i0r#jybVDow%Zn>&S%8Le=$`g zcPnIhbZ-r?3HC#!iy>xvgY~g_ zedG^@FO8Y_X%P?FAKVK-Y~pEc_i)5gI%^b9O^YsKIFcBM;un*)U0~7Ya#=xlKd$wo zgX?m_DxRtl)~qJC8HUi}yFic+7_vTt#ZADtWj@QAM6jRJfm1;cFQjLx4((z2t1@_t zAI{gmBeLw8nbRdz@a(ki`G5BpxXm4@aEQ3&V%|3>mr>@m6sl%MQfznSl<5 z>4`lI$!0QoYJSe^Yvo>q;bTWw-RrQLcDcoBBIYn1cAW%kWsM4z4~Vw~xOE&|gfWck z^AF-S6H24Pup4bK>?w!%-pj)M2TU6QK1UqfoFRv! zBPR0Xn4=Ze@Z(_NjM_zJ>iDmLs_Ph>R`2{V21w=E^@HDvQdQuJ;Q7%V(Jf|rqruI9 z&M$z66S%ha0@z8@*Av&d>^)%TVIXKbtoQZoifw^wzG}*$=w_MRW_O2083fBW3m9qp z7TSPlZ<4OBx8DoR6<0mP{WOKw9}lGdf02s?3;BT|HGPk=V_;)VBjcU{;mcs{<|~}l zhtBK(F8OJ{(k%=Rq5_w!*e!IQ4Z3LYS+I^K{f`$A7nrnSr$YSOViU0iusj3s)IMjU z9m*oVXvc~T8)ic~ZyT^T3vkOE)>9Xqlo{*zGq9Q#soo&i`(6x5+5nc(xZI>S#jre8_N&$;%jbBZ*+0M(e{%}| z3Rc3tX^@rfvq`^7b__!drfcqMi}pZZcnobkP+qD43++7~`nMr5N?`3{8=qUK_ZKj7 zvQ|^t`WwItzX63attT!33;76`T?28)Ehb2Mharu!qicB@sOsy7=?ruZfjG@*Oz29M ze~hlSaXH1MTbB!nWz}sK3_~gJvD~vkKx4$`F6RvE`Md8x>489>k64=)!n)kE?p6DU z`ZqD$cDrAGg@v*?UfdaWvmz{B1mMwXpm;oVVH)7!_b*)_a}FSdVIM)K&f~kyjR;#%2DY^oaLgVgY!cXE7w1Myu3a7-_S-h# zuzp%F6R_0H%k3`wF_tN&2N0n8V#iI z-A-9BCiwRRCC4*l*fn(V)58i`W=D>KMb~}GCx)dz3fz;;b|I?W1lIVM6xRm<3p^SA zG>fL@nfaTzX?@Waw&xif3++>z-TUr(FmuutA0(ym(?~X^3ede9);oUO$kG8;O0mAp z%WBO0SjPV{l_DP_5yEpmdd(%7rXT2dtfs{0=1qn?$%V;dsA|H zD@{#vW~aKqk)Vht4Yuv|fQCg7uNt?fe7-&>VOw3*?NNZ@`M6Qu4nWn1SW~V~Abo5M-z&iaO9GGelfaq4?#Vz2Q^034%=}Y` zL;3+TCm_bvNnhUqs<^Pj{W|ivE`z(C1*-i7x+pd)!jN(8U}>^4WRvc{z%Q&(^v|LC z&Z=6lJ01*DKV(Sc(}=T*V<>V2_97>cG635ACxBnR^h{%=im^9em;2&rt^8+nk5{2hl>~F=8 zlCFKuX24q8yKRPc`05x!8MpHeqRZ-E`m8?#J78A4^ajH}!GJJsO1qT|?q}Eq+(ehd zK**^x$C(SO))$By6$tVONajWj)%|x^nrHh)8*88o-xv15FYP_sA{Mfa=j(XW7l&$!WwO&%bIwXZth64!SJ>#T(RoB(Wf;|F@9Wxh-fkF8nOz-G9E8~?z* z=-$^&8ZAshq5SfA=@{(NQmt2DpM^%Y1nFIkV*O!hH^M$R=>_XrXHVYUefp-RfGY)n zn1_J@FM(Cff!{XNNv;ENdLrIy49jCus~7_o(O^n850-i<4>{KUW`Lg{)|=z@x}noN zw`JSRxUV6A<~AE;4XbH--EdDEkHRAUF%UQAgLQM#m|uViR{8Hsfwg;q0l^sj$;NxL z**&wFH@@Bcv1JT?xER)`C)S%s5Lc-$+@wM=v+|eK@X2Y|>i$4#SAvuy%)lPA=UAL$Xd5pxk!gA0uGp6|5r+gMsm3 zx1z(M`4~eRB9<|tqRoNz@tFDXUsy9cwhTdGd0GQcS}|nHC)lq8z=!@q7<3(W!@iqO zubtufChJ#Cp99%yp?k6lHr6%G?R;(aqYGt8>!&l^H_23Yb({DEe@6pu{sJ<49N1_! zI}{T3t}5daSj|HEs*fyHZC!(0I^m?zK-;M3!ng*pLIHiA0$qKyOam~Cx(s~D%oTY| zWO?m94x1e-8b{R%F>@6QOR62{#*Tson!`#|2DTfBSA#IFQ5RS)mo7(p;Ipk#GE-@b zEWighDv}X8`!0rAL1EKfwP&S(`>s&6RKOlRBIH$AqnfaIegX?S2-e(vdl3Xyr~&M1 zUsyrczJ@*Cr@TOUv)-y(T(QWk(qs>C;|OBLC_KTtBn;VO3P0_&wT}Ujk^+0{VW?UY zL!%yunZ0G=kFW?jX5qxJ7bc3paj<3`VfTFIH=Yij>g_KtVwim!C~kod>DR9k(U~vg zF2rQ{8PXvRtmkIfgwj}JsJrQQ*Y65U^@O?FdS1w1S@w2-<zYopr#-)I9oD~y;!*IQT=NN@Sfs{*ti0`(LEoV7rI-zou2s{jny1oYT~VYpuRw;tQk7Ba5)SZHiba~D3F zB4gV;SI&s_%V+KpI2-YE9oSy~95{-b5@38x)l1Im@~8YufrIH8m+b~(oZ+xXdR@L0 zh_iQdZCKNAVT)m?L_n;Xz{NH|P{;K(Heq<~nFM?8 zf@KefA*7DJ>>Rr9hhc~I0JmQujy7?Z3lEgka7SGVi*=odz_%S{ZWf!{DDS`9)+Lc1+4%jmUuMKN%tiJbw zYX49S!H~SkV1=6l3#}=Q{k+mK7A%C@Gu)IL=uUt83HwjyIu(~8T@8q_3xR3rfZAO! z)G@b5iisGz54TJ_9#&2NOYbT6cqUl085sK5I7Hje;L5)0y8EyfCaCX6VO8703Qd6B ziv@%=B!k97SH?}gQwEkk0dT7Xa8DN)f00RJxGNe-)uIOrzR89?)U4*#242FI# z*p9J?vtDq;V^=c7T*Sjmfo3|_FSB>t0YK-%=-wDJ=dG7HvjbBmp$l-TDW?Bo6A^Fr zfz?Ta?r96yJ(r}XnI`rZtdYFY_Opm{h9DLi4jaD!$m~5*xg-^@VMz2BEXoiDPjS`$ z^-E#LxUgZ#v7VoTp|l?(&ToPpZ;2spTMY5@BEEE)j`?mc3&JA13%9MmfqLSzzkpCp z5FfT?a4ugV%57kyC4WgI;MNPog~oXcOa4WB>ZIdf@l7MK^wX0Mfb1?wt*Jn&#y}>w ztc?-cxhSmLb)bRKJ;NtxWN5^9ai&y;J@PN`KI%SSI|9=~W0+|XIhX@6S~MVzm8rx4 zbTQ^&?Ozy3ty3322)lU`w)z{eG6V3n8M?bRa=rY%6?`D#7o#H70ieYc#4^iaoxTDC zFCxyr1Iv*E*3Oyhxj5Zcz+RmIs&oe`R|4*4V7}I}xmRHEb*X%l864Ca6=yxHhcEs9 zKg9p+WJ=kVt+E|l-~&}RT*gE}4D<<_`Z?*x8`yh0lrWZwvzCr&mk|T?y5|vrm3I+) zyFE>-W1(Q3tf7A; zg}u^Mjs%B&FhT7M0vxf^x;qN?^daLaMMgaK2w3z0@l!kCv*EI%Dv->ia3LhHY!Hyc zoc+zuagAMwm=789tQwFv3Sv}~(Jy~1jN`AGZ38jX_!nK~FtFcif$)hCL;LBiZ9Z6d zf2=sO8pHIJKykxwpexz_QdoIM{c8J{#uy50WOTB>L&e#4HQ27J!I|8uYd{8_yF!LDjmp3nK_O4)BnzI*H z$b@(01NTkfJ#L#&#)N>C^;e)-dhDXV82o4_Y-e4dsrmFD&qodY6~l$N~>@MAAS_B;KWxQNGEW1W*4@keXKv)O?4u4MXsz`+d;o&}^^ z47@Q_<2iB!VcW_fiJe$Cn`feZN^2-PelXE)Qmgz-MSW0tU5nJb;XJD-s0-fErmA-ym zOL^uFu$U&i>$4HZH$uGN(oJ8DE%7Spc+MkJ!(TgHa5&CRWjqem!nsm|O^jb()!cSxIzD$HLnF zhpw6Py?5MPtL^Zm7`8-1_iG>GV}A;qq=R2})0$?$aKhvg#olAFHyUF`80_;cAI*@f zb|HW17|~wAntumAyU6YB`yN`ZNB_g%fTmt+Rry{X7SDA4Bq#8%0e!p*(AW|lxjec! z24$k^z+xA+hbixsYaX`=tkHN_S&M2uhxFQyu55Hz{bw*7Q9ra{#P;17O|Xz~dq4 z+T4Q$y5b)$GyTs%*ta<7s&r-gLg5kX?neCE6t(y{VlInZ9%_JI^f>V2yObJLQ?`^()3rGb5}ii1@WH&|*EhEo;$*eF!_@ z?!U|myt#y~Xieb4K*o(R4OUDDbov8)_j7B*iCEw7z&f@jy1O$GM+#YDVeN0#YwjuR zlix(9h5_=XLKo@-gMX$5Vm9a6*)I0lg}^8yYMSm-|a2`0fKBsrFtPI z$qy8$14R3Z?qz%6o@ezBXVFC}2+Yw>7evNT^9<1JIgqCyP}O2SGYYV8DB|j!Kv#YI zT_E?UYs$D?AL}+J?dPKv+X;+Fj5z!TP%Rr!+>bAnjjcGVfWQstf}8eR8QsyR!|oe1 z@m6DfFaXH<62qwPu;%|^{bQm19u>Ij?gwPRFtieeT)x(ZqCmn#Sbxrd6{(M*lZhw2 zsjBY;#FiCchn;jw5Mam&#G++jG16hJm>(9@FPYPHy$7bgtp5NTQv)CE6|VZ>aDch# zpu1n%4H#^rvc{L$pbH$R3Y_!#-dSHF>TsJfz@8ak16IJ+`vGdJ#rLP)6xx%;!HrlK zS`_x%#P%GAHJ||2%mvUzE{?9H%XIn;ER7!zw&%r=RNdURz&c-MgoZNz0-qnFi=a5N zDKIGtV!q12<-CY_Zvdrsa*v_;m?gw6Sl|DY-Ynvyy+Ev{@18Wj{Qia5+GHNICoI84VAD?w z_q=)Leq46hfXL*dE&q*SVJX;;@USLU?-J92S)YKrD;0YHGj!nDjezoIq+-r@*6On7 z5xTNznILpZbjQ8h7M&qn35S?1n)trg4ge$E!POocQtn24Y=!uJ1=wTd?B}FG-JZ#w z1TyqR%yAp|=RLYmiGhks5c58Rm2-((#Rg_p1nRcNFzf*=(I#L_Lne6n1s1sz?9VV* zM8oQt5fCymVpX$L4fm+5DRQ!R>ox*78XJh81lVZkw)KHRjziq-o}c%q__`#z1-^cP zOtAAIfW={e$DYggxLYTeG5Fay*eGk+FMpc-DI5^)8Gb8`?t=b#PVRmT?)wCmb_a$w z21NS3ux;mHE3NiPVj||#+ZQDO0^IXu*0<(9LGN6!lTU$mwjZJMq1%!Mv9~ooqFFDe zjmQBL#ZZ57EU^m1Nj)~2k@ugWwpeFaW2QOiq5Hn`o$!17sxh#m*?~v;Mlyq>_x~%? z8^*0Uj#%FAd&A!hiDdj%be0K*WIZ$WQx6M=>N3@NSMt48JgSS+Fg&^gzCz@&7^YkW z(pE=oP!5*OIDc*0Y@@&IcQpppgw=@zboD2rB>F~;49vI0g}qS`G1Vg2_l&?B{qu&`CFezLPQJ>&|5l{q{7`eE%v3 zx`>9*PX{OUAqSX;Lg>mV+W{}OAh!Ali*lMF4GzL0Wk7c!CaltVpq;baF=cG_$E_t_ z5Ubv1NUr2SV6eh*_Sa z6+>LUANJ8^EO}_e#+I?0rk0O-c1GPIetjTMXRISVGEjUxwb$AU23+T-L?blA0H!)C)@)E z5#u^bOuha03E;n=Shp4fntf(S5}&l9j#(rK(6u*Ee;(uJrvxrW=0;=eOAZ;PgPX%T zjODTt`fjl%=r*Tj$k}?ZCXulAGb=C308}rJZc8^~#Qv{$P7KSp0AU;)CJ2U4 z3lP)$t82kP#Ck&!KZXNZ8i7++WV;Jc=kG7lJVc37{1B`iwu5nMGzvbz2EMULsI z^kLsOZb)F6L6__??1F`=UOAw5CUl!yplfU)-8Kw%!?XCzB#5z>AUd zT?l6$8kHSGOg;9Nz2oQB=+@aW)-h*C`vF7^!H_QNU>#2ayZzZ`{Sb7mOcZr=fi$x) z4Dti=sUqm!dvbVC6hl9c@YgJ^%O4`1wyM=wjxMYxxrh30Lo-)yogvLN;GnfJXbG-p zUy*U6A|Q5N4HWi+#-NZQ(cDaVx#yHcj`I(auG~l^vbG3xoMn!uyB3R z^|ZBF=>k;qX|m6S4ao*!znG0OI^EGUag(vqy#6KRBavy~aiVrk61I+gM+Zea;=OY#~F@;$GB=Wa| zh)$n%G-4K`|ApTxinyTdlVQlU7BSgd3_0|t%aIVvg@gU8e?Iq6QFRxr@F!s2Okmt@ zplw~?c7DbM?BWS~AP&X5OsR*;2=uME^Be`D>aTeoseZ={bucE%VEED>zTIndA?wMWg?y% z6S3GLSQyjlNl(hb+9K}K;eH38yLld#uNN@Z5|rJ2JGY-n@7V%{DhOP4su-5xXV$)Hqh8ucBu#!N+Fc{YNfVCQl^==m+k&l}@2hiCK`0$+xy5#`ct^?+J z^NVYMOJ>UJr+|nVxU6~|Ab)!1%j)J0(|vlE0TMXh?Bp0$nGoyu!P>@rmP%dsCa{er z=Vx1CjS2u`J_GMI180rQ`c|{djbQwRHi``@0filURt!Z98V!0Uk0WSG_>2YH8l*6D-e&u4;N9rM+7x zC(Y%?uZW5m$`6bcb;oBL5ks5Z+xuvHEiGa7&KR{}=k?AbYp|B-j`-^y;>>ceg?5T> zYcX!Um36Y~oNfZJuQY>4+2MyXGwdG4xK1Hp0kQSzKpHV_3H#n+!S_q6EM$3oZg=yQLh2BUBpcOCUwbh`R)!rvr1+A zhOY26baOq=j<706^*xIEZ*lVKQvdnSAlh0O$BjTN?H7r2MHEd6m;HOS(hD#=-jA4V z7pzfpU`$P*YIdx1I|7?@kl*^%QD<%x6l(|Dn6p;&pJ##jDG;x@tHpHh6ZSV{lL6!U zBmRg3EV6bEu^_KY0Bdpqc-RfY{Kvq%)`;8w0Cg-atzM(s=GJ!q3QYai!6RTL?8HJ; zguVO=-Hh@;-Z4NJ^LRQVDos3Kd=Mbm6bwB*-i|QIB(@k;T?wr8eM8y5mNL2@c+e>N zhQaqV)GY;T8V^Wh7yRANaocNQh;D)pW~q;3;4JwKi`kKDE6#@1PXwHB7d~zWE=R?% z(hRc2*IMfiMo7hwl4kTziGY_nVZ}W_nadb9x;WSMxcsvQi zg#la(|tM;FJc9Naa%WCkvl8r_OO z#KpRNxy6XrIskWc$EQxvMSnhE+goHJaM)KU=0e;IL_Gctm|Pubdk@`~OVkR-7(@0*oLLBtj1e93r1Ym;KVI1dzb=N(N=DhS>>rMZinB%%3+ATZA4<2>Nn`3 zy;A^RQv#8CV_0F5S!<0iVTJhG5b=**H~Iv+wz61$hTiR(M$Zj|aR=v`7<-w9XEg`j z9R?P8j-EJ)A(h4fL(KAHedeZ3fjx#nOmE$#S4d6m*;I*DkqbCF{Ws7;l*i0i_QE zZ!0^_J|eNzrO74ODJyZ6fj|%MThdnZu*IQ;r-;O+!}>{KFKYwOyCIJH8}=nKSIjI9 zgmBNN`ana^A|}x{?x%sB)1TjZqvdwh<2zxf`4AYA7~MM4VY{8M03+q!Ft7tQyM1>6 zpPmEJ>+l{wGXc5v`$9q-VURww$rt=+Tk$3(Vq{bEfg9+)se76lcFjt6%4`wGhm6-1 z=xDYm-x#)M8PKT=kG9R`sr)Yt*+KwG>mzRT;x0KA`Y4Z?DZ_1+rm8H9)>!h(6t-Q zxSaarinu^Ry?AG1SfAY(mYc2zIP>&M=&qPSx`pxz6X>^W7_#q!<**^h=E6q22Akkc zZ}jhR?l}GFQW%OY1#Syx%_{YM(mQ7A{?6Rfcw1B-i0+c?TLrZ6f$AOxLPQ7d+y)No z*@5>N*VQyq+BURF2cSe6bXn#wbC8HYdOc_3Ck#nf0>8r|UKk5x^hW($`(gfK8`tGb zSQK4`{Xkvw{W!~F%l5#(=8~yz(H(Oyo1TVMbmqYHh;e=2*@pO$V$AZuq_E$rThe^B zKP_Ux?TFv)WXk%@E57fM*e{A*{UrX~#~pnM*yta14xY+o39aY#499``O zmF|@-c8=Vz5{-a!{`#466>!Zb$Z154{{y_rhi-OW*pV-cOIRBCrzKF${YYb7n5@&h z8wyOfy*zme7N7(Fv_nbhI=5~BoOOlP*yJC-hgjM!t>K?1poZy$t!~ zuM;7!a>ez*=$>x{u2e&;=;Ow7t&;f6B|LT1G}v?b^rtf+9`*!$?LN>YC*l-cewb(f z_}yW}Zvffs`PXd2S|&U2t{l3Ldh8DGHeKg$Y!*$B4_NgY_@fIfcnuu>#kI=^qFW$r zwv6TTmWM5TiCzGI*(oeoh_2=^#J=9BSP~%Gf9QJuhJCvM{PZh8s94N5$O6>KK4)}k zhD2%wG|C1X)`1hx1v11&Y<&jSHV5M#*i-+p0a}01moYPxz7FI_#*lah=Xf(*QG?`% z)g`YHuzMIVC@~PieAV50bpIe?vZk%%%&-*UeK;`q!BZ=t(kjk-~SA=msOF~2NO zq&v{`B-T_uZdemV*etM>WqFL}7NC50V1s_6o6;L=p3LZa2SNOh5q8lU&|ow}78zEh zwgZ_`qFdY=>)(d>(8jL0@Mo&HYe@_FO)`KB8e5$iks~A;2mh0h9xMY!!tAg@VqjI+e{ zsTRBYIh-n!4zk$vuxu@l7Tv%(G7Hw+1Nq527@8ad?ruhx$QVo#%$W`6)l(5~>cy|` z!QO-bZp8)md)6K1SMJQI5K~@f$k@g}8&~LvHQ<4log5A{%mBQ1!4eGt2HI>#+63G@ zh#`Y1ck4M=Uc)qVR#-OIZ$);*Wy14X=zcc^nmhzv_{Cwz84MKzfEdP1*l<7wccFqV z6{{-Hq9eLuW`V%`h#7UMhHHTA-g15h;7BXP8z*2HyTB@Y5WAV2g_vXw{XPNs;Wm~| z4y*3F<+9)g(G#zl>uMK)t?G&4;2j#ka zJ-Q)BV14XQo4?3~-dHq}Asw#)mt5>r z1u-Nm0bF~6SjuheF@S4xxg07;-|lepUu(sk4NL5Bp#N$T$=6@074Z?!#EywqcfnW)|e;6%dcuVoZq( z9GL~YjEePecCP4XCOR4hNd5)LIRi-HZ|E01Yz>WqSlhJP&qW?m68LB}+ips!`4u>2 z+UoBEElz?sL1!Lt88*=_BzaF@-!Yz`glVvWzSBwHo^l_kVOBiqXYbjbI-A)0J`Rd* zvrceNf7*Eym{1-uO*ae~1_N)Vp!=^Htbl%!-FK_)!9J-qtk((*Q4Fzn%YevnfMzz6 zC1pqagmY>VS5!&`ln#YhC<<(n*LFJ2kO;Q<@hhVnY5;a{D>l0Z+gz*JyMZ$cnJ@l0 zhK$gQ2CYRmwFnTRI^voUz&mSBTOT~zEm%uu>3@aG^2SHJasnu3#D%shkFk7Z$ct{C z<7yhvfnhPkwEVAX4C`UYb}Wr}&o3r-On!}=K9}83K?A=-7g))Nu=oWT_uNg1Xj({V zDHtA~!3QoPPHO{9wJ^rDK2P!p*fkz3YzM|Qs{>oo2{_xHEAkdX*Ks1^bYHNkF}h|k zx_P}|XSxEtiz2r8i&+jEGfVy;272PkZ05*N44CDonU%8Gr(oe5GUThJJ_-TYro`Kd!6QhCmR@J_I%>lGGes7rUuQ@^3_pm(nH(PJRw%&!MN{iu~N$9!h zW71pTlM9jKKJ4{#h9vw6>-Yth{w+}9|E|}ZA!q%eCS5YD&w~L;ExyqbGGArgw#RP7 zdk@W~@!ch80wHSBqeF1s(2%Z2^xF%ZxWvGh}* z{4>PzFM)+V#=8_iZms2QCz9JBg%n!(`gbM(Gn*m)?MKY{eGudM9^Fd;Eu(p@k9+w9 zET8f5@do06Ag~4Y9z7=_ZZyFz&*Svx(dFBR*u!>gZ+YO4ejncw^jx=iY?G7Z2oT$q z9Mc!WZ(F$oAAqxknP5p0MGH!oe}I-FfjK^3mp!n%7MWA&x!cE>usMdtC)4!~Pp3iC zAf`J6G#CO*^$98%Oc_lXn@cjmFw=Tfb69M3L5jmdn^mqqLj0=>ES+^>n4MieXD+-B zcH2Gweio?g%M`J5f9dhN@F>LYmX4*Bfj|0gUB4*KwdzHv0JQ3iVVYAV^&$Vt0=ugh zzcYiBKg<;c6Jy9f2r-M+X}aTOU3pYXblvX*XH5kO?7#Bu1lk8ynSGXDv-QsEt4(1C^G~WkyLzle( zkY*>4&r)9DFn2585$kIUWYQQwYU8|-o-@_2L8Ut|B*cF}B~#0xQ9y2ec|e^uh*jO+0^70fScoo}^`n|^wBDFmSP$!xt=yx@L?CTf zta}<^7&Ay_{N~pQ8=Ft3So4x4;EII)`c$VLx+VHrv9-VzALDsTSVy-k-Xd6hS)><0 z%GZbi2Y@5V5wG}>wPzi~f#DFRB?UrTg?2<{=BhRr?^3C2!jL)kOI3~JJ65$*zSfux zu>5l{)G#A`D2c9nN_6i{g6Ycv7jmQP=a+_wF&P&}A78%(*y%GLuM10F5>~_Rv7{b$ zpcasJ2;%5!O!{|tuAR9NHpl%)t`~=jjrEBgO3Hn(TP-&N!rjE?TlOx}DxKQZvTY*UhH30Qyw`W_uES?=6>vM%-h04__1A9rMdG z_h`gLSh8}!K6fExb)bPsb@(J^9vlQVcq%N_N(MJGkzMmd*y1SS9{nKP6kwK5y7OP4 zm9@K{?{;}Ea5@$+F$jjn_DFHeKFi(YdAfXgAH1dY_ne7rsmXF?D`0eFpvM@XaAIJ0 zdtTwP-OVXe&_QD%mWQ&1Cbwj6d@UEdx0xZ5UqTLTM11U*fuDKY=kcNQXtn7U~^W+#j-(bUI~`M7H8-<42cfFj+mfg zxce(Y!OlzrF75{oB?m750lL@0nzu0QkL!Ht2C(uX;#HmDxH)3)T%e&2ckcu2OHyEh zYx*EFtiW?vZ$E3tG!2KE1LU>Z$M@73FF0b1^gtQE3ym?02ADF^p2b?l3^%Da;-!m- zsRqM>PDi)mw?pE?(wQRvYyu4$d)Lk7Ws?v2EKnPi)(^jT76pZJRr`bz|GM zle^aW^FD7?_4LeimwLXPn7(qD#{-u~+*|@^c^AmxUtM!D=YZyh z^Wx47S#T6X9Fxabo4|x6F?2tTSgtzV?K;scX}WgmbXU4WEkxMxvd!9T)oq+_a@I>U8q z=(~cjEp5@=ZGpA+H(>oL3|IWxm$W=$s!*_XF4M0SKt3Zc-CW>QVXV7!;Obgy8i-qc zjDt&IolOOY4gj}i0;PPT-D4S7HVZ?N1i&)HgQebr;g5b*+y~EO-;}!@u*)OV>nrGX zwZ=N6wX7yAnrn5zx{$_$$$Q(Lbwdz4xlFP5Bla};MsV3%+;H47;71T3yx!hw7?3D5 zVxFB$aAP!(aTB_-?*2pbO9&n5f$z4)&bQAZbirZ+LG7;N6o55uiFLZcd2Kgh_YOer zYd{oh+PL&>KC>U@%^@aUq21C7ID~V;8O$!ml_O< z*b~T-74h|3pod!#G6q-V)oBvf1u9(z0##&!obGBATiuq$7#!Cxx5>)@<2(_(vRg`R zMa-c;&o|D;n(7l+nT}mT9O;`sItDDYxr=rgT?}E0j?^?Wtcz{M!^nsalECs?G~?Lm z&kc=roqjMZHBi!Ae9K1Us+sUoBdnQC&DqSNXMDc z<$PwETj~RqH+}7py_pOow}=e$5c0^hG9jwf?M?L|G-GJLKfV4(lE5G|SEQ@$QC)T`Q5nsC>+5J*j@-QrEMj%}xAXEaZ zeQPmzh==d5ztKH8hi-IMSfyP+>pZ~h*XTwTg&olUQXKM@jbRVZ!Jg{7jr@DW$FpFA zk^AO{;|XE+w$(K4KG7b3D_{wKc$9klVb-xg>X4u}v5 z-7gpWmTBp#OER!LaMS+aQ*Pk5VQ}37^dP`-5fPK?%D?I({@w!wIe^%`Kd>w|;_@EA zLGx+w#jwQ7fHsaxdk|gJY>bPqw?9b^o4*~f?vH$*cYCLmh?JsD*`~Y?vit};+ z^M&K}m?Eg2I@+T|ib@PFt{cWXh^|X<*r9Q-Q>TE&`dFKXKosZepA?8P12Jq!pzAGQ zT1j-#%D|4Bm?}O&+%HTu*JQMCe`$-D!9HW_UD!6e^ez>E8sUIP{ei{C?Jd*lrqYbd zy$f-Z(fT32zy=x; z+1djo>jA~|&x(bCZR&bV5;_1!Ox+C?e=KI^6txg@{{f=JKo>hDx9oQuHe(u4x|4%@ z0F})WHFV}mkzhHUs@`{4@mb6=U_D~+Er>Hb%We0Ka*skxnHSjmh#?K*V3_8Lzp)I5 z^)J$LK0>@-7na>$7VesprXJ*qG{a!6&59vg!mieWwe(QYbT?v*;K1kPKv@@irG}-Q zVbxsN0C)Ny^VytHJIoPNAX=w^B#<8R>2A#@jR0DJvZ`y?@}g1prO@h z*pGZb-0DDQ{j^mGpyFw+_*97@ckG9^zeIP*W5eg{=<0VtEM^Lwl@K1duAX7DyxTI20)CRq3iuy%fzY?~O?vo=uLL^8@vZu<#CiNmn{hERg~Tv2m4y6R(q zqPG!anX6N!26~@oNRwT#zSgVgZpux)^T&K3x`kq+)iL)aAchTaKli9pdZ4t{_sd~l zrvP*9*Wb3`vLFY56uE$oJ1~r@2|H!HW!?ZRdN5mfQ@>LF0WsLm%7*` zY}&)kLbu{C5G^g&hR`QJ?ExkjOgG)oiB1(u_SxqfuScA&hWIfHaB3=$$>97v4nsH3 z>iyy&mRN+i-c#b=RfwBh&J-Sm*8B8DdL!nV#(cr%!FG)YhF$}{_C*)G1>@STWnAEz zuw6f3F^U40^z2co7?=EiupMz=sd6$T!&cakW59y0!2CSG@5du?F9^o4h#>*e69b5rS{#f)`NvigYJ!mw$o0mopwd=4+=D)>nfZbt%d^%T%DLl|?Z`rIP;>?w>&4)7=CCqmsbc2hYraB&F5hA(V&+mzP}l=R^u_23**@hC0o$x+7gx+~k|+)Hiq`b^duAa{kn(~OZyl$vE}*zlS}}|T4KoI z{+2d0>R3b9^+Wt)6>sjZHa+bH|1~M3ZisI76vk~a>pic4c+5sQPD;dgr!f590joO% zcF=9CKMh!Z7D(p$4f_|k9f!-#WMJIDxQO`;#62FXqm{?d-dbDH-%|&+V@S}Kh>PdI zQuYB}+8@q50^8>I>6gtIx5))-9~O9)8p!8j_px#|?GD_^#^8k&U`KWDPI|=cyC zA}l~pYP27J%>ba5&Kk5S ztjHYLXd^G85nreyV*MaM@K8XWtV|H>HW1xx(Xb3qTh=WkgHyEx>Ui)AWam+%GKLkk zVFSz-g%e^ps6St`LA!Y#Yu4_t1FwPMI^hZ*D7&;(^78z zZ<2KK7!mt-E(-nWX z3vYSf_a0s6{fHY4@vYX?8}@`<<6!7J1jCofus*3Ul>Gx6;&0kP9T)pH;`*hqzD=&~!Pl^(Junclu&;l`C9dGLY5ZQ+%u4+J z1meFw+PfRDSc5Rc^c7C&AYToV=UsuH7NGV0&>eB}68g7p*+O#JikyfO(lKO>Y2-iy z#Cj(Ewh4izb%0wru|{qN+?$V>XeOEbjN31LNDp}S7iVgfAb9dtYM z0RP(4luza4|!e#Ns!`ionP1WU3xLb*a0*MQwyOIc2 z*6v|TIM^%GP5)~^Iuk_{^LVhJunO+XntQ;Afj~UZY7z9hm7ifX%5(F7%!%ttq06V| z#I_+A9tr5}YmKqHuJr?$pNzp%%obNRV+b&{j5DpTw!0}22(fuA;PM@AUQa_2?{UdK zBB703BioeMdQQynKq1dK^L3DNKG3VQ3~6fBD3A*{yc=Ku^nVdEyDD=->3=`6$a(`yFe?uCfsM#D@nio zbVZj`{|hjF>lnJZQ^8*7@?#y+?g+Y3X%OSp1TGy#*Si?(>w64W-P%PFff4)B4f16U z=Yoaa3Hw|T*5D+pSPo!OU&Mp0U|s40tzGu)(_n42BR2&r!behN!x9{O39Au}Suf`sAC z_f)_TtO>ep`G9t%&;_dwd-n+V?#*|YS}IxS^Iu_bjN`DazELUz=X-15lK;RX_G8$r znOw2Ri2v)dhYbw-R0{UmT2{$3@krm}aeQF7*(_CGbbHGI7d=hP^z(Ow>WHH}9!B?p zdQW5Ao2}?dnK!oj(!oan!(IS2tPs2XK=!Hu;@o&Z<_AD*yXJ#yu-4XTk{JQZ4x?+6 z8Ecp>=(d`D#+y*y_*-V;BCu_f(It1SF1tNN?gB3dBMz<)JL*GDTMIk%8W`nIb6IV1 zV#VOv$U0nA7p&lXbZP!FB)~$I#%fw66^62_5J%fj&K>}q_m(C7diYOsto^KhaV=T( zoh7Y_qJTd6_9W2Nd=+IJ@K+~nW?0oJhvALs>+Mxo+SC|2)&h20lmFxZX8QLIBNCvy zXz@R5Ei3Q0hhI++Yc4~)pOGPT+QG7~K-YH?(A&N)zUzFh8Eo_lSk%23PQQeGaDRU{ z1x{=LX6QbHmcj~H_k&uuTKI<~?;66A=7M$Vj`e3^;E)?1${;S`2J|t_W&DEpWCmgy z<2+;xSj5^ub(7YxOR%H1_E&}jjW~kxuTzhh-7mQXbq%~o{&H~)9=hiz;J!`Y+IgTv1uz(dgjaJ*(Qtq=C%Dya8)PG)`@ZV$^j$H zVvWsRncVPcr(g$cr2bSwTr&posIT+lJo6>bjhMP6&`*f9X)XcdhX7%`<+AmRYit0Pj)~aL$6YxJ-MEyn zP-f!;e(@gcFHz4zBR2U5xH}zjv^lfv2E^V!VS6{D%kTsiw-8WGahaKg+lX?*BAfhi{D-94i5X_q0NsYfOdnE5%`( z;#~cJ*?$<4TPN*nN?zr!!AXw8W_ATW#K&;eJn*g`hC+5ljCMhqvf10!D|cK!n__#amsjt=zw zfOz^B@cBF9K+{ZKV{grApx;F^pk!a`<5heFkF2PjBwcpE(gY&0q+)oeai`} zqg&kZFV+99;j+9oIfK(<9p*u3Ra+p!0>rSHfKi#SW^9k{XMflxCwO-O!%g?2wB3BW z#fT9-I+ZVtE>e0Rq3!X-cR-?5znMoMEC9_kSrCD-qcgUlkLN!u$0E&qbnG`=@Ai3 z$^Y1c9y7Cz4+87bkiq+1&Wqy^gH+~jlg#O}?NRdjMh_1It^ac~GiB2Dh;^R>jps0= zxAP5YjUk8gHAxKIH<Y*dntfQ|MCm@|Q3XI!STr(o$?W9@7E zG|Le0V|*me2wP+S+H*Ho+|P#Yr#DY-vvFkyy01pXJtu8r%;dB2xw#PWy9?3p73`v! z=4yV#`F9bQnwCmgkmLIi-pVzWS)J3vA6{k1y4&&Kfw0-@xULK)^mA_dOtr@WK2N%=-7-lCaV?Cb)Ix_J5x~-1u#2(QVTw{~8dp z?j!c`GfZsHCvz7fcJV}W`x$q8wT>a%4Z8EqfqTYzYP}?}skxi4`o$1RIs+K#VRfm; zvn4h;-F>tuUxBfD-Q1=aCPo0N`lL0?vGdGLty%(6W^zSU7x8p7#545}=hQ|FSOeQ3 zeA9C(Yv@)F!=p7qT4Cpj#=5fE!7;&*@NNo9NY!+`BO30(~zZQ?nt`s9@^Sik8E{nH_iHz)4Y zmCITZ%G!j5%L?0IU~g!GxF9!!XMYCfB*0L$Jn+&YQrV{}VIFFuN6a(zRY}7Y6E?!C zo7P)e-`-tUlQFkJ*;_o*#A1i z+71A!cv)e~@!~x|#`8eptw0=0>euzKa*4f?ivwvBB0jzX`(IHWJgLDx)D_zAqwUertGnkTKVfb8--9? zr5gh)WKp`P6CSjbceC}&78b+kN9c;1HiKBotHnorv=}HqOzUIV(eJRScCv%Y0VR!v zwze7*9>5}7941c#ig}~ho)gv0`B?jWbL9i`m zi+|<z#Md2R53KP^bhChju-Puj?l-XcLt!r!qj^~UXq+FdinwYt)|(q( zPfZyG2Lg*cCoFbJ`kGmLHG>6u&$wJWVD}B;UEX82)qcfhSg8KM0$t!+cE+VQ%5v7h zy0$Pd)^m2tuDeLx&!ZW?qN7CIk;XO2eeSNmfq<}+{Z1bZFD!Rvs&(SRQ_rsn|fDJqg?Cb&jX#$*`fFYP0S}ZS6<}6}ay)*4_*ktQR44uDa7ubVY z7=pXRrQC%_L%l*TIps@_ih(%E9{9j3SQKC8tmAh39U``sB%W~G#4KKLn1QNpIMpJu{`E^%UG@bWTPp1kOaXsx>*SmJJdeTreUVSlJ3?465U$X9q~ zj!kK1`1}qSU_N-OM-;Ed;F@D#*At-|^%v`?W3Wwb#YJOlyt$;)rLL zL*}a)MKG)qc3;%$8|Bvpe(ppUcMK5ce@r^kUHDlVSXh%GEvCXo>9Olf(yN!lB39$F zx)*?Q(|}oJ8TZ%tK0Xzl^?qR2{uu7+4!$^^)6D z+OM1WdT@`1cI!bJ1H&I;7&;Gl^b{!IRDsg~Gi_MT+X|)Z3j5b~I&n*egl>WO!6ztC z8E9{UPu2j#jgPRH*2^!oFyuJ}{&&C{^X>;1;{7#XTz6oMKK{_p4&mMIEJc8cCW>R;@=FJ- z16u=CEGGlY0q?2!UV;3{HGVAo=KqHp_`ZQ;4sOvcRw0k|Z43KFLu)}vs zVbZ9m@BH!igq~H=^)YAO(-Tsg@F8o943Q1|9Ns9AiL+c$3{UScE}y%3Lr<7( zz*KJv%jGwgG46V|`iPnKBF45=dQq7nStg;&_XEi6f~Nfl?6Qz`H02es`m_iK9ypl5!i~T~pVjWuTB}7ZJz1LZ61f+LUBSEuVRZRceYyv0?czB%O`;y*-elGh)DESi1tS)j5H7 zZqH{Iv1k>bMNq^%HgzHX<-TQBqB|P~-H)p1=DLU*e_}XiHVJ(P@qs6<0i$70>!E9$ z45;GTS93_~D6rD{LBMgK(LQu-`T?SL0J>}j4mwMLkU+C- zj2mJ4XzRDJ&VrfjfcXDo`4N9qT0;|+UnW!tPzz%G5F{=bZdVDQFYeT zzTo5p7?%2lExEq&WD4R{zYAS^z>thRVLQx}ZhI zz{VIREru0)2J7Tyr#drk|99ANv)xKrA9rR{8^%5V0IO)c1^ElS^m|ka8?$*0u>RvS zpEw9x?BG8hM<3gHzD@=7UBES zb2DqOQ^4i8%shW7)`T_!L0Z6CCj(-(1)>C?OWy~!CL(OAF&!uZVglnMye}QeWpAuo zv}}zo&udr#%hI*Pz#Vf=e!KqJ2E;8J;I2M>dwpnoPINt8=OA-{U~e&mFb_5N%hYju zSJuCZKQK(c z4eXDMSUNtC+Jsz4_SP)W(z~^M3#2=O?({EM?Ip1KK3ae-)wZES^!u_Vit^i;U|DN) z?@e<{{ZJ5KmI{>`$e#(Z=wnzK_w8^k;H=?N#@;vgbRf%kbcsw=_q!vm$OQ}B1>J`^ zz%-M>*JRuy>0DTgaSU1OA6dknfjGhS+hH4+ClD~z^IeZ8SciJ^?7v`bth=3UvOjoM zy1NQkWwu!6>fT!m>$nIgk`VZ|5Gd{OwsmD#2J`7}1G~P3V1Q|}hwnBpJh1nJ^ZBG* zIx()K>3WpC;I%!l6@DkloC&t}9@Yw8@!C>erVa3I54zzqvBvaqcc#Z0FArkKnXtee zfo`UeiD}Tav-=5T4IQ){_AE2jT<+yLH|lRSU{(#Ro!#1chS0dHz)_zs-89&h`mjQu zfOQMF+tP>(9_1E(6B_uU~Al-T~2?x1#nU8(Tl*LWfM!zGa)^{RTeOc7vL&BZgKGhcZZF@84SjJul5-xW^iK5L_*du*a; z=L5a77dT8LCJuGnmx`W|i zb&QmDml3O5quw0=E?vaX$)YsQm&xA>c;1M+tv4Z`H+{9$W2gOLNYWJO8e|3X=3(4V z^V)fnbhQMq{m~isq$<|B$q^5`gB_+IE-+iH?Tom?bNQ~ch+C}-Kdt8>U5(qvf$cxA zmd=48t4FbvI(n2Wu43anfvT;r&g#n*6J50_|D7z%=+RBIIX|Hb$d5I( zu@&3o_F)OEifvT$+Q7ai=#INvNxXULRR@eLVl}OAZ(BzP$>s??>tw8l%$U)B0r&l?5YQKEu!e}? zyD%iO;qp=siyQ@Oyk+Q`2SLp0Mh(pcByErG$S|PFPYk=mGcK=T)qD@oB^0_1ZGk0j z$}>NdmaqYzW-3^i8#c?GE_V+IWOs8sEfZ|G1n@boTXBU480d9Yg@ zfywp^eJuH_M^>~kA2?!|bBcD_z$ zfY|4N#2YZA+6W9XbSK-ERXPB)7={?b-t2-Er*Rj=L01uv>vf&1YPWUKP1At6N3mYZ z2>gkJxF{v8j+uJ-dSIrXr=G@x9V!kh;=%6OXT<5IzBebhqJ%LxK%bnLgdyK`)*KUI zX^quuzSdp0c1a-&c}_5Hi~0GWKcHo@PDe8Z6;FvSRt})|Aq<;_p!?Dis5SsdToBmP z0PDJ&up+iNnLSabcU{uDjbUz~>)RMsau6)rTV^@*8P?jIeM-Ojo($_lGt$Vtu+j^F zL8ga%eldBdb7lMh6wgy}b37kHHg*peOHVt)nSJrY*805IQo+vm7xo*-wr&VL>QqxYf9XNFsBQYbSV z-7`z?r9i-#;E2WisMqElEQpa@Jp&MC6fo#0Lq?v09XiIOFLmXK=F=-WYqfE(%l=cc zHd$fmI>Hv|AQ`>Kid4WxT|T_0&zRW|m#+oN`O@eA`-w3ativ{R{d+R5fZ;se6(7}) zyL}joq3t%r*Lr6xx2%S{`XVEjtw{}p_c1aRXIuxry|>bHP9@qZ{!CNHH5&YR>Lh8S7?i zPiOZnOn7wV%?u+rDUh^3LzZ`g^|Lr!aC_n# z3tPLRD{U;?cXj`|U_p`L~w#EjGHl3JABx>hOl)1`~ha5^_TlMF}ySXWz{1FSth#70xtXDt-1iA zgFBVE>Ab%i_0~^Q>64Ajr(;VoWXfG2{(oJ8J!{Pi%olnE)@wf1@u65Z*#UHBnfRNy z$6eu(|C_=)$GU_4Y+InRA7nn=$J!-0V$dtVFu&duF9{1Y1V~{SzV{F~&=|vme;B-c zHDcSZOm)z{AlG$R{`jyG!bw~3V;6zGR^WpN&}B6l^y$WB-DS@b12Jy_<0Ake&5F1C z!zyRy9&vgx?twYIVhY4!c3nxL0;#?+Zo8T2WG*0Qc*FtL-FJb2v0irgDe!bOhW5G8 zB{4yia8<*OcE}u{&1l3;{{m$UyFn9y%b9^vy85<3z>a8Gcbcc>=(8UUlYZu(J*m;P z@jagWfyF8U>+}Gq_mNwkX#^Xp^JOZ+eP8^5?bYw1S*};^hCQ@Z3f%@VKwtdiitjhE zXY!od@DgI7X^1U#(k2Iic{*v>&_Jb;h<)wSlY3B`d=K%l-Z8}Y*si~yvIGsRz>wT} zYD>4GogY<(m_w$g074A}GWx1LtuN6!W1SXNrY|nG?P%Tt*3@)9atAEPR&;aMz!H3i zz0lFtcVOm5giU)|oC5365^ zAxB>U!A~L1w@oN$B5CNF)-))yIbY?ez_{gzX^+A_x}0l#=Bnixyvm09tACtu&i!p* z7`HcZ);B>^v#*LW1ZbNZaj(w5>jUGq3Y9EN!_H!z;-2p>02H#ZSaAnYow$| zhiV=i&eYg}MRSEDh8QM=(H;s-11g&J5#6-6v-ru=;p>okjWv+O|l zmssnc1lATooaPz~&{aMe;^mvew%9|p8HQNOjk=rw2&rQ>35hj~sVBH8`AiIS3tWg6 z&AIPcouQ+ZI`=`?5gmB5Uf0tqfAtG&uq*j&Gvc+AK*UvuB_eS}Wc^^a1@DnJ-+3Fc zReWH&r<~bBm`PkwpbWa5VYnic;g@SRP$w?Bwv&Kv(}5qpW&aoqIa80z>eoY@uolCJ zMzFsXVC7q2sPq(QSQ_z@i`c-xDW8)eF=wD#XJZlEBHd#OVg&2UVmtC(9S{fBhP9px z+wXiczA(7(4TcP|)~(hMI5u#{cCp$>*og)hI_a?y|Apm`2UO^YSl5Iy*PvUy0x`)j z*nnhQmc?eRiOx0A()S`dY;-Xodu5}JW@%?2Lo+T5mmW64!~Tgo%$M~V;`+ou9QXW)8&G%;FgF-5 z@edQEpA7tOJYtT`u(LYI%j&RA3xUOc^#~OU-EOD4Vo1{z42n2g;AXa|_RP{sYLD_-WOwe=} zZ1+1LiK$?stG1~fh?T88ZS0MvH+m^-;!S@-fp6yTUX^g;GpcP#rF zDB*T@-v+ETG(LD*%jH58&cLLzKVV3&c*#@KM?VS#)L_W`>gY;025xCcW#xP~3qxBS zx*V8x7}({}>1`(rM{Ucu`0c5MUB)v{ z7L)D7uJ32u!(t5Cl@PdWLg{WszugarQ4e^(2xvS3==t9s8A5%o@GLQJqg&!x?vP77 z=owJWcpGhB^^Z?lavUs*9vjg%I+F35>yXyFh^}8X)ORQOmZPlGjdX^>CbEm>-7}tEsJ3(#d8kkJSY)D8&u61Z)S-F6H}VPWZFcHDRm@o`mPZGB+RI&Rd{du$zn zxcUiV6_00`9w5F6!xdY%!g|~P$9s#llb$#~8iwZjMil$v_n{ConPkS?$C~ybY`KrI z{x|GOV0!Y zY#}=3MAz1CX^y^@#;&T239o>kf5IAm19i-=p%}N#FfF+b@%297Z%M?T)~zf9fq~}E zpTE$ha>bu6WP;hv5Py|J%wvLIZV8Ov9WjvND0jL{W5ntkfU`N7;Q9a19q9;6aHl)l zlEg9H%v%IYJP~ME5W^oMFV!H}5j(e5hcFDg4@@@UJxqWhrAc+LALWaBJlke_v@#ED zh`Q=FXlo-dBv>1!TIY>Mxw?@<16QmSwakRu8X+dqUxu}XCDf$`_J-439}B6Q0u z1BtQ#&pV-eo1U4YI7?|aZ=bzX9X}53)>%&(wKK;8%{;$9cdcHxLmX+N)L$oz7zD9z zBCI#UAx>Kg47Igt;oo)idW$vB6JU2s;LvPz1M0#i*8_rE?$+zOf7T;bHvuGa%L-&* z-1}F+Qu9z-*L1#dbjwt=*s>GE<|MN&^;D<6x)j#Z4UO;`!xPi%fCcEfmxCpa4y-SQ z7_bt^rGtb_0+ctYPVT^ETUH?sI}U8r|27+lN%X7UzI3pnz@7KNBJ)*<&#=S2fC8t0 zX7hlX8G*1qecEF{h3`PrU`+6L7HqmtdS)d&}M_Y152n*!$nHYNb(fdXu#1?w{Z8xAq8rb5sKwHzux?T*)W?s8I6S$=R9n}Tu z`az?-`Jh>DphZ$3$!%b62Mm>>z)D&IyWEB4j>vt}T4qQ00OndNS`G!0`hl!PBkmFG zIfmQ5^wAcu$iIR8g%LZw0#-%>K4oI?zae1bjo)Cl5EnOcZSJYCBDN4SY^Y|92lBYJ z^Q|dO%*8Vj0nOZ=vHIz}>xid|0M{=ehUmt8nao$i_b^}2{TL4Y_eReV&-qEHpJnWX z%~<;zSPSZPZ#n{1>~a&ih_f3q?XQB17Hn(jBXErt+|0x zy3Z3|W`(O;IV@uLU$FE>z)dTAGiy{RBcQq0#_{M@W(K;pzQ>}bz+B_}m`C$Ir5HD- zFwjX43o#r+V3S8V|FOg=Uq83$b>@6vrzPR4g&>*tt?1@8u>ck8hB(xn9_oYl)+6Hh zB__T}zef!WL5<`pm4QqR(0yAAdzKzZnG(ot3-;5nKO7wE)9lpsY?mIWg8!<$!UM84@Zqtfme6DV?R1p|juaHsoW(7e2_bGFWGw zfi)IzpW}+P4*j1u+x4Z7WL+> zA|rk^V6y213w4%j?#Le_vvDoNNBLpRJpo@eSFbgkZs~#j17S_&`*zrlc)=c^oep#~ zE-ZwLQ!D_(F%x@A*Yr+WSV@B@va`G%i|$-Y*i|>6SQ*3(W{!2Gfr)RpWp?}e$$b&W zPJ_jI46FGXxcC>?-;uj*3(B>NW&v{&0`cQxsA@o8PmguaH`pYjwWi4`sLz)uEO2}^ zVt^aE(ohWJmIX4UOf@6)9g8)IUK!yf5ZI}1ZpCoJ&U30s{K__15_dJ_9Uz4XY?jGB z=}eyVaWbqULj&zMqkGm6IAb6A-P~2hA3gqTL(JY2xL%xbvr__1KLd5#!M5(lF>^>4 zZ$4lVx^?b!mi$0py_%@qw-XqPw1&A=?%pW-W^NP&W(P0=CcJfxa~GS=zz&nlH`|24a3= zNW2W_-lc#A&kZEWjA7tS*r{HyMaJOC->?v}+%DL>oIrv(z$vrEKi8PK)NqFEHM&>T zh8_RUo0ec0p9$S=e-dt)6}G)S)^+P(p{u}pxv;|n0~>6CGMoeYnui{^gI)e$h!X?Y zSeA$UXoKE;IWW|QE7>ksQS)AHCwOO)ENQE`%)Wkxi6Xb&d2ASBGH>*D9}rKM+SQ$L zN3F_jDq?*Y9$mXhuwsVfkDkE4=CFs$(Oq5$B(wyL-2`Ow`7TWbitD1Qtz5lgBCdA3 zzr8_BHVx=G67izhqQ12=g<<;4V2b69;<Y&G0Nt;rK(uY>3Y$SP z>N#nvVGVm1w!95&uyyyDu@Fw5Y!e2y)3|(`l`DQ;KvyvpY_-RRhE*`!^9;1K0jyeK ztQkE{l{2QtnF*)6mzDnke(8EE>!bT(J&KtO@w(kvCyR6%x1x^j^KAv}moL4fATZLc zSZh8==?>;Jp@g&~bTJl^`o6X86a%-xP|r2!Y?3*y$A&R<6X;xvU!uEq9H`j|NMZz( zXn|p$S*n`hQoI_vIPUZf=eu?W_AVCCRzDrv0hsD%m;jgQw2d7FQCVd2C&j_q>O}}r)P*7JHZz@Po6T>GH z_km?VSZ^8EKQ9UCV@!O9xT7!-yFB9Sh_G}Q9FhuH<#zwHuvD>z#tQ}fYd2M`E4p*V zf#PA%om&93ngxt;>8@vhwJ8akk_EP*KUZ{jf{X@T8bd8kUs(IbK-f~iN>lhji+Xgk z{QSSL5q6I?7R&U`&c6|h??f!4TU78Ame!neVB=ss2eF`Xr$mC3iVPV>sDo6Kv+rv%E+MNH71A>DN9VFS=z z$N~F(6!y9ztg+vZs-1*2%7QNQP@ucM*4;{6-l#Za0(h{AWb92U9l0V z))APxg)7#2SPjt{Hq2#e zIA{Zzz)mYdU)bOi7`~0fP-70_>EE#8CxGQ+fYq+Sx~v##&j8*=L#$N}7^X`VYXNjI zsm{`y?nGp&G`dO>eSE+JbRkcnD`;(;Fag*X5<^;Dc|&{P#w8%}GYl=~1D}1M=V#F+ zcmy2%!L^Z$^D>?d1G$%%98&5DY|&;QZ(HDkuljTkuzDx(rxLmoFSz!T(}&YR^5g+Z znvt$91QN|a%+w9IUmSSYOlAQJHXatsjC3jkaCIQFyfpk)=f_&mjf#;L_Q&3AZDqvM zAAzc_-|^w-zPp2srXh|9!84B-f!KB{;`G$O@RPtkck5b0AX`C(+|yO6+SeUhz}=ER zhP^ogM4rsGwSNE`-vjTPpqmz%!OIuHu9zN1hlVu{3;R1AHpw)%e=$%m5#yFdhTZoA z{G#iyw4Trl2LrlQLR>fq_@M7j@o3W1!)mT==sNn-Qmb&V5OxJu!g9rq`-q8J!=~!@ zNB08z>jNdWV>oEKo)ZVS^A@p<4mVpDeb*daXY2lm6tK|KF+_*}%k>B7{{$%42WagH zE=5bMiI*d$nhZ>_NIx;*%}RS&ML+KDIDvT1y49%< zlNPRsZior0yU|l-ExPCR8B+E;P^Ki1)J^#{4YtG}Y3Edp^qhk}X@iVR5YJ@wbDpQ-h|<~p1t@uaLnk=U@DknA=qWcoaj!6 z@NeRd>P;Pn0n7b;GgoO0D}0tNZpBW;Bzn``_^?5)P&9*Sx;bJT7Q+UvnU z3K#Z!BiQo%uvEceo2!WlD3 zZ(z8v3D!6Wtg=<3b7yC%iLQ1%#He=bbKSf?CwZz}=@I+*GO?PX`!?TecLS#;0-sEb z9}mJ(>HI%u!UmV&iU5Dj3bu&L7SsS%=#If%_Tlcr8?RmE9*rK0wYs5pH6`%HY8qb8 zE@EtbHze=7-Bk^`jRyAMABd&RQWd8F9daP%cR4?MoXh8l`9yf&c6D?q{KOPu3}RM& zs8cO;CtbQpX@KRifXoemSB6Gn$My3)T5N<3_j^T;aIo4oPq$(M8>V4R5(GAD4)7)> zmqoSe4!?|{;8MgQvw*IKbNMB}(&~(xW-t|Pk2s(zVq2Ymn5pH0+jB}sy3`z2NJnaA zZV!JB@vQ}8>^s;9L#U(eM~fI(>)L50$_KO?iEfjrrH85hpzXpTA&+Otx|bMSNVm9R z9#543*21&j$blH zaid+PSUSxrgXz%}3_*v$Mty+I_=h2x3UbByEx?>oK;%0>LeDc%s$sp7gK^3E1Ooy)-1uRz6gSVI+nr3}g7 zpngL+qPH(f4g2NO7x5k^m;d)A?q_GT3v&Xeed<&?)xhMi(4&Ccwn|rRi~co2_U{9l z`AAFkoeu8sH~$5GUps_;=Kd$A(1jZZl=M*1atW-)ec<&vhJ^hWwr(u2Bq`!@^JDPY zz(6;n!~xj%DnPYkh$E)K@|x`$^g@i@jroFj^9MGfMO@GvF6aqUXyU-Ixu=2iHqg~Yma4xO?M4uS3#WL0d~jqo2E4^cPpTK0mR9f zVXr+QU5k#`$b7cdM=NBK%xxy`@C>oO(NOdspvebx?elWCx*l*6=^GoPc$v>!(snVh zE}VEXx^$m`c&6zgu`#5niJ0a(5a0t<@+37}7cJ+R;D|SRk_p5A&H%s4qf5RT*2(^1 zS`(~`_3dodwKD6_rO%F-EH`4Ik%(=qO*Qno;m)$wb-u6_w#%%YFbC{}i`YgFyYvmV z*w@cK2}oroY8V>!Z+_sXukgy4+OCThID>W4Jj7G>6h{xE3v2!Q_49rE%zy=%fnkT4t+ub9V*n8M3lP-u-@tQ6PknMr0BquZCaCls zF;so5E3yCu>tbl8kH6lIb^2x42qSNP9$36X3~p#+DcVI@nz;yecG zmSw6zE?p=i>ZLC;@*eP4_j%=G94Z4ON{grn-0;ZY1;`$yplVV*^1E_Cf(epR3HZgE52{3pB@GS-q zIsq`GA28(^aL2f;lalH4w(-Gz`k0pxU!22Gv@fte592Bs-Knk5`DJa(0zs}~2(lO` z{uD8uYtZcj?2j&RL6^Fo0QP<^uskqg1Al86Yk7@pfPH9#;f8-X^vs5OL?dA>(p(#IV($idLB|5}B%EnH|&V7W>1%az;fL-8rk7cu@(SVDXFn&TN9TKDeo2FT|V)c5t9>A)$=Add5y z$KQdiiws;bT%L9U;`B$XWVU$jxpIX2G2Z0%!OcrL7;#)}Shxu2dRzHxx)7sA!mip! zJ}bwNWLA=m8GxNHFdX+(SH?f{xM|I<=qt3aK;Ec@Zea6^ph3aj#&V zYi=6vt3LWKKB{9VWtvNL3TW@oTp{%A-u_Az*qaYE)71BtwT#uW4}p2EWRa6Vjtz{< zI-VhKed(V%;b|i!+dshEVd%Dc^PC4^`_lvGe<9Ah2HQ}YNmDv5{Y>C`Go~8V304@&zP*__(UB>pM?`zHf75K6pIOOy7tq2UUq1j~? zoou1s<&bCT(CwSWwc9Kmr>*Qek6`HPs{)EwKb z9l4HKY8HkC9su0Z85WyzOWEvP^!)kE#;lDVu`W5RRXCtgW8ku{S|A9MCJuzP?QY=E zdSG-FbiZA?^gh9i2f&dZ7`}O<+#7-Z?|?aWG6ynZ&9nfPYBcOpL7-n|#KS{jozilT z0Av5D8(PXT`#;&`KCr63`L=<;_9W;^x&{gKwPf94sZGO8N+5PW4-4<{tf;jjZ~*gN zSj~_jmC^lAR^8|>lpkx7?}-0S1QzB(Os|+m=#mZbtuHgcLYl_A&GXvP7Ths&V5Ncp z6KuxnUxA(4&bZ-MfFb(iYeRBDDa0eX%5`&CySlJ0Ss47q*k2}0n1op0cI%{<6`qcm z%&_lv9TvMQaQ85V2^Z0Ij}H`Rhptx~SXYk-tui8BHXjVKPB+iRJ(>v#EfZf2(?}U$ zqy26bZx^h$)n%NQ)$yfUm>y=DxzgLES6GQI$0lHBQLZif-!iR2>@<)ePZz;HN5OC+ zJ?w3FV8wJUOIse@fmVpy69cuQGq`UkSn=S%)6PH$_p(-N*mF<(-KN0`x$!UkL$;WA zfv$E18TJC{lQTF^A7GNxr>_Jn=Mn4H7$DM7V0lk;k!2eVoVpdb?BG~*1+0S$8YAYH zMfKbEYP;~%Jz%r-=c^XTJ$_7lrUS3P3p-<0erDutH(N~C&C+B-7sh8^eimI>KQ;C+ zneV8FVWTde>;dBKps=#3VR>=_*UlpDY6N@XSAZ;c5d${^MwXpUxWFt}SdSFVbhyv%$L1Ws&?&%<xVeQ>bJ>Mbx=3!SOs0mPe3XmAPt6WonV>o0H1dOi_BapUF^}; z^N4zT)t<~!X)w@p4dTYGuyy-jO+4M7vP`tJyIwc}T_OE6_DI-Wx3-ogda?Qbm=0Il z)K^zn6r2YNWs~|d0fxwXfGwt=DV1T>Z7b5%g{}9E8pnoZ{1@vMYiOx6h*@;P>TX`w z#XtpD@~M86c^Ov(F%xEWB@gz+y1xey)6XH_o1qJ%d&i0byB-Ez!mqHiMS&py0Qu$v zL+x|QyDsZ*FnEIAxo#mdr!a5yOa#32F=j7k$kB1YistCvHbM9F4B`=gIO$>HS!i`m zYomV4vwA6;wgHn6GnU1=Au3|y-msm1pm<#vmeMR=$I#8{H;lI~;?3F^jz$EwJ>-hg zLx6A75v%>@5jy{)G>GY20P#9-MUa{34w?=VghaQ%sUl5=J#c3h76Dom!Mghv?6%id zvveH24Ma479{q&w#4cc_@A0iAhCrEs!tQ0%;ta_@8gbPf#KuBh`ib;r~8qE~#G9u98dEQMWz zDg7|?NCIo*S_N#xFzpvm$S}C;lU}cmVbTJIEcDI4SixeSMy#&OSGWa?9*^$CPgp(I zpton2xy=~d*UNfbKum7vMl}O}tO<*wk6-!-G)Rs3)@E$3yD+^gtZ7MDYI~%{7R@L2 z0&9(hT!j(S_>HfS>Hoz-psBg!V+nM@e3nm!WG<%<)O z)qEzNRFQzQ_Yv#H13F$sT&TB~j{xj5hvlDwp|w{uv&elPh%VVt#LecW6|Z0)vSPSc z7U*cp-rZTAu7d5YgsyfRphq5bU$y|j{5&zL7SZ0b&+Z*#=k`h5^XXr;YW)KjogR=T~f zfaqm_3;BVGZtVo&hk+RVHTMX(4`lSa>FX*OUYZ`_>WL%F5lg>dUD%$%>)fO7yD?QNVA^Ni8TLJ`}Op{Bw9E?KW! zz>D@=vDt(j-;8j^XBcGc4cd>G#8R5J4Ujr9P|o~axCvMEF3Y&=ArSN0)U|YP(z^=X z4fh^qlW_*ZoJ+7}CaXl(nDpyy*ipY8t}$T3=_i3#0ilCAi;s4?6cAP)d)fqevlIw> z3g}&)30@ZS1%2Fyo*2gXq?J6gBz7Y^n84CifKBwn(gA-|?X!o$iCyl|Zq-s=b% z<}ScV^Vt?t)D~lEmq{q!cZOu>h?wUbaLX*#&6|JlnR6LfxB3IEjjkSNft0RL9XpPU z?o9T%K+oC0{O7>iG7LFZ95%vxjJL*4vR&+?_Xgwz*6FUP-IVgJf!prP%r-!?VHkqA z8V$|b$?e?hMu*+;&+DQMW=P<-h%L(l3I9*RIfm=8bXzpGZQHhO=ft*mY~#eXZQFKo zV%xTzJH~ha%xA8(s;jH3mb%}aTt)opcD}O~pV4!gn$rga1ztx1QZEK#Jj7ZsG%SqG z={Oxd`Y+&`O>qim31P^dvC4;Y;rT5=-DAQ|)C1C49WOlrPT8%joQtlVUG>Iaut&jw zH)DZ*b_j)hz$}-s-gS3RMn-&Z1Xq0mgslanP06@QR+^kOfWD*9&C*Z%Rs$NHQcMU7 zu+8sdsp`2N$bSb|ZNHw()P2Fv@`Yal+3iu%WX76d8*Er<*ypUw63!Q#c+S$kH!yuR zusS7%=yidZsSrQAo#DfCS--GMT4N>bjGbpko%OUXx<)S!@6xU%gM|oyU2eg+py?3* z!~#n0LigRmc*h@{ZY{$)F)zB$?|=`^($J$=Xt4}^2spd~h&ms5A}mi0)OLq{)&Y`l zf|YXSrQKQmy+mK&&d6Ikn{y)6pO_1Hu{e#?Zwn!?PoN)PMX z1aZGPJ&|d;(ICWl34lE*fSl&AQhs7uW08*W8aVg>*!-Nq`P|9wZ?Lv~0jq8k8_H^N zr4qV6sS(e(`k=`pUR$FM+-TfQgUM zowrUlGD}6R4!iH(7x@m1tPG6nhAx#U{=YRqS3@^=RA8AWo!oR?Q?EPYq;agp8~%ay z8G~WJC%7Uk&@~CmsC^#R!MBY=gJA>ptFac^qVD}6lg!B;Kx5xKPFkNcj6;m47r!v& z9&v(ZX1zOgnQ!WK*ogs*i)V?9Qxb8F)$IHXppwf7X#*16Q@Fj5As782E<|_?r|r$F z_&Mo^O;ecW=q~m__uV{n&MkT26-DE~BI_V8dI5>HBj&PN#dpJ&bwZr@f^qFep{vpf zUGoFzaz8^ncL(;T0Fc!)k6H)a*H1v7XNY0r0d3v_5r#5BBR|M2^q@-kQ+{vvwAU~U zcdr5~ECdPd3tpK2hPv5f3ZeV43^vZ>5&I9;yPIISO@hk{0Q15j&M=E+Zo(|b4Eyx9 zC)3^{#?uAX*Ftyb5>U1@y1gCHB}oKSD~q@|8mzR>dp$CjU3rX{u_WT+mcTheBga!pqh`B`W|fOOIW?^u)Ai_X=bS)mX5EUTP9yo zCwejq2Ebl8^VJowO~zXhSDzsg?3G8>Ck(7wS1D)#eko?EM~VQ{lK-YNgqyObghA zuITPHW=KfO&a+kMh8IP5r4{UZ2-w@Q|fsVEdV}=4n`vJc$0L85KY4zQCz84KR2*j$0IHf*p zcuFRSXuB|^Eth2;2V2z^I1rT~6Lh3=M!+r8(guId&SH0%CnMssUa(1+rl~Ob0y|bJdf;G5Bq?742 z^d%tqe?VpP#z7m5(B_D#b|dAxbH$?&i2oWN{aQ0s&qJ_WrkhV@q_pOt@-NWkwOyE_ z6VCH|tJojpFn$m0K#b-#rLoVs;y2vRMS)Rz-GgxG+B9XB&z8kgX<;SIi3xMVdIrV% z#s;JMZN&Tu5D(=c zzqK`zS5vnO=x^lh3C_5S`4HpmLF`uz@w4s1`fb3MXBd7@20mIZFOEdl-=-tCasDF| z;?4#@({_jtz1#TWh_h<~=kFi}9S*$qc)E^2m&5W@upLmv=dEvqhDwJR)M!lGn;}(n zvl%9oNT<;iu))}4b_{Ugb)32KST<+9)qYk=bmy+4%kKefGHGRq0vi^BS^m{UYg*~D z_%H=m0mWwlf&BHoV*rD0f5e#`m~We_s{IQX=H72Kev3W@viOm(*d4}|GST*H2`ha@b`z;L&2+b*C+8N`mi zVQme>q-L|bTY#)*S;ml?zzaisrH|033oyc3@x)_X@(Nhc2H0?%D?X+I-Wgk4%__t6 zrUNB_R1+{f+6xW1+rS}X=Bpo>IBd<&)pruYYasp7lC4>K) z3Tqz&=>9LzdjwFq6i|FNa6Bx~papPqIg{=+TT~0gWkD>=_tyh$O$9G4HYx{2^9`la079thaB1H{$3MSpgPdb+LOSg<#U$RxwuD% zRItU?tqie&`XPag#_F0quo2km}9D}7@0Q+p-SbmFJKFJ8n?soS62Uz7pPj@3~nL)Z)nL7SuT;1!yahtYX1+gA0 z!BlN5RH@zeVlLxa8VqlB){^^R4?eZ5Mz)uAo>W;OS$oD4ZExP0LuX zPO$Qp^7<=)WQBoxRe;9sX(?w3S{Pl%{NEe&1 z8wU~FnK*+P9Mx@nMtj1C4kKpvSRR|Fn#KUGX&9acxNR45--UGd)SDSyH%l@&kv>+n zFNSg+Ulp@^4IAZ9?r(_NGJmGK_%CAX_`pe1%J9%!QKLTMBNIe-XO3i6EdLtTsSH!CM0>@-rc3)v4tOn{@q_emOV?qHZbfxkxw{Rz{XA;6%8Pz-g z1M1lBthj@rzu^?FI&7h@j}Of5bv`lVWkZJ;PE!VAO;Z$hY%y?ktUA}c!yw<#7#5>4 zm-SqYI8qmR?@RYfo5U%h5!;yoi|QCdjI$eNi8-y9G`H<%Q%go$ePT}=#Bn2G)%r0c zeip=@(;4^P2(Hr}80#0=1okMqtuK8|9}~QynEqbZ`G%H<4Y4)_7zhz9P-o3LN#|kM z_Z*mOHYxO+sd8?>Fs46{bt#5`1h9P_u;w`cyB`rwb)eT5%u5RnmzOwHNABStx zB?m&v8b87ivpt5I-aFi5G(1dy*;B=*I|qN4z}MvL@qrZ-8geY?VLcPyoggy z0M$DITRoYGnPHXPh>mlCpSn~kLv4_qT^%25c|xYjeHV80FYv)Im}JhZKN{FzDb3(s ztuRYOcm?b$2-NW0o?M2Va!bCs5xG|()^w5WttGqdh!ze4PP>-8R-~Y2vCn?u9Q_|q zwk+bz^FSwm#mZ{a{+|c1&(QtqYe>q$h%tnvHWt^LV)*S^#+gi;y+%A^xrsj=7Tua% zz~vr1<~{6)Qm=>I^GCOa`qker4E_}rSY8omP!+=lTY|4iu>SP8BiJrhF+TS1(pz`BhGULvCer#a&&{uYeP*k*-c-EDgos*Ot-NOZ5;LL2yC(?&ElHhm|jDf z9q-wD47vl0aS>MPGAxW=;`R?i9P$))-jfLx4OnGn$bXd~vCOtPb&%S6XRkM~$ok*G z>{!E&LyUV9_P!LlUB6&e;sTj0@RQw~BcAjSKau3xf>>-2(8x)Xn*S;$0uon7tm`XL zgfobf<|9@e0=%z;*y0gz(v7J9gH>hPikL6m-jd^*q)U!@t83XaB|eyBP2&3Su97lw4+p zdP@<{4Mpr79hRyoEWN=r&Xl&>_lW|A{pypzP0Qwgw}8+|fuTn8VGng?1?;&^L?r8A`8*DG%?}0uiRz&HlN~nEf>wJ2?3-Tz z2f7>i`(a(Z4~VHt4ef#9leMBnZ&>-~=RO) z@Js8bY1}f^cG%!j=<1qj3O)b^{6t*lxc-F^uU~*=@LwnNG)wKBia59pY?bMMsjl+M zmL-z~ExONJEt~!#hzVT$j_z}B*z!O?VuQU~9j*wnopE<*bU@!Rm;rOFU|wc3UOIQlfp4w`LA8U zkqp2!9W%UM7ugnKY=3mYE#T=#aK*wTurr=p){z+U`ucdmCia~jK=m!?G8&;%s{qZd z5FKJM`1&xQrN70!(P{P{;EHrBU~xVIF?=%{Vpmu*1`x@gX^z`(?hFSUD8wvpPQd!w z08KIM1L;!FBLUk@8BYoVw*w>gw*?Cx8K~l+v?>aWzK6Ab0<3*ZpoJ};Np+AxTH}{u zExqmne~Mt(QxLcm9+>Fhi5VF(c@~2!>H-z=pc{P*vAJ$GY%-T+w{Oa8GhV6{)^SEa zqc^aSrpPDTu=X@}PKto8hxw{i8V1MMh3;(?;G2-m7n0o0()M45G5%sY~zEt?fGY-+diHvUi*&m+Z@)_ zq#9rlU-Cv<4U#L(fDnCv7yB7E^bPF3_n2qTdZPy7u8Y7)7qr#mZm(m`49k#FD;V-2 zHoEzFfpigo1jn%U_!qWRh;F5O-xPMQ4{TL)u1IXw3-SbAn=Y^hyMh0FuMF>I-(QcR zm!a{>D&ExBf|qp>n|XNW1Ax%x>{C5}mO9~i7u3Rfxz`dH+CC>_7T}zx|FHmUo3qqx z1$*+4aob7iVD3S{@VM;`*}?EogZO`is+OU4R17iGx0f=qRAEiBA^46m{QLk-mNt=(QF&S_^9z6Ybzt5nHl8#31E*$cER;U zHVN+VvHmsaKCgxiZH6wpr*&F()U1-`8dt=A2m7K&oNvb9!n$|rB0x$j&I=d$-4t2X zKD(~tMioPBu>km{H=T6_2baUf`4SSrSMn$G(G@pV?`}tTUni__9bK%>h)wMIcUfYR z`VP^r0oH9$D)TN)uo&kKy50vt(;E_H6; zdnm*kZrD@{!8p@l@F+~M*M07u0SM+}mGcwlCj+OfkFeiINNWhC_RC(4<%m!G(h$l? z$38<0-y7)TtLl!>u#w*Pa0;w%7Ngre88*crDVPz%k~P3dPhm)JbhR48y3B?BZOx?d zP9wIm4fyUWK!g-P2UoRa3PX}aL5w{EC}_c5aS2`Ae}H7kfH-})teft0UorhWU|3Pc zZEOh(lm>RZoh&SHT4!w+7+oCe^a@X=i4oBIAgqA>S{_5Fp7mo`KA>_F;N2vkzSIBo z&!v*O2PbsaKstIzr}}9)KQdgd6^C6af%WcEpzJoF_(c|3Ju{FgE7nDAVdu;O?T%or zpMlF>ntd|po$H)xo|&t8SKvis;EI#(@+0_ZF=#JD8N16-)?1Mf_=u|dEF<} zFQBlOg){s@XXlm!eboK!fUh3yO52J%eq;V*t&No!@q0I{DVk%Asbg+4qvse1 zuuihRU2(`n6JFf?z_IIyp>s1h#6?)jZ$Ohr!1l)I4lIFHzXD9!1q{5!6_4ivE#3i< z9x>k^Ju#`F@ux0Vgz}Z5oaZsnmCiCNw;6&p_&`{q5wHoLfa`mJq63xd5g9l7|4$BUzcc6_JV$rS z!g#qE5T!qc9)9MCcNB51DInQb#Nq83e8Z3p91)nG48tt_>70ovmG{Uq35afUn$AY~ zNDZJ%By^?T0%LX|R{hBp`7U{N}<=mhezX5uext%(G_qNeK&Th#fu)WPOh= zwUBc^;&DB7*T2AQUvO^qgypUR3ulqu_zj5E0&$rRp7S%%Q}=4=ktI8ZHMM8DRztwHIql-6F*V#Qo!dkj8R{6u_<* zh+8f(OE90UhJ~!{AjE9B5O<`3T`*aF%z@#f`?7i=5F!LnsR7VKPt8`IaW57#ZlmXx zJ_)+j8G+dIFjTg#<@ygXdNyE3SHxtUfPcLwL0;I;vdmJ~`Zxb5*G{Ve9PW(azuD+&*=m+G)V7^OOt=IHT!VQ9OFV{;dH^th=?F=Y@HHfjr|H+8x1QmRX{jm>z#KD2s{b{K zPY^rJU~teM=&I^37j&*7M&kqvd=q1EmttmJ^y7V4G5gnTI}qyyLkt-l7WxmY%0Ac; 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

      {tC61pE2kme(K|cqVUrib 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

      (uY^QoMjRMmajX(v|= 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

      M$IR!jL9pgp~PV;=r%QLKZZuD7~4p`j% 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

      h{&T|0Xz@Omic%NOBYv&& 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%0Dfr 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

      D2XTRHlyRrv$r5O zW*J+ND_8qARNGZ8`=ccRDz_aCzp3mFRL)xM1t3dSN;{G5cPS8Ec9M3Xrb|>K2+=Ls z1*4prQV24eCGAE-nf2{K3+WyAqEl~_-G|(mKZl~e@01Ng4d@;BqvN@Xg`}VfEq3pCCLem{p<8WS%D0eF$fmIrjgr?% z$5G*`Dt7|yIHK4|l+jwTQ|LbXR;N)H_LcVQwW#yNOp(Pw&apcDArUc3@pjb(i!r3T=d|5>sqp5teYl1v@qN_A| z#JE)kE#-bIizb{`IeswJqu?*a%At{5r{&Rhdj1M1JXorTqNb?5N~l9C#n?jfnEanq z1r_+CBdCh}*cGgX{&Lo;qh04!t_G^c{b7cZc#WE9HDi1&^pbI_Hu7RTs)I~>N_A0( z#Zo;qd8F#HW$&@zzTQUzRAr}Rjwt3xD9RBN!Z%~1he40bJ0&683~^qyX-6?%70vDT<-HK`5S&P=~8ve>6sI~2-& z)E-@*u51T1oIblF%1BYR6SCx2fIFitjBj1gM@DfgG;F?NUC~mm>~5$;tlqCRIx<)4 zj{LevJ@j0QPsnTG?gDG}H(4t9d zc_`Y$H=V=K+ZM_?qq<)e8;)}5*G8c6?DmXAW2dV<7u0!-vaTq?P}xz)V5eek$Ujms zcXT>NvC+tyS=AU6)K0C8MRgb##-Z}nRAW54UQhBs&zh**1oULAViQq!#_mbz4LeVh z(V4BvPC<=tNmG#z=iU>2WgamN&CgJFdR~mDDrcZ}T)X_dlz#0|HD;ko>;=t6KXMeC zgUb1;?p)M`>vSHnVW-y%b>^LWqvG^K^U<6N$}T|r_&#kR%8gYyA9T(`)R@}1U;-OEky^)NXw8j-#soz(@&_z3gr7#T8VtVORG?4{sz<+ZRI*$jbd1XtwGN1 zq_xPKD`FiQT}fJx27QwJPz%1@-hgV*?`}kU&7@6eGvn4~w9i+uE$D{5v=!Mfcie`8 zmP`KVikq|@?Piv{1Lf0}fL#D;!Z)ltkqv(-9EcXv^Y20zxi*4OjDxbl==fV@Ll9Fn zyWOaEyvprCM;O`nqRp(-_n{ni&_eUdg-KzkAba}z(f2iqg`+LSRpS6M-zyzNg}FZt zA@94YaX3#O6gz?vSkpzIEyom#M5|XxN73sq${s_%t)(brKyMq39+%apbsYU2t{Nv$ zQ^t>zXnbAOIE5may`DyX%&*R%V@IVJbo`OBXVIPoQY`w%^W|~q_coP_M>80s&Y@Y1 z5a&@ob|4c_U1nq#kQ@6~i71@$BMG&vp}H5*?LLZKLQT%9Tr%q2RoTnv=~C$mddM-S zpisu&tLXk+)ksD2A4zGbJM-9U=tH8)T}Qn$l)Zr}+DJE1&DYANBjZb|aSN^As@QFG zGg{^Dpx4}GcTs!BqkHIbe`W8ZV~Z4ffCiP8GElJu)p&@E5)^xcTy`mzi7qm4e~iv> z2RuQ(u`2fz?d9%%hFaxH&(Y&?%DzA!N2|t5w4J*)3)ymfuaFb{&}&q;p<-`P8RjK# z(fyffB^!bA5isED)$iuXG@>Zajufjs3U#T7v#NEHFA*EM8&?M z!p@3)L-n&%_dm2OZ~lj-)l<12=mx#OPjraAkzeT473nux-b=0IA|v+5{vcyku76QS zMy7wL3-gG4>L@&#Ge6CbO!i0x(6!Z)0qV}US`gjm8Y+Yij?=j+j2holD~6~l&*T+B zEtv}#Ay@kQqA2CLR16(DB^5^&^yno}J9^-fXvJ=2OCd{knT*lRbjbuIGrpBZBZjD4 z8B~Hjl(Ogvb173~e?m3Np`Fau%cDzthgJby4N={S==T2{-FI9~e;mhgvXaQ`N6E+x zk(DSRJ9}%`StTP%Bs;RnEF)z{GD6uDvJ2TWGRn>f(eM50ACKqb^Z9 zdeu<`bH^G;|E-+nf5>*P#4TyhNY3oqXc~Qv75Z$g*QkR&geq1SC5A}#P?h|WH466D zQPoHMjHYt~RQaLm+Mo(t=M9l@KD}Ba)TM>g7*z|9nxK)K2Tc(_P48@rTqj7)kdMF0 z*`ZZa)n0S-oH42eI$Be*NB_~IJD{gL3EC1pX7qDJi|LhHp%J{_*60X3nr+Ytu2m=G z&z-`y=wwZ)9h&N<8tqY3u*!8nhm(};h*~XFwiBApS<)FTaZ}bA72&Grf`YA7t}AM^ zS+Q>DIiGlUw6M0+1D&6&qwk5n(6{$O$;um_~U7@-|(dvoH z4nwtfs>X0M@Vhhu&D6&r;bHc>01k#9Z4#-Os?6&#D|Oim4md z`IafW1eKkq>{7HjL9u0MfvL0{&B%~eAm4M+O7xhPS0OigxDd3TYkxIb!fwSHRBonX zYtbdvwd>I5kIJq`*3{U5Jm^6}(cIlq7+P>m+K9d}W88%7`bnFS6MHgS(EMMDg`*5F zy~bA5guWyKO<^32L`GbL+fdA2wY(j*Sg+U)GN~32zj+|NdoIqY3rIX0$wQ8I~nI4LrM$haO zJA*1SpFE2u@eKAkG_b$2=h1-aQUWRzASI&EKhg!{&z$ulDj%rWCG!G zpBr|*f|}4{UPV^Z6uXAru}gOy)vc@84V1D{x`~QqOUWpWJ^d6^oPGXVXzUxsZX+Y! z?;W&?o;nqMVu`H z=+#o`8R|k0@*Mg5DE0zf2$#}O%LdX*WN)T&uh0wnl5{l0M0$-nzLegeF6q)+RHlUL zzC-;T^^P)7GJAcQ$hMHmy+Z-RVuYzvHa+LAH9YFGUl@?fGoJ1Q4n4GrC1^4e?TgXVr`Ty zBI${^dZ*QnA<>ESNk!2`_BoBv!8%egl*ZU(jFvESFOI@TNF|W%HDygu8}^w>qQi^T zUMVz!yDX*A90#ckdc;$(WzlQ+Kac$bw?sZ3?7pbm`pRZ(FBm9s=4=89EAKkQYbI&x)4rv~!) zu2@afptDp9Ei0`Wwb2P9$qFr8E7d{oIVb9(<@};rJye3dCu?+t>#;rxWT&P9YGSH# zHYkaeXhYO~u3Bk?D!-K)BPZ4gP0)s_D%TWEO_pqt`#5Erq4D;L*`fLWscv($vaMn* z(B%_~*`uz_BnRXjE44&H29hIM`B!R%{?W&^M(5L{HmGEA$qCKm_}Zc=Av%I~$dDbF z_GmNfu@0!h0cAU)IvZ7^6B^2=))~d_Q8|8!(sOKW#k!yZ?8$XSTbD`QkSU{bcVziP z>Vcln6ZJ%+j;LHO!0L@nx0a2D*8Z= z>W@ybgD?%ng-X-WvMI_2ptn<1V+Ja;S_(vu43(XU#?i;kLc#p@;B2)1w_2HlCajR= zqS|FtcOEijwmcuTohSvNz({EU>dJY)5S3A6;*Q|zLwL{k~-R-q1Cq!84#u3lp`a{Q}uYfwMtcx%yEdWLn#m>u`^ zsK-uaH=sVuGeXgNzO681#yor@I$@{mCe)T|a5E~#nX?6rWoI-T4Pjot6}fPZN1)-H zr;(@(tM+Zkwx7yvNB*1n%AG_n*kd_`3>GSO8hz{_ok7JDRO2k# zP(-nFX!8iwIFDY@$0nffjHZcb@d(8(pu?<6E+Sh~)xCt`M=6$sI^I{g%cuZP;a)*4 zSYup8buFZ8==~MxI^vHo2pLqAy! zWuO*(R+;DlSIT=d*+iev2h@Nu^dowkHv>fJj;iq)9X+Y+7qoM%^c9_ZD`lZH)>Pk+ zF>{OW=mBT!kGyj2q@QTyXek?+F*^T3dwweR8(DZrf6xtfLUPbtepTr&im0pDKa|-= z%0=gyo8{{!wR)=8&5uURc&Qkw_)0QHwb_p87Q9P%C~nWFT(9Y9ozovHFDzNG3_K&6=Lo1v=qs$q^EEmygUs0#Bn3zXPO zs)Q`r@2QL;m~B=;tdFAe_ZXMLIhg28&UQ)ImvizVL*2sljt@>!Yhq4V&P_SY)=qY`6LuACeY=mY$ zQLHiQd{nU}Xwz_shm}2-1xU8YzJ}Bc#dDXy4vpL)HAm)*rY%qyfBR&QUM^P+hrC!3 zsb!v+wK$@3d!<(B<_)PevR$B7+Mr6k)QS^wWM`@^n$7H?9U7p8i*tMQxti1gsVy=Mdduvd}gm+$oG#l4mIf~d83ldea55YcxeLqv{6}p zvd}Yx`;3#2AtRy>+TK?!Pe$+46q|xd(C7G~Tz|i_wL0(h?NdLgkjCc7>&7DAicm<)}lp zVk^*Q#=Mni;{<6H>Q!C}L8k2JtVXu0r8THDpXpjupHFff>NZ?Qx*knUQEUU6I7|vf z+XAI9G~=u4ZbSjhy*Hs%e-zt{ZuXS6pu~z&IO?-Zb+@8W&Z`KN>7{HWir{?VGVpB8 z^IqFgVxY7GZKc23i7qnh+l8t)DYhG>R#9vZsyIlBLJ{fGUi8LW<@TYZrh2t#bjVb( z{V0c(bqsRg>7xTEe7B&Y}Ix3D2WI zBPjv>t0E;Liw4pKRG+iyBKp!>u}kP~nv{gP#!8pbRO((q+qqV+qK^BdYv>+3ve%If z=idz!&g}IjN{CjuWK@Y?v`;~Q7b|uP#axzdquShUyMrRwaY#kKd5ycsoRRY$%IYoM zM}c=#;{huCN_vPkpI41XXb$7TW3++Sc!HAI)qjdM6;1t*mX6A>)A1S=<*vvZwEI8ReT$mXo4rG)n5}1^S~Zo;MAw-ky+>b} zeSJW`=;1yh`x(l9LRUCDKcg``fAR$#Tc8?WQTHS%3q=J<-_UW+@$cxJtMmieXQ-8* zsCbxS+2}5#+Arj=Rr-xSu?znP<>PK(4!TlXvA@WRb?84-g}GTSy2~mnpH6Sj+kAuh zQN|Kw4bbI!+hChqf(M z%oKT9OaGxctdq;55cZQRpeTAouB=!U z)Q9$}qVyYzS)x(g$E$`$*H$alk+-c>1MOgkswNs>F4aQKOG>rTnvW{S1JRxi>{Zo4 zof4I;i{A37)kE*^D`t&$aK+b0jhQnvK$EMhoDHhFL9vGD-(a=Z2xSp#jJ!KbO;Def zs=*(YdY)t+!5^%6X5~}18FHMWcVvfx_>P(*vx!m*^qrp79$7L!bwGWc)Lu(8lu_If z@spI!tYT z>&rf<*et0pTKP>i`k^BOrT*wX=gR=plv(aTluIw*g1neryQ1s1k{c@dQsvxHbhKiF zQ2+6I-N9%atBE0~ex$NP(GKhCj{nZH6n6bwL&CgLQBheyeucJ^yRy(6n zWQ^*LL5Y`?9gFTUi}XbGn1Ons%umud^q%qD8y#D#y5mv(y~<8NE$Im-qDM)E`OijK`=vRkT0Lnl3Jy_?d3mu?sxcouwo*0-b^oaB z0`!o+cp@NYd_C1&jFuEvjU}iHqt#MmxJB7z=)`!%mZR(3wO)am-cxKP z8e3Ibg)XztAA%a}l~$t^c2d`%fU?qBw46R-9pXP&a9)qDmRD>8iXS6|qMzfG4MQ{e zEr*RL!%*2xs3xzr8TAOzQEfp9yHq0_UF00!iY75rjX*Ozq)1e6plWPG)rzW>?Pwrl z#SYY(`RPt{na_C_T5cfiM#+zq-GfRKi$bl=OMB5)_7nG^2V9rYs4Pz)>__casay;i z%Z%p$irOw6L_JnWhftvhI=;gwxuI&rBCmha5%ib7|K=%DrBN3%s zkS-wO%gSCve~tCdFQMj-)m{=RH(uo~qq@vcuArv$m{-xmGRj^<1?;5js7DuNZ=e{~ zrZTykXPRm}MP2EEpP~7)Rrfi%;;GmRRFd&14cYN( zFHsif^DAWXSxQGvXO(@8I2lU-QZ_hGwCC?9+ThFR!TFcjSLa<$fTCCCdIp zE16SgBj=UM{z5x9tHy7X%}DYGwdFj>L8+fq?k_T7?D>bh)+w8d7W7j#pH6SjzwA!u zM?FU?Yk>Ig`kV`(vKLgYAR1j%u|jC1xoQ+fKGzg0f)eT14AGD3Qc)C}q;f{+QIKNA zP|=4cD|3@akLf67{*4UFQI(7j$NR~hYGrfe0o z;Jsp1ku{^0CHiS9RYTF=l&y}EI;j=js^?u-sU~XYt8%r_TlN!cqgfoY6?(wFavcv4e8hctP{U|W@IhuoS-?NM4UWjmm%d@dc)0%o9{P*{YH zpfkG7OvV`%rkCo1c5ITmB4e)PZs=Sa#k!*)b}M?IDqP7u(S44z7kbX|^+t6pq&~=l zv#u|i#8LG_Ib6T}QCaT94L~P(je+P1>n#@)FhDh2QS5fb+)$>s zSmeU0$P+~bDCUJs=()zBn|!+7=ummJHy)K^M1ftUN$AsD)$l=yjLDOc z*AQt6dN4(GeUTCSYksIQJA6}-A+7kM=Ji!$8ZzNboQ_8KlmgJLzS0bIwymm^}m| z({-w`2#vH>Y%$u}Q(A&5({n9FEe=V`P|a|)w;V;-Nh{EmS<0?Nk?&M@70PjxLQo(* z(rQ$WK4J}W`6{hN?!Q!b9lFoey&k=oBW*wi#Z)&Gb>=C)FyydD*^MZN8S*CdbGl-i z(Wy16u?3CdybniRPD)$Ro!ZJqAOr4~MWPaomEDGXd9HIi3hbur4)p%KvOCc`KHXiY zIG@^Xw1ZXt9(02CqL2;maxe1X`ImiY0yF(+)P$$D_oKOoRW1f?LI+TohCAnjDA7?j_!LXb^_V4wm*q> zwAb;SLN;ViquuwUGpH~7IcJe)n97|)VVe{?k9rhTxdb$U9kfK$i?iecs=89yi>P2< z#V(L}6uC~Z>u4l>-3@f0m$EleFYd4b-qHX9p_w5&d9y@RP*< zno8gQndpc)ihjuxf5Z9}&14>wg%;Cud_(5UBflf70&4LGTE+YPi7K-*m5plOP`O{I z75^{WZ{$gPe~@2OWphwDu8_aTYL;UEP-*sIbCKn1wVY2Kr|0^+iseT|_#O<?M^%PRw&lp|qP)X*4EPuTci={UMb_kNCvPp-K%@&J_I%Q!D==<7ZNN zG$&K#Dxm#86*EKrOC@uZz!6kLKTE0=3uIATu}Ubchw4^FW_$)!(6HaiRz-W06|+QZ zUrNM zp-tn|N?SB)kYer7HD-J5(GkA$4yZJHcO6kwA!R$E3K5ERMvs_ZJEKZ&I{Gf?SQDu$ z>dPqF4OtddtUKyZN;P`qW$P>36FIu;)q0`p)aZ?}x2aqoWO!S#zIm~|iuFSin9KA> zH|RMAASdp(3`E^od$}MJ=B2KvPkG4=nemLfJG#oQ(I8~hTrCeqk<3tspiaM(9f~e7 zQV&CQx+pdreLO3TKt))|d!YS{W+Ty6`j=72Zh?MJ1TQ_@j?}R@2bRV~R~j5quv3X!cxXXQ2KmQXmRwt?Wz`N`E>F`973p zqn{(CIjHzBX)fx{Xgd#`n5x)(bac2Bgg#GJ%L~wzbj21Tri;$OsM{uK5o*Tn*J5OB zs@M_~#cX9MY8r4)i%u$o+rdY4s=H7LE1 zv=;ql&Abj>G*E0kx_d&ewgDM!l|s=DFO>^JH&`)jL=&$`o6z&!%5Fxc0~FhW-VK$) z(GgY*ThY1|QUuDTZ;wRnJXLNRa=IaHM}rPYJJ6#ADz_6APE%|ba%Ud78=W4Z*dBC$ zycC53I!JrbU;e&jAM!e**NsLC`>XDLG>!RT42p75>;NjyjPf9=$=$$1s3kkChf!}< zG_mL}yH!V!6IaDi6ix4a3r02+FrCNT03b5u&Lq#}GUm}Azwekv$3sx*0kqPUZ(R;jdyJQPIgN_X+)2q1b11oZj{e>dDpk z74`UrEE5Oxkj;HD2V>xH%g3_{-BbbmCZrT zN=Sdvr5NcSdR9i|a#5tIluw%$o(n!p`O%XDk^%DHDHT9hSko6ojoYi0LTDDN_QI$v z=U)-@ff3sfjVdM;MdP^^jL^*^YOffIWQK2ytXTsU&&z&Rxf1C4KE+H>GtSPE=q)2j zDP+Wox-{Cz>ZJ^N&ML7i^58QqhvE;aoN1o;?V113T<$rQM`Nf_0WDu5nW0t8jLgww zX4e%_P^4lOXc%X4C3J_CRAuDBC{zXgVC1ZdF2yTriGDFkRzuCEN!5`b@2v)EpQu<( zlu%Ntg_79esEzjV?1~k-#hkwmGU2{{U9^RJF!j)P&KzsBo%c~6b)K(m1C)MGF&i|N z@2DZ_maS|f)=a*Jy$&a~(BBjqXdfD1cqJW~g{=)v!bH^zzM-19uHups-<* zJvthtat)C;xZ9&~SXx`ASS&^qQXeUVkJ)DP7-tXBG?MU@mAfb!Rp2BLEG2QKL8Hyynz zn$9)ohQe8IyQ9UN_k+;n{K^hSML3&=pz$jd8;TZrD>e-6Z?D*Jl&_;=BTz7Bga@j` zYk*1)7tag0Snxm@ghsN`LOhs=DC4V%A zD_|Px!ZA-rl}0KSfNr(bk>|yeX|hgSgH^Q1`8htwt5!E4BtzcqOexDI279sOb-tTaSL- z((7(O0|ONcMeRqcTo}5>jBz9K$*=4tbd~dYGwRH}q%Ei%=Y2S``l;Afba|0t5vVxd zTO_(|E^R}O)uinx(^1-i#xdL6iH0@Q>+V9eHYm0my=6AM2X!y6SQK*Qp66ba>m=<% z7gi}7jbbiH`_WAHj$=>(dZ`2GqpxBIkst5;5ZcIhei*%E2P+metD)Et^np?GD6-=m zI))6Ht;eAv8B#nl=G!`szVL0GKwo)M<|Jx$S+P@SFmuP#sD2;C&Y<58j~53DR4%j#=6}6mUYyK(m*r zy-YNnV}6eUYf2x`F`nJ~hz_+?xlhQHmOrDg_R<&hoc*S+=vNJu%R*c4DE194=AC~> z_u`}5Ge?Rcjx+!LYvUsYaBq~l%Qwl8$P_{HW&{Had>hdnj zqSwsa%AqUwbOffTQFrM-RIRF19=V@Xxe90!eS{hEGga0c_1+>?ME$%Z3-ll3Zza^8 zE4eayY$R1dXG5f_$iK8|SfX@#LQ!wQav=6QOFt%nj+OlT~ee5XeIMC8#J41t09WbmKvc4vy^R&>hTRW zL0zn+rs&p3$rhdQ)wj?Lc~4Nx4%yX{nxldp^=d6pJ;pqHw3pSQ13L6V*_LQ$BgGt1 zH?EIX$nw5gX^nnVlG>oYPLdNE&(j}m(RS|Sv_n~}IoqQ?foi1#>Q`MgI--}1E}hWF z&dPR1S>JeMLEkh1WidCKh?0k?+$8jD zw_5f=CQTHZjLLHTPCbvSQQG>x+s7py-Q= z&B!Ykr&u7eq(`5L+Hl`s7P@#)uR9xgTvB!pGUUC@MK+9n^U&%s(tI?Iu_p*U;o4t- z_OF!|qFAnvU{s`&$}K`M%x)H=m**5)f=ujHZYe66uIw^o7%weHx%9CsklRkxSc!tk zu0mnwl?_3in@Out_dY7O25s_DY%My|R9c73c^-E?nlxLn4JdB4Vxj0UJ#ZNM%t*2k znRC~F6Y9x0y&2Wx6WW4)v*rv(>GY>tQ8u4d1nSCI8;P91O54!2hkA|e=+I-ucA&zO z)XGj2#QJv^YTHlccB7|-72AW}^PNYb3;cD#UbKzpBK9HYDpEAsFiF~vGC1#J(D0tp z0Tjym=pbsxksd;GUP*^hOWsE;ienCU1bu9(_Ku>F+jIoS(9lrD;!v+3#p2QKY{ibF zk7rf)1e(aXaS}CR?sy7ibNBN!>M~o|Gw9`AWzV7tKNLHMOxWu?kEU>EF98`dXGlc1 zSm9nk%@S4aB09~ubqSq4s#p>-$*0(5WHn4JUqK&36}yUVeo(n2oI~GGI4hCwXaV2W4>aS1j`=4l zQdP=E_J3957kb}7<$j}No=N_L=F&&xpoG1O{Y70SD)tY>_g5?zon@CepOzz@89Xtc zA5G+WQUkQFjA|4>3G_Y%Q5ELdg-`^&Kw87jaL*dYf-#O5gEKdA+3!d`|w8qONR0X5H*TB5$=RM!#pXCB)M z6$)3jHEL?3SR1sDPuvMrqL*)r3XWE+9WweXwMW;OA9O&OoNFD?Io1Z9(45OsXEfrh zb23_XP z)L0Z1-8;2Hh)_J26j6LH~cNb{_N@e9g5q)L-HVJiMjqQVuFPHdF z96X~el%0Yq@?H9(#mt}m&~J8orlOGpRKp)d(sxcn&l1sO);QnGtLQ+D*?8ip=RP!cb3ovyCY0t6JHF zemzrmb6zY=u`MW(RF58`%pC3Ry0bvEbT{?m?OoY3kB550c6HF za}fPoC>=t_T-5Sm6wZEFEZWpa*(2x!GpM5|strgIxL+=kETjz&~;`@XVK!tI{I^HT3N-;qjAns0*Z50jYL#DO}c=L zcS#q~epbSlP=BuYB-D{v#%1(}dkI(2Xzom1MFn_o*U%;2?{##+QCYq+PbYfTn`i?& zfypRxklIT@Wx6VR3#}Ti_j?|2F^WDy9agB^V{~tj^aO3nlAa>dr)u#TI_Ihy&(V&N(hF4FM@mC2xySJm zwe6(3uTa=|#nO=@_wZk%7Fo)^LH66Ex9B$ezweMYpI`>c|4Ok;w28CmJv!M^`he0c zmHmi({Z!)!2UZwd$hD z168gbs@p>`Ycz^|tNO^Vj?@5^VD(~y3NyQChz9o8J8FblT~W3%TE`AT6O?j5YKj`~ zmTb{=2i0wsSC0P74t>s%nxi|6m@QDpj*>lcttC02{#8`BB}!s0=!oK{O0Cdl_90rM zHVagv4Vq^zIiY_qlx>TW+e+=w5mU9-9(~G^I-uV4%Nqv}#`bb64)e_!o+p1)e^i$34g zQT0O+e1rU#g`Su4O9Rkq<^=-b9EIXN6dR4sY>~zwGY`F^ zv8Wld0Z&wuSMx#v)fF3u4z^d!8?EK~7>|CHRx1#u<6#nEM8zL7c@i zQEV~2w^_(_yRx%Uu|A5;K?w zv>C19GuVPMf^{t6$b7%*Zbkbtr3hqyQ`tyV&QGyz$fc#~Zbx;pl-+^yvF_c8444t^ zLRZP|Mq%^}dyr9Em5V~_im2RPG@Uj5K2&~}V$sNrHROI2XD7v=3Ol3&s584B2a!=L z=@1%QOs{bmrEp&%7VYK=ID!I>NJr6dMwerGVzw8Dwp~yx9`$BF`8W!u$2@@!(Epu8 z7r!WW3RPl9@iaQxLOO$5d{w!#$eew(bLjk1WzVCNoX-iUUyhWBcCS+Q0=mmPzlf@H zbzeeujBiP(g}q{z(Ix}w3OapUx{3}jS1Z@h4(<(HM`fvT17*C_tKCE;KTFAZS!Vqy z$o;75-a<~6s&N}NV%>HJ{T-}wsc0u7(_M6Gt8_1~+&N|MBUknoAE1kd(nA#ErE-r@ zdT+gt$Ebv#Voy+ymn!!ZS&mZd8L~JiJx6Op)$$9}X{BOmD6yLK5-lyFy01_*u8MSY zw2NY|5ht+o8|1-i_brNNJ@F3pXXhdVl`1b~qL>vb_a6DLQn?SPEo-2U=mB%CPiXN6 z)%c7KGL!j&*40w>D+=NY$U^D-9o9E=!%4C4=sHLL1DUh$@)Py;S1cQqW-R-Ke0eJW zH+s&U-9IRRzq!gm7r9pdqS^(ee<-4(>gJ+;^VD)a4OE`h85i=SXS@#s6vO?<0_Y1n zD+STA(W+Yrb){!0j23eK6+su7Zy2IshgG*IN#Q2JP%1rFZPb@}wiPPuNi}+-mjxB;gWMQH`=ak_mF7tkiI-8=pBa!=WX%q@!7iu)Rz?nS;H5#rMKcV57X)Wou zg|)xM%GC>1ov4<_p@}CXZ?v5n<5AE%m79P@F`7<9X1t?G=*nTmd{BQ6)tHQ$F=L#9 z3a|&@i;S5Q`k{uE6q}0d7b)hC>aq_u4JC5Fc{-ZHkp`f$(^PH-GA}L#q6Rz_I1^oB zzA+1RqCcIDta!>{4!XUmY!AXJul=K|z(Sz3sy7F8?3$bmhI zMd)))X)%f{sB%kC2llO&qRpIt%g{uwqvhx%y%xI#vf9RRcK?NvLUE2J?m<; zKU`Xa>Mu~awWx-ZV(UyK7)oJ;h(o0VrFgWDPy9Ig!3^pIdiYxHokVer z)2C3ml8T*1H|8mJ2CZf<<1FgbPT6zl@&xHTvU{Rz0^0Rku|(9@La_^|DeYZEndXXJ zLTe&)EJ-NXSJ}(xQE%xA%IPItMK5kj*HGONs(T$Zr&qp#zA`4?%*)dAC!_VeMha>e ztJk=Np0c{Tjk;?x;d}?xzagcfYm75@(IH;r9vaOW=RW!|O5f@OWM-i3Lu5_eN2v5x zm3xeGxoh(TmE=2riq^5K_6+6Y8LQ`L74PT;`a&O(hWfC^eu>I3b9;sUuv?an{PrmJ z8g-_peuL844S0)6GwXYY4m01#Kr{BJTqYWDMX~p26{F+_RE<06A5kN&_)n-a>z>bO z9eXlg(D806_Z9t4R5lB3Xs_5e6wW#R9Sy0d8b8pBNhCIhw1N0y3fCA`DRn;hn zCUVslLLmc{EsPx4c`AZ3E2^9!+Cz_26s_S(F+wl6x{IOmi~+`|{V=IG>dNfD1e)us zmQB#$dy17rS*9vi3I(!zR2uC)p=_DFauHHl~EN(SB6qWG&D-BSfD1~6sv@4otG-3KgC?s;IKJ+Oy2d^6ghc z*XfI^qd|-dHPEp&iq%AsRjxM*KciS5G;)bzebFDz@qWmWxp#l`d7rWa zP~`=R4MfW?OD@R5OmamLjLvT8n}v?g9bIE&8iWF7D?1n^)R2atDf^_Ms3l{{FtnY0 zn&HUHMz1>p?bxN52Wq!k?Tth$f)yKuW<^P((Gm7R#-Qg}(pY4EUNtMd|UHT5Z81N`e7<9K&BT}Vx( zadj#BGD6v9D9K&f#uU*sNoZp z+lo%}ghT`i+9gGzQD(|+LpNBHY)6swyF1W2R**YU61~(eRDeEqH|m$FR`#GX^dM0v zf%m%?9i->lhjJ3sN;DeROxgYDXE`YbWpHL6Kx0Ey?jUkcR^3C$y1jH5P2%`sQQSkt zj-Zk}1A7#GnV{@3WXJj~4xM6`DIRSeBppZT%+XJv0km=w)!KAI>@=FTO|diR z66MaKJqr;4n50DAp^h0#}k@N^1J+16xw2Eu>37W%M{1i}1t=g;ME#($Rz4dbQVR<0r-5peu#d%3I_z zO?rp+u;R-=DfTLti7Z*KzDGt?)ba<^GE~`*$c3x%6RKt?eMV)+NMBGGBhFVe?VFAu z3ti^?`-U3x&3s3x4;1@>hS6L6M02L8Mm9Rm&eJb6>XKr=QMkWie^4T4SPpV&BK<|f zrc3|Oho@35I>=lq-vFu54#o1LM9yLZ)PIg*1&~FyR1iJpyefp&Wvg6aRE2S{2)cMw zGDKThpBF`uL6T9PIRA>FZQUhfw4lF^xi|`(AeBIcIeHV+gPBZ8l*Rg}6k_@1TpBIm z2+E+SzfxKBiWPV{lyFex_}K!_1okcdL#LQ$mq*K86sv%8*)cRjF549|N3-3eis;H3 z$pV!MlPaMEu9V6skR6OFC@o2`s;D3D+!EE`TBwH3&XlU722E711}b+_s)_8F%hy6N z1*O`kqM2lcW=~Lib&v^tc3pIn`Aa?2-$doCQ8;U>`sg|LH5#Cn%+_ttiwu=(h}PVa z8ljP=lx>Xea8)!x7npN3MWdJ}+M-1+D%T9Hc%_!@&|Buf&Cz-v#af{A%zf<957wp* zDD9tOEm0l%Vn?)wzsPQdo-qcrM%MR~ZG-IDw{=2g=r`J;#Jeij4!Q9RQ+pIbf7$`n zVC?RQewS6Y6Y}n-Y-beBxbKWU&r+-l+PG7(t|*<=VmIWrSlRCA7T0tSw3jtbPc*54 zV!cq?3aZ;1RjIFRA2hR-TIq{6F&pWJju7jQQY%OUkfFP>1JS2q-5q7J7c>YhAEt7H(c3c85VVBrawzKRp>q6(+n!~ZhYd%8Eu|4?jfv!e_8d?R z9;EXu&AshW$Z)bW8r{33>=?9+RpnUJkgMAhRja3%7c%D_-#B!K^Vu7nm@JJ)*O;|T zK!)52nTURIB~L7s=XPg7c=BQG}Ky}i2@n7W})%)_p?!p_R7vdmvU5hE;{-_v3cka zXYqXWletO|a$()L0DbE&Ekrl@>&Rd9s0jjXezrOA!u#5SS(9aLj8@(q->pnrx^I4Z~c*ovOF}=v#B|T|%)$)QpwD1vHH3nl7T^j5L?fqV-Y|GTW}~WmKu5Vpq`n!qQa~$^7dY zdVE8=j;#5ADsG@@%*1Y@jH#-TjCveYECrpUhq;ArGSj(@oFf&xgGP2zEES#dl7?}k5nIh`Y1I(m9r%qWY0XjAsY8yu|{a1o&|Ppj2gaE ztO=^c?58Q3>aUnB>bFH|hT1a@*`c{y-ObUE!HTs&-Pv8YM>S3;>wxZXmb63{-$;(= z>s@7Aq0~82YxJA{L9PvI%nHc~Z7VIcMTIz<+M%vDr1t1$bG>c{beVmej%YtS1D()m z&g{;p3eWF2BTGiYE+}G(YIH@-e=61ur7$n(jxI49=z-eLQmiL(JEn5I&?{y{y-`hO z7k!YcuhbVE=YC{AG??C^Kl;fCG5{qMl?I}S){+bA9WJ>d=TylJ<%a6j+)?WmiVZ@x z|8y*aQ3NyNA!yECX()PTp>o5}`>WD$G;)SC0*#_i^gt>0sxcDH;CdUCmmMdKMinYc zV^CMly0Pf{1j!Q(ovS18LQ!WG8;7bVOWx>dFSR@#J*%s76Obcg@kC^9ta6i3Ru#zy zou$TPWX(u71!Yf@e9@u<%KD)zaf(evkNc@*f8>{_*fjKKjLJ<%yRR!7fQrvnb_Ozg zp==qH?RzbyLOGAWKG)wJ4YQ;X1UERrY$+W|PWoK;^TgP!vQD5{7InrHyC=YqU-1 z^?AiMqmsvU1Y1!1JyJLd<$lIiG?D$N2;|Rw)yTXo-_bUdTt?cCPB|&N14X=$b|RZm zYGoIyW2)G0^p+lO4|@GU*(kJ@D{3#g+EuZA=%}~KMWZJNl--ZwSX0HIx-QBdK>Ik0 z4#C()57(kb*ZOgfFOv(`L=s?3niqIkxwbEpq9fb*zkU&RuT74w`#RG&5O1yqMK z_9C)moqq|PW!y?aliI1}%P5v>`U*P8JnSl(%Q=1x)oLzXM}OB!H_(ls0POYQg970F7p@@({7T z=llp&+$=pthglswK^r?sPf-B#jc2Gez0`Bmi#5Rubn>xcX{c09)p&{KKUC}$YRZwO zBa;MWU!!QQvNz~=TgBd@3Y^dHPy?P`$UvRxy))4&)@bk1`8UdbK)0$%AJHB5w?3gH z#@f%QHuH@yi2r=W`76rJuNqm%lU-NU?v&ntP+U=r|*6J{QT4u_r&WTcE4~y1zlO0w{Bs zK8=DXKUa4lbedh-!pM?m5R0Ja?0y*{essvWC~{?uV}z1_C{_%0Yb+V(#rQOeqnEE$ zw*=bDwZMNg;A#FwDv5?IlS(1us#0kbT0$y=l4|QU%A$a&ij_m->38`N9?yTw<^Mxl zS)rFlU-u|h0Y%g2n4x#`bp+<954}%CGd28_WU7HGus*JdawbW&Pz`3PwUHY$Ei1&2KRVYzLEOEoi_9EU zt{(ECKea}sIF|b8JoiiaVI$8t#w{BZ7$G%8C;#W@zTgSp?`-}uN6ABOQo&R zSJr^+(KB1c+Mr~<{kEugAGLKr|Mn@y53#w|pCUOTqn9dekFq!dC)Cwbr5#WsdXWxNz z^s!@5&~UYILkZ+pW09S!G!7Zl)3~Fl4$^p3inkIbpxN^j^FXZ_LnorQ?NmAm&E>a_ zJyE_cI)cgQW2WkPAxG93rl4eUm8qyT=YAT>8Z1pm(QeWV^pjQOnW%J&I0KIjN{-W+t@Q>AlJoc=M)Lu1cM^HKAA(gIYSduAc3!f3Dv&9>I|d{OK~ z#TKIwMiM{tkE2?G1~gJ^Df%0!ddtwQcPd?u7LHJC1^RPWv6W~Rec~$g_Kiwcqitk( zYfxY*X)UVvpX84`>8aPDrp>jt^=LfLUjxue-d^2+Dg`RG5nU*tEeE2P3a&CUaZnX zr~^+352IydEl1F#3sMBy!YWuKTF_5hK8hU4y^o=SjG@O-i;jw&K)a_ab`rfGqqb4V zs+DvK-M^#K)2JNT^%-RBBb`NEx=H7d4QDMHePlLv9yQ^!#h^>f17cC1deQ|Hx=P|= z)m%s|E}|7(rAz2wkV-EjGxD%2h@ZeQTtx#JiLar2x%nTO!o3xbPPS0#4fKS&ECC%h z(&xR27CckwEwq6nxQ%?2E*KKgQ3&qk<7jMPhp_0yuy+?y;Ngq%IJ@7~5PLKHs zm42((XVi0q^aT~?$@5oqp0~Hs(c4pM@eLX6mA<2Y<<#N_S~yGkiAIrW{X!#`DwcsR z@^(rlG7eNM3#GHJl8xH0Qj6bcRZ*4xK^e@B|00*!D*cCyhN(0Mt>bTt^9+){l~TRD zr~~U}MkqghXFlXZFO?sK-_TYHpfSv-3ZfBQVTF({IZ|O{!S!4OMfBD_ilTR9TE^%_ zm`aPG9>$6lM=|@Q5~yTDsU%9StnHOTet*@%1O?QUN~80+`5#(+T(PpK&1QOTNKMs1;*bWpuotVpY%s<~>!>6h5yh@?dnShMv>wRY#xbsm)M@ z`r2C!^rxy~HPJVEZ*x>>i&P6WI4adf-h6Tk)SG;~4w_}B(z>V}Pvz>NBRqSwM6Ld* zv_4wK`|1tQOzzc&C}pj-XN8Kg#?uHr;T$wZE%@Y3P)t3kDT-zduNm@U1hYnY$rGES z7c;fJ7HC8h?X4yH$rWpZ7G$ZOEqXIqvO_%_RIe2}$gcymMvo&^YLE6Xi)oV^TcB85 zw1~Ne16o3s(GF#-mmJZ5^x5svMXq)y^pn1`1A58R*^bD-k#<7AmMP|p{K+jkBM160 z11e4C+XY$kO9fq#H+fw*G~j{ibw^L5Rj&uS%(&kZU11*jAL{0%(q8Dr6_xfzcFgno zAcvCLa$l6yL9u@57kO-dwD7jXYxC~M=}QKpaeUrED4@197^QwxJr@);Q2Q8yKE71x zP?SAY8iqVNsorq(xSIAm0cm=o82Uheun&2pC>D;cMkux)*{xCA1E`llv4hC$jOraip-rU2Xwn{)9zm-a z#UoIYt5RfcY_aMcMTtDKIfjb;RO~n^!7Aqol+;gqJBcjvNKxp)Ht7_4$GJL-a9Bq_&D( zLUUO&x{RXev#+2RtEH=`?Gcq;LkB)e*U=mPVl5sOU?z71Sx?YWC7`~i1do-k=D6vHLBW6{FHLG+~-b-yuV+w)`Gdoub$WWHv(eKBAzt(kEmxU8SE< z_94Z-pg>B$q6qGpbX4|*V&72WcWwDQa%Beo16|^Z{fWX@Rr`ge`m0_BsySKpGSNtm zAPaq_FUdyZAFJMP6v?>%2mNNu`-_4&2mjC;Cv7y+A-zQbWGE>WM90Ya3!&d1q{1jMSVvF<1(#H;D6;FRm@#tLqF6DshBdO{ zXyP%&N}$E`B_+{7#`98W4}Ujpg0i_@N~2q6r7|e1om3X>)jx)EC_Y;%kCG^@fco<7 zS44MC>gX#W!xY6TqY2{`tAYwAYrp)+j{A95olVi{`>IzBxdtg#9kn^AdS=LoZ@LER zL~l_O-8iq9IcgfGSS=LEOsO_1SX!kPXfkUVb$XREJ1FLqThCRo4#=gW)DeXqlschZzLGPFS)dl3QJ}Z>VL&Um zXS$%5tp0XInS8cxs91{B9X&Ev+a9QTGpQ%)n5h>3p#XQqdZE6WoN+Z!UddyL%E?1%}YGNvlMkN`U#vn_^OE=VxV;PGAxwpolnT;iP zbcvP4@#rki!6u;H+)*BA{XxYhqR#sin}iC^Rm>CJXeCWX;gwYCg`Bb!n}T+*+A|f! zlvn9Al>ADXjyzaHo`HD5%P7p%VT#M$iHlRFY;TzFuvX(&PV6S}yp};h06LQ+EdYjR|<@W(Xw>yIBewQLpM0+U`W&f6r zqVjE|W5|{q{x}*yuX6&u-K^4+Xzc-QISM5-QS20&L2q{&dHq!E4DuPIwr7#!Abq-X z=r>nUG}^F7EzYCZpHd9s=UNQ0sKhtv0%{y7#i1x>B^S}MNzx^>nX&0Iva(X_3hK-E zdKI-~Z`aV(af)3>5ArJ(k2ZEy>;~#FR>zlsOy6sJH_=1ZCT=0So@#L$eWhL^x@o7< zJIIl~`Y!rzt$_yEo1nejtZV4hkep^OOCOGdq!d!?WQ+$)dJUt5(v zMkTvRPtc}J=_yM2q8884r|XJ6M+y6-7lt)smPW&#%nb9v|?{i z#|zS1w0E|YhB8y7cj&Z@^d9;4l0G2AGabQ4RAP(t37t$(>1TA9CvacTu}_M9McybK z4d6TfhGOn2_C2@WXz2%PcTA-}(S#j}{X&UpQU(fO&XS4TnV)1KYwnM1l%M|gH)_c| z@DD09R{D!B@s8C$G>F+%4*FPCZS$xbbl;GzSYA|#@7D-b=jl^E)Xi1(@}s@nZw1iz z0%}nZ4ZEb$LdbTKR2U7stkNRLlX0jhvRtTAV-(BXSPac2uPTnhCQ2ocXRuTfmAfOA zLXXMAP0)VkuBFlH`cfHm*jS?NJLp zxfA;3FLglcrfMr4Q8c|&C)9-JH_j-9p0G1=J*H9v`b<{c1;w&f)D`WsQz?mnyD#&* z?x;gm#d@H!^A+of3SLp{KjhCh(+lQrL@VgqC!_K^Bro)IqDrTrxz1`a6{T@EPD8;xr0HnZ6t$Rv zGWaXinaDFrv02E^NAzEn2a8D3iQ&KH}$E3=2>^ zea=GEW{R{3MU+uJUldYEZ5QX3vbN}l1`blaCFlUXz*5x3Qd)*uzLA!r@7!A}&<|g= zU5UDqN3KFWSPfr|W{}OVK~vAD#aeXBQ=i-)ZQvc@j?a3`=1vM0XWnE)0s=QUDVdzkzv=2GwRlRVO z&|Q1mkCx=9^Z=SxOge}bn5f>N+!*us!)UpMN{^uM@rp&D_S|ogD3yERC@N4x^^T#4 z(%Q;#)Ryu01RBE=kdw$YO|dAH|BrME_2)V`jdI#*duMXhLpqC^(u|=8;AC8(mpQcmh#Cjp^Nkfm(d93N>`8_*TGeEq?mLK zt!He!j-tm%@u;+?ws!*=lW8TOs3f(xiAHr+>=v51RP}D7?}JpDh%#O%b_b>KzRg`^ zx=k(aq4YY^eU$V|dVmhFhWii|pC%=t#q{XOD1pDGNkJ2zDE0_tk}W;X6=TH{)Rimj zDay;)c!qu~Qt5LP6(YSr2FA;mC}6Z=uh1LLODgKrR9ktCJXlkDgUq+8#alGXO0hKL z+gY)9D4W^Ddz5rtZ9kwiuAz^}?Y8s@9UCWoMya3F_6u?)gZhdNFmk4&!t=G2Z)iJL z=XbQ8Oy&oA-bk^Z$cA~!FZ7Rdnt_goY0H_YmWx_sp^lt`Y?N_M`i*|=Q;R>yd93so zHBV9LKlF!{)*NJZU)#$wM2eoFSYDK|Kr%veR!aF$yH=`~AC0)CSON6$kyH>_@F@!+ z|D}o*Mn!otSp@B8)L<}lk7P78MjaTLilOVnrQ)dWCaDDKy+rj&qCs2-rBK7hikTp5 zuHDk8JAG^!)S8)hS!BeP%b_QXW#!R1dwr`FP%%cAipYVLno7B)(TY_@k&dcY1y$yb zs*0Mol}yn(dW&l4(R9VCqedK`8A_`p@rP^fujsRDqGZ-h&5`L69dj)-z@XCF$c^;{ z3sjk3pR0pn>Z`Oax*jCeLjw~eOLVrBR38P;lNz9V**dC*$Sqv5LM6Ra+6ehHQ>-!S z-c@RXu5*T(qWG$cHAAx|D`t&?EEQ{xcCfC|0yXA2V@veUNylu1syVBLEpj>`*`eA_ zs@Dn)<*sdw-tjr?(N9{mL5bwRZPBBRiaDU#tiHBG2e{T8(GGi+wnwgO6>~yAs;OQF z^fXPS9no^e^G>KxAITXFWUT0n;;Cmqqd50n(99I6D@re`?R7)0%#ORG1FNJSXnD5O z6Yb|Z{SS3|FZDtV%1gabBj%ia&^rgIFRIu^>W8M2<@QI(Jf#|dzR%Kr2co{0RBsRp zX8ti4`E#eZpw{|4nv#DNyAY}FO`l!UAIXiQDgQt3OVo8_FPdO zj%758W{e+$V%w|K4b|YRjYTaxYRlu$9Nu_zM~~O2-gtB>K$?KQkaKyU=j7QF(ePW+ zB;>eN@u`~@?JF0X#TE~?$16}0Xnu+c*!p=g= zUQ6C+ce3iuMjPrV=7W496`O;Oa1YK!Md@wlp|8w)<|8|LvjwQ`E|o4sJGc%Op$p7m zeUUY#i%~VMD?d~!pU%({6go%ySc=-)sopX)bHB74c~p{CAp6eJN>s0-+O9(HxsO(( zH16az$ZxS?Yf;o^$sgIqOY2a08EHMTq4xTO4z#woS~1+oUU6Lq!I_JYxz*{Zh--RA$< z3PFpRJMTtoIpcfKSNgC}REl>N_M$1|0%2%wq+0R1hI2tlcE%u{k7gTxx^%$kt zLDa`dI)rv|cOOPEx7GFtG6`2K0zV(Gb#p|KXyaa5Gv_5>Q0uC1Iz z=NTcQP{LD{oMRq$CJBJEBRlR8RoRRK4I?Npqg9>prV$p-u zs&@gs8m(9yvN4w~qGQZ#E+O~pid{xkVx=o+599e&^rf9**HF%3={nlXcpi_=1xPoL zH-Dj*fNId+-$brlSGSO1i%M^!>Ew=y$mND~2bq7A?xGSc)b<{F+Cj1VD4w;x2k6r| z=^?6SrP3r6#ClFLO3bTR3QA?J`v^I5S3E`sf2i~c`b<{(6vgt)=^5(LQu}?53VEpQ z3lw!o^ETUq*wf-F@p9o@YveM8UqYtZlL>}AD%paW5A@e@t2 ztk^HKjVmz&^&?BmL_3_dw=9%GzmbiqvDWe%E#bTTgN%5}_ZQ7&mh}(4hV@WK~#;IYa!HXrRo(%uFR8*pe9Y! zq9}4XFBzi>t)*fpX{G8FM|YUbmOvT)DlLhYJd{eIIXtm7L9e=~MQIdQQ>A6lPQLT9 zXiNdA9J-mUdgW0qM&}CX4B3B0w3acd68bkus*HT!s6`c&hxfRuq9J8fYKqE}cUD6k zhDp`Y`}&d@%FlVOfp+v&i<+pHjbi2~qk>cm^`{4}jTUmpTc9_r3e`bT++}r9m$gzo z)ar=#VTpciQ@#3V8lSuYN~3>im|L2vdR8beV`w8}Pmb9bxzocnLFWAwYl=?hSKDUj z+Dw&NBimOhZH~Ut1Ghkn$rM^5uLp|RppKsCLijHiZkozhk9>RtUoGNQS}C(YQGd4h#Z$ogV3`-(qJ@|yW0hM zv{H*9C}*!U6rC!pV;P2qxhggs@v~}%5h&%X+KxmQ|0p&JxvZ945gnOfG^*2I^~RvP zJV9_njn=4iELw0&v2mz9-;q07#yoU9`uJU%fXa`MJkWYmX(Fn@iqa&s$XN13uB-)3 zMloEwUMSQ}nu2oplvB~+x6(9pfUIviil-NtftF2|W+HxI%`gkqTP}H{g5=M$QIR}~ z`5>!!#pa-LoriTZ$4_pn(6{{pon4%QL2?E8%Uec(fv`1?Lp;6 zDHe(zGS==zdl{p`(0Ol_?nAri*TRuGWBh(pY@k{kKrU^igXlat^&xaWQS}a^l4GPJ zs6#`Ymk1Qi3ST4&Y^komR z=_PcBEcY_1^G3RYejk^vqOZ}?HMBoN`@N3Zke9@xZeyhzXyr@QOF&D*6uXHIrz>^~ zbs+P-jkfzJmWV=Qq&ujNi%RdJkSN9Oq1r1HyN^5=2Ol7BR>mHpD-#t|mhMyxl&e{v~oXqznD)C&Uuh25S z)l_u2k+$+0wTPD9pn+j3eTx2Y^1MfA%6>(j;F=KA?Z6xd?@`uy?mvgD2{cXUuZ9xM+P#XZ6^9g z=9`7SGahB5Wn3G-QFb-y4@zWve^DG+?mx7Zd@TnpXHJ)Am~_WXrFqdtazg${#Jvu) zzIWZ?Li0+$6h0xSHQejk%ytoLmV9Q0(@SBPmqw=SuVra`JsW|e9 zSG^J_Vv3HcBzkg6Duv>?!c0(;NX1Gcd-CEksC<&zmPO7+QaMzexl4HzK~_)!9Xh5K z7118%`;|}$a>B}JDYL99$Yz3CR7E2!6f;Ew?kQFc#WG@7M@_v{YKGQu=hZ-_%y4U> z0pvsGD6*SkwGjW2fT1?pm@QeL5VC?gXbzcgT~xHKR4=#mfJ!Y<2BTknH1Lwt0D0O; z4N(ckS}QaTH9}8V^Jt7>t0>k4eY-3*MLigao1t)?09vDx%qp9sKg^z5pnQDFmdK3^ z#Rhe4psm=VCyb4DXg90-t?RqEvih9?ttvck=h{(<}QwC zaU<1hkDl=Ef)lbksCpfc3+J>Wx_(HpPN+EN#ToVCtaV1FWHJVn$*i&qI!DjY6;0%h z>V{mmE7lzyW}eprReq(?o+$I0w)`Ku)l2Gy@=a1{Z)Dh{SRWK@qFCSDQu611r~qf9 zKWaNgu>t6_{xJ+h`RSDhp&?rp8;tr_mt0VNFO{ub}H1Vh8j}E%2<~nr6Ua|G4yQSI$ zAdftXZ9v}-s@_Ia+))ZdF<(>~glysz+k}48yKhEUVx%o7&|Js06=gdpwhf(asJ7d4 z>s^p`ppcp>-H8VFk%G|>#++Tb_1Z}x=u%T{Z#VkQOll8$(@Mu2ippguwii`gB88!P zWL^7E^G~W5jy{oH>_?W>wdDi3_42CTL1a5su|sHQ59u&kZLHEGsMQ830?p%!iA3MM zrK4ya?+F}3MbZ>Ij&Aa#^8~sxOR$zrIQ@p$@MVyNvowldhnM zfznlExTAX45Eq)^I&xtYjYnyG(>G9I-gizw6S(7UqI7cUTWEl}bQ_toVwZ@{G6T7T zuAh+ZqSzT~dk-CA?s^{u@OdAg(Tk;rs7SPwgx2z%C!;}}@f7r|iS!8Ncxfw-(X2Cy zJwZc9OHWY&^1f%tkKW`t>ct)R0ySgR?IkKVQdiw8beP#jD$1h2eT^EpsqGtN;HlDE z*=(ojRzQs1G0N2T{D_^eudKts68KBDPs)%Fugc_e*C9dD?`7i7eY<}0dBj*^ak zaOHeMr;kYAQ9S+p59G+&(@!*Rp7!wzwK<^eWuTIXJD-y~8QMIYkZ&cAk z+xvqOS<(56^0igzKXmrIl!FczSG_#LrE(l|UUY&pWR$Dgs+SKPE-&RrX5FO%Xl%Ar z5G`Ax7KPBXaH%kQXs6O5=uoIs6a{jm#)vI(ca1+UNkn8MNMxgRt`1(sJ7+N@X9K!fLic(g%wf!O4X}`a$cyk zGOEixQw1GgEmcMR=#5Qt#ksGB5@=f;t=%k{A-C>Q4beWO?_@>R#f0q@jg=(*n zY9kN!Yk}HvU)DjZb2C7cM6Xg0g}0I{(PVo5`sjwM)BsujQfWh!bWKNUg{ss4H9}$h zZChhBfIPej+E0t7s2^ifGt_ODWR3jzyQ${rg0EsNkQW(NOVnV1Vm9dIUv1A8O&cuP zAt%;=TA`!dTdk21d4WB$-7B@pRVS$}I?w951DfNlt+Yc<*Cj_3HePCv4CU0q3B@x5 z>3}-FQ>-Jp$tUWB{%~zLqa#;z%$-qKZ^aDAg72~m8tJN7SLF9Vv2Li$L#aDD%{|xy zE#I$tJyA6J5BZ{AsNV;*=#8elRjd!HKo-K!&%4j0AL@thPFHDvl#h{r0P1fe4Ma-@ zNrTX$chX?gXPLI_g7OYkYzW$2Oj{X>sy>y5p+c8cZ#Z(Vt9m2QFM7<8=*L#YMxpX# z?yjh)y<(%0TSsXO`okN%Zm7ydX)K!2UZvwu8gn3bbcsxHJbIF;*aT$vQZWyd!JK&_ zO3kOzNhq|Fw&IBb7}X}D(T`Q?g&MJLH3gM2Rq0ez!$_sm(33aPbTpHZeFk!vE6qe_ zN=UO%8Z%pOwE4G=Wj1Q=qqaUMl(Ao0|(X93#sUR3Y2VqxgW9>w+{$Kr~GqZH2be)O0b%>lHX zdF4S=p6m1w3g#X>jOwjd>L~!UQdcfd3g4C9(8V|7BR^8kQ9sh z(<@&<=EUMq(+7%OM6DB~OXxLsz-3hBi*yBT@sqBi8(d-6(3lC*brg13ZR63|j?xV@ z@2ZY80iEW4yNO0wD|QP_=dGvPsLMo^Cg#S-;P0T-|4DbzhnZ?|4~3HF+(#pM!|nkp z|3md2qD(6(2_@0*CL=TY>=d+_`|=Sw!FD=x=^Lt6NiDvkHNnykRGC@!Pjq>+ z+WtZ}t<)j|C4W-AOf(=}rCDeUS7$a#BfI{M_(?^>9~949Xn#@j&5Hd)$2mhes5@Cz zo)OX+uG758BT_O#6YEO((7UBle$+ih`z?SD^Gz2-OIEA25L%t0V=0U_e^aaoDnyo6 z6h(3O7^8K}O^czpOtmPEnz7#!s7geZRoVibCA(>f+P_yl8|3IK*`jLYLwI+MR9lcK&J!Lq9=-Bt^7Z9 zez{`3P$chf_eSd%OMTGu5r0F8ySFRlC2L!H;bvoAXK)FG#K4t ztZ+dVWWGbt(0H{SisCn_?JzXZLK=?7Fba)8huKlY;+ZrTrOuV+p*H#T+2*5X-rC9nREO(jA)02UdW+EUJu3A@ zMKYzuD5SsShwgLbEJ6EO1zUu1ffjw z-AyQk?0+-r&b_q-y(^`yY(<4k6x)UpdrRBV4}R5k2eKkp*@+f*(N==dd+xGbXuxa5 zLeQl0s<#`3@ic1>YPw4GLQ(h9(q6RCO$tM|pR2__WJ$jfj=EM-+x=(?bBF`E@{kT9 zi)57^LhpZTD~FL2&l!)P@|#o|fs+5KMI;*jpGuD+GqT8I$c_x^I2yTM^-iFWOVUZS znEoXSZ5S?{LY)q&^fX#hOFDycZcAs;oCVT3^x>xzjkpvd5r8QNl%dHP}O^izU+{mA%|7cb2N;* z>;(#Hrz3cYOgAd_3R&e)vY78@p)MuVA{$*jtQNn~cruwk=u8diFAA8ZdjHVUL#mg9 zy6{vak3NEXF!^L&WE8HL5h}$jFdw?oRdalA~2mNjl zbZ)e^QWRC=EevB+jBC6YG7prBqpi$mN}zefN}_^1BPfMV#VTfkHl316qos3IS_XM1 zDOMKMxS&`$^aerFBt- zerj6}P37$mOLUCVP~8t6oRcgN(5g zI?5g3j3$vuGj($}=ItH>>OMp2f{Oi8X;;*8m(&eac&O6us0`Us4`lX2v7YEuC)N88 z-6L!1g^EO|v^PqhtXLm()kbamq9l5~erN+3S%0*bm7M{oKDpyS6irSz2z`7j4Mx8$ zwLKS9EL$3a{N`vYL(vf@#fBlz3Hm;Uqg7=T8-X0?pGTrO4-^}P3Xv`GLm}?2&eCY) z$z3)EjlZQWyCFC7m$4|efJ(=qM!ytuN1<`5Hy%CxB~3sDm|JqNYrpf6(K3}TKuhR%7osND z^7mG~#c0M-$q#*hCoMtS`QDbI$EMoyGSt>WTUm~ZmsaTt6w3^4CECvSwhHZHG+m86 z8L`)(CuAsV(F`&Qf3#||V(XCe5yjS{licwED4Lbe4Je(yZX=3}QE4FB%NuM#D1)=M z2_^ce#b)#;Oxl9Zu$8SSX1lZvB|lJ$?PxB~t#+WJjIcYAeRO+;^Z>Pfsd^95 zmGx?ygwE3!CnI~#K?*8Pukr}>AiH^t_N`EhCun+Z{)c=Xsopb`&ei!G88K6Of%iDuy_!}u34Iq>Gjp}l}{6UUu6#I)#7m)s;)x>g8esY>TqokGxrM$?3 zvulJhlB9g-US*Z$M=3lPFM#asNCnX<)(Q%tjhD3L!l-YoR0LTLQQM+uFUMz$m^c}V zq001J#gQqo5~x&=VkJ@7I;j+D7$%vZ*F4cKjT$VF%Ah{hYFidLzfr6l@-MGgc~psK zR29&0*3BxSs)waY=)q2vRz`Cex2m9JJ*2AW$T-zAMTJ?PtcGUZQfYOR!r$(ip`DhB z)j;=|(bq&LKB|Q|3dk$fLi~uOp*Heh46s16IF>qS7;Wn!tIIm7dMK-oWQn$1P`&!7 z9Pg+#KskJG4bd-h6)SYAnqrO65X6$6`%_1iHbE(W6l;oNycBDO?)Ov78WrEKEjLFu zxprHi!HjP$(NTI^8}x;h1Y6|MRWUnMkvp^%vN@(Lw?@M`K6~UtPuK<(9j3Nz(N9)| z9FWIOm9|5fWc7|Hl3cVs8Zb)roX`hWH9DZ$o1~7&hDpVtb;=yQKfnZ+d}V=q*Rp8+F;J7JX31 z@rw0DHch2|=pUJWe{^r4Gysib%o~Utcm_TQ9S>3IV08PQN?nj^RmFy&gPl}wD9YPS zv0-RBe=9H?nejPBpvKJ0Mxr+4W~0z5j>;8fa3C%KUYdaN`b!?Ur92g!h$=i&Y!YfaPFwLrh4@61QQdNq7b?p*I0Y5w z>`q0YEu?Aa0b}=cG+?kaL(&^@-dw3OiT0=0o`raw-{74q*6C)WTVy6asARB8=b-1? zbu@F)3+Bi3&?qBmK62pGEkJg(Scr;|GcH1N8mO%=@^X@`n}3qNcPGjVvpzLNBtV)o3Sk$Tg_!HEAvK+a>vgz-htU|mqa&zceklTd=R1!? z_qfxKq7>G~j-gFIRPQ(nW@?DbJXO!^a8zQ=JOJJo+QYVJ}AbZNd+ z5@qJD0HV(EikYAq;c8nN73Q6zGH95q_E8r3wpP7zs21ZwdDPZfs(|`3##TgaxVtN% z9UdyJj5=PFs-V*!RazC@=&YD2%COZws-Xn_UbQ-UNv>*!`te+=2AVrYEo!2%;fk4~ zZpCz@wa{a7#@c9bineEgj&mK!L; zTC_*6Y2k#Hgh(CGPDY`Q=mG0$ozUntk~7-hR_cs~=2JZbT6#(9f__CwU6E~!)D4-C zIdw;oRTb-j4BW{*Q7tl^|ImZ~q+X~ExpZ&znjWMNvZojAi)MG1`k~RBq5kOB0%-tB zI;zrvs6F4{AT)zsZ!ntPM)h1!nXQTqL4O~r-cS@YU8Td&4W7jfN0sTNMxfV>IK1NM zZu3+vMxkY4in*fJJ=JzJDzRP~gN`Pvo*NooMX|By?-#|!q0^izceLlaG#+i>?w)|m zcn<1;`gK!mA~KXzy-B&^40-0Nv`QzV9<0xJp{L~kQ&3Q-G!?a^|C@&9a}K7Xgt}@m z1Er)(Gm$CZ`7G3ee$5;0&acwhXsxkgKIja0#T;b)Qksj-vE_LvlezkQ^mCqK3()LP z#TKH{opj8L(7h;?`XWo_+l$c>7uEAajd*sp1f5@@*isb1+WRsT)K6NDHaAw=6{x6_ zv=W(+U#&uS$-`Eo*_EX=sK#!!U5l=tk^IpOzWsG*K3Dd7G-!$xfbKJ5Z$Q48(ni#N zo7x7VYYP+$LN709E1S?kKG9~B$e6MPO*O7|ew-in1H3)aT=A{VZ@Fw}%mZ6B(dqtbBnj?rL0 ziW#BU0km(C>K#N^YAALHjU+2QjLwgij-YGgW)Wz257moAMir!^=z@uK4E?*PddE?| zwQ73;MU$nSL^<>aQ7D3u_!R12Rc%kBj9|sipf#0rU!Fx-^uXtk(+q7n8lC*1*m)FE zT8hby@fmM)?6x6)-)jn%#@h(FvlTt%5Xq-)5TIn#AC zkf%@asDCrXZlJEzOF$pCX)8C;uy@iew3W=`HgcnXPDCE84BSEX9n|(N>bpv@d+1Pc z#qOhOWPK0N3r3BHXxIbAl2A`SDH%EKkWx@z`h!QP2ff*26u>w51bLZAPtoYo(lg}2 zeBn7d&i(NMt)@SCi7Lb@_6jZArWUE_C3|~~YM)o>8&rUv;Vp9HzDz?I8x?zp>?SMr z9^K%Ke?TP-ihV>ww`wb&Q27+aJ|j0W&@ZSBcjH&&%>U_;jy4Zgy>ICDNtJ#_skIgR zf!^*@>?i7cQn6p?HJ>sAE#=zCM3s1RE(?7KlCsh2`)ctU%_RH(gPO9E`4`1RtL;CO z5vdkAXj-CTd31{1yV0}eMf+HrHA0j4j`E>CgViEGYGS5(1<*}0ih}4VM_LH2Y@*V_ zr~vs|5%ln(R22C>Q>igZ<+>_{YR^(>apb>Br6tf_&QM7dWT99oWLrrw6Z9uaZA+t$ zbEGopL6%C(qS$kal|v=`6)TU7>DMZtyJV^r(TxXEC3Nny>QzP#f2ArYi!r$>DsV+I zMd>`ztA^aTuBxL=+<9iGzMb|_1EpS;YNEB5Rcem*F<#a}VeeI18>NwZTcEjo=XKBs za)!DnsEt$)eI%!`L~;3~`e@Brl{P@n=<6Dy=d3eXp&aD#Wx6PxA9O~u92M(~7I2jq&|R+1E~pFZ*j-UcMx1VF*hH0fM~MMy+XKa|QLHCgM*s33 z>P@fQ3*E7mdZV@+b02h_^U@a$qDSwCo-=;*N2>~I%LCAUN(Z7KMvXxzmgjSW(PA<( z7Zf*DEry_ZsQ4_BY*OZ zG3ZxI?ZXZIov813EE>g{(Ks}M=MU~EBuFjBqy9If2`J~f>Up4d+_e)?^Y=TZxYUr|qrEExo1| ztI-bL4_t$ar75-+%|5Mq{wOaikn2!r#nzb&d^RYd5mJg$gQI4?Lt5D zOCiXQwb$L~3|Hcw+|pFVLeczXYP%O@aYck7Gcvq=$gY%Hgd=B0*!`$C-^T%De^6UF zh|-5jhtMGAzlRb3#j4>5N=}d>(5GWkBx<}+I*KxQqH+xV8Ko^BN3q`03Dl2$oJ8YC z>G+~hb^d<+6neuMI*s1WR*N&JZ71n0vf(;7hmKy*R-(~1`r`9w2=!u6UwYtJA zz9FiYfUKHJH<3{}=@#u3%Z;*|NPP1NEm+RiwgjzY2grrlKf6CD|* z*e?`JCX<28kEt{hnY2?Z3;B`3XQOD2{x@pDXZwSkUMTh##n6NNLvJ`kIcOqxXr3{W zwWUh)qMdBT2xa{zk$gdE38g;5-zw+OmM23i!Iah8lx z6!V^9=pW;6aa4J)R05sbCY3}lR;pepd#AxNcmD9K*2R*2VN46TtR`HMYz#JAN3ePNz17uC)%xho_4j(c0EU~FPrKJx}*7wRz1+HX^Qnk4Vkh0hvJGV)(eg0T=hodS4n+P zax1AX`pP<2KeRJa>W{vsN(0a$^4NjMnjC!)O8O=ZMt&nD7vx%3Ery^}Q)wtl;92W1 zRFnC~a5ULk8iB6aNF&h)M(0szEV+Oy>het*jp}lwW02K+)pJ7y_(WsT^WUmB4%zxi z?&!}3X*@Eu(Gg5QTkX`s10DUN(uwHZdBr9n-+798qK5UP$td85=o3aiBoWI9=ziQaP7W+BhTig_b{<^i)&!a2o!(A@#j9Q5n9G#3SS z)ZXTy*vV=!ADyEgUx3!kloldRonaB0k)wLP$ho3oi%|tWxgXl+pzSR|Z;C6n6jhp{ z*fO-3b=&30cCFg3Ky6rESc#kusl_T}d{XsRqn^7}x(1C(QR!NgQBm?oEtsdQLx&kJ z*Q58`c>!p*v9tlbIIit&M6X9H7KqlbQ!EIb*rc|b&2~66BG4-4 zZ;@zWpz0k(+pB25$IxB+wd1IDJ?R8`l`5S?PfDq66e>r?eF_~tC7niv4oGKE4s+tO zs4I8qIn#gsvWyE~9#! zt1Db#dGwLp8o|};-J!(=(f8`Um@9MBq^+c(m`aMhLr2>v_8!?4)De6@8yGo1q9f!(pU@C`uFq&9jW9XipW@OGk+ZrElmUz3q3@rN3f7(6!TQ@e}P}UEmjb$rIEJbfl?bnJ7O`Z?cd} z87VtAc187mqo>x=A2fNWO8+AJ%WC@%U7**?L2bC!^0-M2S#ijV9`QD;5&HLCE%Kow z+(-G*WAb&%VV`Ihw|6fQI$s)%z7)JR(Did z5w#esSS3`tl46xnKhAv>#H*TyswkeTo&SQ}J&13=8k$VrULCp2S6egGjNGCIvYjK< zL@mrDbM)!8R10k++pLZFPYewfXn$#`4$9)5;q^`T$6FPvhdR;L620K+tdH(gP>i22 za&O7Ar-mqtd5RU9&o|fzjq52jMtAA?o1l81)V3)~zoesYhMc&Ht&x3EsX6M)YF-O; zXRPYAL?0N%ZO{b9OItKCL$X7YxyxE1H;$?`T0}Ntk2d|1+MuAhDs793Fb+DPMsKBd zD0zoU9nrxpQhQ_`rMCR1R__0Ebl-6`{c#+}?Y+w0BP)?4TXs!rovBVMfRTA^Y?!BkH_=z`Fy|MbMC$8eAl@*Y3%M>Ap=G=Yn0JW>WLom zi-=xmOIx*PgMJQC))rl351==?#LC|erOlG;(Q*1>2NY~Ri04NGk@FpC5L&xK*}>?pvor)1J)l;ckl8!Q8Ce`r)&^606S9Xq$s-jL8#! z6LBm$&wDfu)%TLz(Lz>X9wc>%g@b}>-ps)Wa>xo)@lqRBdd)1wUQkf%rp;|mQ z@dik`G#0Lz<5GnWpUwWXw+COq3d-y1r;C?fIdd z89Lf5H2sFMvr#y^WOGpLNoD7v%)83YLy26U{^;6HwK5+aj*tS-seH;VK&!thwh#qh zQ*061R9p%~2K|&>jJEhF7K9qovjwBc%$t{>Ku^U&&_G7LrRdju#g?HR&7|dM@;}vB zfl}Wq7K%nsS8OFZG)u8nD8WpzFciXUU^R*lRyG{1XT7}!eY&f1YmqIp+jVFpE8F!b zf<7|>txS?4QA_TI4ak#Mxe?G|%exp?`8vT2x>~8eRT8cqei%79(OKa8GgOYh2ai|nC%DpJ4 zwPO3w2<8C$(LJu%cx1}_^#IDesB#C<5k8{?WYAwqMCqNBO+wl0RQC|Nz~_4y)h{d^ zLEY$~kD>~-q+`hMwv>!YKT_S}=;RH>PM~||s3Rp_#kvmVbE})XEKrW(oWtF{zc3Mc6(Y-w?cLgnEm7R)0y6fFYLtog% zOGh90+^(Xrto^T{hd0&obu?yyTKNx+$X4tIYRhpmP_e73aTBdzEpiJzXWnub5*{A4x1=Vg1D!@qQAw| z$~P2#P}%Qj1$W*L)b4}y6Wu)~{X(xMs>W~Bz+JIF$Y;7@e^Gr$#r~lqTpRgR#3PZO zH9xX@EfqlL#;Zm_^sk~+2xXR4wlJDFRIwuHM4)0tQTs=V6+_NHq~d5&oU$d*I^O$| zs0A~GQfO+BvZc|DQ&JgJ!&TX`=*TM7D2HMSN(N{Rcd{WeI3<-wH&_Q&K!zNxA`00e zRYHmPq{`?iGma`Km)(}Cs0FcVXzfqMs-qi>M>Wv6SjB206Gn|%$Z)Q*wb2Gv0(H*C|Q}l=Hpg9`#OEEK4;g?!&ftEE^%p6VS({G8YJyq5Mtv6MB zti^n{(zclJ{{ zBlA$z?SlHb>$qLfJXU{fC40QcQMNlO%<8HKYLlp#6|!b6Y>k$4$M-}{8cMy8Nv6u# zpuT-o&K6CwSGG4g!yMiY9cFD~k7jY*JD?TWk|X-gTB#4ZFhlB#e3mNP57`e>tUnq( zN3j8DA>R%dh^!eG2BGH6Uk0Pu+{r`Gvv`$rLbVxdozd7z%DN!`TZ*}&2*%Z+D7BGd zZm8;BX&6d6pc=!`6P`$oKp`(wV+yS1b1Xsz#yjVrWCZUpLBrjB>i{y=r*~6HOdNh}&po1rr zor;b>QEVED9xM5vW&C}X>8RTq#b%(iC8{wKec2)TA_qn*KUC38nuT7mKADYL{FLUP zZS)6okqvXHd8i}n1b;M&J9IuWXAU2L-m(+C0QH_IEkw`PtK1^w)JzIQtNGt$7NdcT zTS3T+6?HH&{v$0xSMKO&A*c*bkC&olZ>44EE3=m6$SrUFht3U9HWY=k3$PLubx*JL@h#oN;Nyt;Ul!%;Clubf6dH)Wf=d5QAqi!B5cLdF%FFuM!mXeO4hN!9Rv~F>~8*t(h`-ufo3;X-3-*uO66{%(if#$C^JGeZln2(M|V(A5$P@(8z9|7ar{pi znJALAdKM}crEE4D#~$B(G$2lTfOfknn}h01QQe2AD}RaX5i+)s9;37=YVQg9#x?mA zZJ?EB=wds?o}*00s28a25$Pp5&wca?dGciUHJZ>xu{S6oS>@g$KU?V?s=`yv_b85e z;s<1NOK18K#WH?;LUn3Mxo9=l-)GeJxME*WE-R(4Xj~!1z9ECLihW0uIqnaX#{2RU z^l7nY zffZzZ)Vi0l4NzHQ#;6lBye7z&H8DSW@+g{LYKqD?QMMV{ z%^hWmvKTL$qoZBbo*D8RF10`b+{xzX=2w+#iN?*)`B|V6jHa#f#9XB{`oZe14O(?x z*|umbt+Ye#JEiu>xrx*PwPZHe5tYy~!`2enomMNIP!69*XH@orvRzPT_ENi|N;RZz zh(EGv+a2wtNAH0e`bk#Ehn+`jlunHQn$#oqp41C%<}R~Ai&-z&qUSs_?v3KuZMH*2 zZt7_E$f~+(I3SM%WgXEzBW3%bl8hRC(dj-a*Do)|&Ub&bn7Q`=G@Lo`K(vp!#UM1P zwKN!=p?4gDI`jEDq1D4BXXF#3H9Rl&Q*}q6 z?ey{^kx7cOqtGx$=h5iIQpLs~)9;FnMOPb0F6xu>I~G8dDu*p(?)fDQ5i2~{m^A*L9>uOJHfM&2Rll0(5k)4&P5CQN%K%d6=nTV zIGT?XupSI3((=-(n8dXJ8u#Cd`GcB6mV9t#VDEmx*!xt&mWAovlp}keVeXq z2%5^#mZCq0Rc;w7T}iR!sBbH21=`OVClr;VPh5#|mMXRirEo=rp&QZ4u11BwDjSaG z5nF@i2S{ttvWwC>biTXlu18z$t40L+$euzZdW$xoU(7o1ejyl?Q`p7nO@fmFB7LZWMS>*%-8q zeTG=Hd$h{!LH4gzE)K<9Rdz4(=T6>-ZdptFQ8b@mJX+3d=>WPmSvrWeH>REhtPL-9rrMDYbqT1g>}=_(q)ZkddXLfjeLC6`G?C{4Ptl-r%05Fb%gP&=`CtN&+rbpMoRC|y639<0X?D5{)jyIJAR+g7(X2? z7nM7p>}Pb`Rdv6hw;L7viYlin_6?cDOW%?43h4(b&z{>)^p5`T7kb1U^&44KSL_eE zQ9!Z3$dhl4{X?lIbOst)v>(ApoFDaDrdR>g<-B4Akz>3DqctYBiKfBRB51GH64RYLrFQc1h)s$0U_A zKs|peW{5UgO6AcxuC)rtpILZCw8B}jN~labopWV0wTW7(fQT?Ikrqrq5Nw1f{d`YKoS#-fxBsm|dG9{wo~Y=4e=P z$qe;cEVanXUXjdER1wu^iAFl9JquJOPT5wdZ(qe)qqUW!HYoVGYP3aj=xy7fw+YI& zN8!A-4#=7{aYuA4Ls?6dxkPn4q1YtFIwRvNQWs=hOWCgIF85J4^!lh;>5f|S{`Ejn z?1)&Qwaiql(bz`H_C!@Z73+n3nDyBp13q6{RE_tqH!4|KvP0&4zV^tnj#_a*qZlh3 zQB&qVeNcT@W&5IS^xpl@i*3sGM^{HEI{;mxUmJ+>F>($<^S7(qVB}I;M;n3)v%+vf zM;9sPj1H4^LD7t+uBcdBwK5d_sHv@fbnBy99*g$)C_4_FDWMc=VIezytZP5}troa0Z@eIcwdCsNo33 zCZUt8?!1t1VaXeXm6j%>M-6p;Q;-*T{8SXmigX&feNr(WYzu^jzrsMrdWpF1xUanabWMAOzQwhDb>9vgtxO3EHUKCJf-BA526n}CKhD@a7nu~HHW4U!I_ zIsc@?=rmXC5fm~>XLS^HU!~ZwymGZwE*Y6{M;%9P7+p>vf97i^(V;rZoBe-%4}7IO!jMaj%~&Y?EV6+4ffGaI>pyqJq#M8h_zl}qSsHDxa&*SHG zVXyWcqSIN@BUEmpUdLlpnBAEt=r}9ur|7qx^bEQCO3#tg2DSVGO<5wnMCN=luTcI% zD)$=A;XQqWf?r8*QKdkYdxspD!M{gSS*v|OIgH{TQRD5Z@d>qHUpW{3>8b2zG+}`B z1$i--`ikxs*6a9&{KhNx9eMARexTHM(oeLB=McY8(m5UDHyWFz>>m`)Rs0uy;#~eA zD`r~xCP;_5Ci9~cJSi-IIxkSRAS%XQOCdDWMJkNkm=6`n(3bX=uSb!s-Q~_s#_IBcTlVvat=_eI{L@wQ3LsVs%}km{*zP- z&0+0V81KR+73{Iofet<;;*RGqM)w&Oyb@QU11y zwM5OE>Z~l#!nnq4=Tm; z$iAppb!GVjtsd>orT*v#v)cj4g1Oc}WM4$tL8!zeX)xLqBMm_{>EoQx+E~S$QGfnQ zx(m9oTQOHukxywTdVN|gyP?G#cNpRe=eEQ1va6*L=o2IGNOXi(J_^lSAdN;t`TWPA zk@T5kQRNOgmvLwXJEQKXxVtnS8I6@Z&>}w_V*+ZyQ&P{o*gM50B4>L1NobIhxj87Ytlr(Z=y+MRHxJo4s+>RaVMRC}#oU$x5P#Ozb^&_D?!!WK zxRzpzP#m*?KomYz*~O?BPdbCpQT`TpFe>p>*(K;4*Ix*#&hz@EXw3n|mLWTK3YVh- z^w29%j}=lV>d2?M61mcku0nMpq%f3lURsSFwUok9L9XI8=nb*8==v0C9jea#vmOl} zB1NF9ZFKgLD7%MZ8&Kcr(neIEnX;RZ&mw6v8oNr`g5I1}xvj|Jtzz5IngV*2QRq7R z``eMxIB5s+|EzL5(PsLFUC649veD?ep<=tyUV4)l6#qhsMMlgO_Moo*ip8NwcEt7~ zH%8HYXyq2g_M;K3v*J+(@4*4|cCumz(drl}0hxy=n}`mu=1W4^ya$KSUwW*==r-^8 z5wwI2!+3*%RpTW$7fc9w(hbo;(#fjSlf?rJxT!(is$; zDxF1h__WTU)FaY))bz6IUO;x%id{q#_bPS?Jua%)Wt7WP@GIyYPrXvnf98s%p@O`k zbd<#RE3cwjjDOeAP-fcK(d?mW?>}^(KJf8V%->cxA16WJV+DdaFzRv2HGk11#MxT@fD3>PVo(0 z+@RQZlsHkbA7~<H6>K;4;sdI+5V!TFQtFzgprg_OJk3cyte$v zfu}YFQ11e&TM*4+j4gy(wo|MyI-4LBK}DJ27eyzTofShxycH{sF0j%ofnG4fDv6Rd zNTpClw91u62OShEgZ|JzmqmuFRks{!Lr-XcVrMIBh~92htUO9&u2lg&f2LSPwCJT` zm5_Bg)u@cBa!po2ugWXNhLOj1p7B;g!v{&#(NRW&8t8tUR1=*DQMMK;Lf>8+J@!zn z4my^omg}N2u2MZTEkiOwO}k3<(H;7*258DowcHSGJ)u?_AtMK=F-jgG8KZ(*r6#Be zb21a;$#S8TK+A7Qj>z(x)Cc*8>RkGwl>ut6AF|#d^+$m` z2^)aA+Nj1rl*3AS5c20<9gIe@J{f|NV-<5k7Q-cHlx?Q03tAtgmR-?rdV!(nDRXl- z;D^QJLqDC5ysRD^M19CGKkz3!-% zsg64yP3fU>9w@iJViV9iBbD<+t9L3p5uIqP*d%m{*^(DBsVRA*87|UfWY4^Q3L4CN zFcnSU`=rxQ4*N_#Xgr_WbmYdF&Olxv%FaZ^)+^?V>eCDOp`BcbvrrhCjoMIm4w}X) zXD%}4`kR+muA+|NkMf^a%kxn)Uu6T((96m$K$F%fwh;X?Q!9&5l?SR3h^+W6&0;iY zvtmK$Bd;SES)WoXOVABQx)5Z?y|5H@iI$e36rNHoM~@8@TY(lglS0w=7Sc)-v0qw+ zGB`#U%HlI$jZ8WFaP%QnT7yEo@iEv_PMMm>zx-WK$Ub;?#$y}e@F(BwsmMWHe5`ff*qx+t~-@$*L8ov3eP zwYLkE2~;c^?O_*rH@d(G8-vXFMprC~udDOhgWPXQacB#_?AVJMv1`5$h2K=&{ixYA zm5WF7jw^NmEh(eeLFB@0I05Z*mlDzPXtk1rb}m!w5Hcz#9Y*=-k&d8WoYhhEkoDU! z6wU5yGCIJ1%5ju@xCY2jL3(I8Aj^QJ;;!@-m=|41KzRKM|qv&5U(8goZP2|Ho`xctfRyA&;gIw8nPz{cD7ft0m z3-?f9uwt303bUmwWX?F4jm%tC?mk*e>;cMQwv>as`8Li&)Y(U|M`#vf@?$i9f@(ZL z>lnqKq8P4&XJ`*&*>g0I{{978!z$|~+RJfYp+2(}dyO81NN-RmWAa;c!%D5ZL)+PD zeUJL*lRlu_(#n2BWB3F=A*Wi3<)R(TMn0n(2c<9Q6f32#sM;gx8yd}L{vBPR@ zij_gt`{sUliTPgn{0MM;&BmZl9dL4C917^PU zkhiH?HbQsrN%fIMeW?N3$LHG+wczt;gpT?v+ZZj5)Nzf`&pFCAL1D~QOprroWt*ZB ztY?~`nmi>nMGu}R)*S7BE19AAm8#JK&EVZIN9H9JYl*!0zLEuc%nkA2m{G2Z9y$a#k9_CULDDrQ)$N1Eu%hpa9GUC&Lu*;J_0KEE{=opWEAJN| z$asQU8H9?^`wT{ZoYl$@bb+~}6Uw=&a?Z%&pjvi8c8qGSs2i*Np(y6BvTi7_zGA~r zr_IuEl*8dEe_ z2WrafdII{yJMM{k&}UCXjZ>7Jg!TqYUa0y>$s47n>Z~TCBc&9Zf(FrBOhwxm5vL(j zC&>r-=BVZA=uIodW}th$rI{!?R9RnSGfDD8MR*TpA;VpY%|=t|C^iRKGFr_=_BP7S zL%ux8@kf_mtK59FzJ*?I0NTR&EkIU`mkW_Gv(iPV?i$4cQ6rwZE=G$P8-q{=v%X+7 zAWhjN=rMaYA!zVf)m@4@G9O=t8q?D(M^=3IVg))gOyxq+{!h|Mbc0q_p^khvI1F8; zr&*0s7;D4P7qV-R7iYQ_xlU7T9ZIaA*m|@yOUI2sE)`Ta65U}xdjl%K9CIV8vrRQN zq0Y>LHX~p5{I{Sd{S@1Z8gEj$Z77X%jzS0iN!yXBv9ts28!GKYCiA6TXe0e|G`hT7 z?d?YH?Ayj5&(4a)qJCR+R(nvxBB~LGYyzacXr-aD`%sZ4s<9ufVAmiX^&YEo2hceq z#SWs@^t%a&hi|rt=m0g6P;po35Sqpe;4tbPAss=5xdV=(exnpShBhsclF`gw(sA^< zr^=l`%RKaoP9g(lD5uaNM$^;i2lMO{WXzp%25osIoki^jDtivSdMBMn1DJPSK%JPS zT|~>+!MKEGwvsNRCT*lEX#4_|OGQiR@6%A=KgH6~a=zhy6^&u<;TlRgsWZ5a?$a0l zhuUPS+zs@O-Zlg6;%>Z&P8OGLp`{gcez%eB2F3269KO?d7d4*aH;IeUyXvA+qg5^o6<4BXnz)^cXebDt>~xJXE=-DCLaw40T;9 zJxATTs>Ta6k$3kcax1UwEA*YY@@o{#eC-X|WT@<0w5Xh7?~vP0={<6>R`vr*yDNP} zU)ibrgnqF%oQrBPbNh_`SxH||D?Y)mXx3B3zM(CA!{j@vaZAVeftoRk{D~SZR=Hm& zfYRGyt-&OtEYNsOi9IzP&~h zM|)mKX2|`L&Z-6S;&U@cf0>uGM8RCe7HC#~#af~AQ*{jf;Fw1R`q(xof={(AI>(cS zc4*mWsXc06M%fOiSxKoQT2W52M9%C;U)LSg zVXoW*1#<6Op@u%HYmGvyD%KOl7Lt0QAB?6p=qvY;EgHkzr#JHaBiW&)CXziG#VGE8 zhWt<~j%eS1%JxB%+AG!DfkxBb1Y}Lj6aC^z(nR#= zoN7!$HMnQI(DEgcHyX^9Ga22XC!B)%PL-yj>^f?18p_v4F(1@~dGT~Kg>hyE`cXl# zndpM4v9CsF~{!cY#qnmt|bI_ncip@poKUHoXaMF~8uUy0t)hpj@~LBl-Q~YSfyYtZ-z=3}p>6XY^Z( z2GS#~L;r?L>rvra%0{4w_o@+@Cw7W9pda)b8xda^v)zRJ!lcb8>x;An<-e(NTTu?9 z)i(6%rH&DW1{PLqJ8I1<+JUmBNITIy?yX(OWRYUg$S6*+-Dp=MiI2zQGh;w3+RmN4 z2e~qK$K{n{{Md{3{!(lo>dg4IAI<72#iNk^(gCEwNAo`vv`n!Cl+AoR5xt;~NJ8yj z>kJN|3G~m0QK1gX9zkcSNJo)Z4P}p^Y-ZBQ$c;PsIPyF%oj^kwyHBFhxvF~##phG( zG_ozNSPGg*KYj*noU5}siMP%Pf?Oj6oOr*=`zg;SK z1qC@OmWpOJmeSA;c0|%qCsqVk(Z?vYcMT2LAYDh9=cND8wNU8>@@7q(kr!jeeG}QS zuXhW@U6F31EqsIg4!ZhEb?>4i8`ZdnYHqDgnD3Y~W z4r&#nRvsb;T7HCD8Y}h~EjlVaLBlxOQ`ctuD$mf{K z6-U?dOC?ZgURz02I8iEvhK^UurO^!P@^d~9=hsqM^q`)~l|z%5CmNs{uO&k?BU&nt z90#hE3dm%?Vil3wHMLR+)niwqGO9tJQw2RXlB%NI!75h`8BUa{qr_`!uLjy5EY(Ck z**~a-V(DXRqvqVJbx<$9i&_^&u@0?=jxlZ-p?=(X^-*vcWgDP*m86C!r?j$-P*LXX zjgb#C4`UQzp;!|XI7BfMG@ThwQ*@PY6gETkJ1J|5-Y^a}m-LOe+P7pgqAi#owm?hS z^)*LM32LV$nz2H%K&u(sTcJgkQft(lKC=zt%cQn!4tX?Z{@M;5KB8EAG?eF19gsWk zOh=ToL$XA_m>G9Mr-P-=D3bA@3wrCW_PU~%tggDDhPBjQcND;Q&;#8%CRrhm$&xjC z&_u2D%!@rytQQ(}RkA@TjOezg3(qNfquci+J2Zgt*&b!FKj?s}mXRFM_y}eDpv{av zebEBeuKmzM<{ACb8}9D`d0MX;1Casa?jZE4k+OqP@Cj)Mx<6IroRDc7$r+h&ZM&d; z-jXZ&az@#qXb63<8*&+@*f5m&QO6jL4C18`$c=I%(XnFED74_XG#Xi#mByg{tm((1 zU(9O8Awzm6cl4AVbv#OqKXmy-oo+zWYViVEP2x$_s3y{3f6Gka-WVlkA zjP|jTpMo;ZC^i)(oKb8VG99Uy4|>3!^>oyUzH0_DnxnItiDEY?=8Ia4RyjYko}H7qs&Fq_=WI1(JY*$~t?NLq@btWtws6y9l|(JwnG0@bJ} zMWT#?s=EPQXCAZ>4de6JgvR(OyBWpO3v9_#vdV2mZmhkwA!Bx&qRVsVLDYPJvI*!I*LWhb<-JNm``lFH5Hj~wxx*+WRIwwdKkxlf zRI|8r47rX`-DDK=UhN%6=FOEoflksZpG1u(OQ+BT#<0_<2KR3Ydd_~&8Pw*zVrS96 zqS85Zj5)x0G<~M(UO+W(>1Y?xWJc;s=qK0nW%Oc~bOlXd1(J%cG8U(yjqE|Dqp#*_ z?<)GaP1$Q`%}~XzqZC#{{~?nEWpALfSEUS8mv7nJM1v10b_@L*B;7{0udD7I^zO1^ zcadQa#qJ@yBq&!kF%BiiY&P+zM)D} zNCnYiSG7_IO_(GVM(b8cMNr2OsVLgTs8x!9beO)WB1+)=Dk0CN%2q~} z9i=KLnjNgF=-Eugsv$GR`0A+haH$3w!uwnkHDg{?3;D1MS{q%YMjg~)pN>`+ePbP1 z53N|LtP!%$Qmj6z$Y<05)u5Meh^lZWH$o#;t6XDrVy)UUMhkKjYl55>s+cXHG?sB;A#zx(V=O|KnB@kd_RAGpjKbU%3ql(fC>D&o zU8N<+a)`1aX#6?FmZEN4VarfqdXVMlJ^kbg)R^lk6d6^NR-y^4##SMR{Cc0m&}%-e z)hPOk%7vp1tRdGR%chF0MMa&Yb?8=cW!IyEtcoH~8Lr((WW*@60rh4S+K5uvciDuR zJXN{PsO2SPw;-F1ifu*bxazi{?+ulWLic#$vmKpHQ)~xH- zGP{u}JwpuI=csHfdcbwM2d!ABY#d7Zq8fYAxLMLZ^p;V4KN?eBibn~b)ye@BX0F&l zwD*KsNkBvHDwc>Y-Br0HWXBzP2zd^X4x{|}r6VYwSAG;NVjt%i`q)9SWHg(1_c*G; zoc{!J`k~lKl%GEF6k5!favCk$u51eO9;6y)knvr`&Y~M96+4GEGn+e)BDi)hpu0B8 zUPNb^uU$f08L=;;hi_Hx3TpLNO3jNkR5lIGHB>Aejp5$9ik$cauc3SSrR!)Iv+MuR z$Tf=HK>kHlHv?54CEY|`1C+gm9|70X1c21;4T z{+^VLj`2k5KI+e|^aB*b)s%yRN=pw>96jqJRF(64j6&Kd_5@X)B0WWx>y>?mQkdyK zN3Yl+e}Q)KZoEWE%sXG9qCXXTjXD%jjW=lXZN=Uq|BEX34joyh*n3o`qVyq8U!{-8 zevkACy=<)4k&EuxtL|sCl`HWJy7^PFuV};;=^MJ}r@G(KlgT=RAE@$JWq+cAdsO!q zTE*_dZ{#^aHU6OX8>GL;^_BDw<=RR4CQE(lN%_%yW?BW%VRpz1B2Q)%h0w>biWNqY ztagf^bByst(M0C*#ZV(=RmG7x<3b74lYX}(`sko+DP(p+Dvhc!ikCr?STUDHsl2=8 zkpCOW0Oekg3{f{D)hLff|Bx!6f$X7FL}wTgE1~mzPo*+y&u%~!RQ;n=6}_9Ny4BEG zM$_u3p0QK|SzM6#&!;?`ouyi+TfFMlM#-#a>Y%B|rMf8TfsR`bU3#K&M#!3bp+52p zRki`zR$Xd{y1thhp`y$kSrmHI=K3>6Z|M1(pr+h2CTL)HsVO>sQ)-6Zb2XWwc{TNV znJtOD)OXr6A{qtY&t z18PU#>4-+1SGhju=18e8s#!?o`k}5Itv`wztr`Q+9X^kND1eb^5PC928jQSHMxu9x1jdn$KxIc!X?d)l}p#zMU!;sZp#fGEj5UTj?%8A%Lq9YH<>Q{7iZZzlrlCOoMwburVwY|@x|pt3W}q&V zn~B~&lYG%qK7Btlm)(z9D2Y32Hge$g&Ovuusg=3NCPCSGD59?9j~305=A%dZqyTi1 zy`=@HE1&N|)R4LDBDC$9vVo|TjkFluVV)C&lIaD4Q3o&8U4nY}Ng=3TA!#WZ!g#q1 zoeEXm<;aM8YXwT#DTU_gvC6GPpO}ZOLNghs!%zkz(`xk4O|ftkP(!gbD7?JRc`a(& zTd{TM0=>$5^o(^>1X|Nku}E}nyVTcQO%*!CKSinZ_d+p#kQcf@6^gxWH3S6 zhUU@7Mj_u;(suNjnf?xBaZK8YM%+?+yU;LZ3ejj;Rh{#0lu5Z5be$&`v1lEm{T|dL zLyAM^yp-LG8m>}}eaOaE+K^1Qg&YC8Dm8Dwl-joz^i9 zp~{RdhtYV>^a!#jtk_YM!`*WX)n;y%jQsmZ$I<&MYWV~z5w6%t^fFAXoI+N;l|7Bj z)<`L6Uxcz}(9*}!Srow8pF@1H%=SEbMbCc$P2)M#MKo@TvX@ZD|D?+(b((YqrE{jK zXy^;oNJFi9N$F_FOJ%R3lO3gN=m@in>*x<>@EsHelc#NWQ7BJw@1dAGDwl~YFDRRZ+_;KYp3wvJikVRkvJaOY zA}7`hkC1y2#U7*e^!HED8+JsVqRwm8@-tM;LFJyK5BzP@7bw|W*_SBJN!eG(dbaAm zMy?^!8?>r{vTxA=#@ctN>kid@kL;RCA5aK=_D7U_P5Oi~cBn=!D!Ntrj9ivWUr=Q$ zmHUd!xQ4!=*VOoq1}<0Z2MX(~*iSV2xAY4=TA}Q3l-onE=ns0vJM!2f;*rkL@}qcWZUs;(BVs|cn?Ab`GR=?*qkoxF5%i63fAAm8du%JAV-!O{&dL@? zwHaMXpn%&_Nz|9oxfGfotQw{Bv`4Wr=NkQMKWAt`)L!R4c8K*>lC(ptIGbwx~gCsU7-9%k7bIZ`J64ran=uBkD*m zWr>#1Z*)Rsd9OO7iLAl8ApY37ZCCUtTCr|uUURkA9SvTfGwp#~7+0-OMLWqF&Civ3 zqG3y=UT8Nf2OH$aU2BUh8P$5DmpnJOL$^PxoIRT9p>huB82h4*D3`i@P<=*&zQ~rl zq8~cPDAXUNv9cL}vgyMHqV89vK`4|fVlc{FCJjMN52&sa@_i~fqphq%UC=7_1zeFU z_t8)k>@T^Y0Apzws>wY)9JOFgHv%nrqu5BaVYOnT(15OrjYi&#`(se&3es3~)=*-= z@Ce(a8t&*Nv)u9MAp2Y%sP|x%n}CM%K6|3Uyc-iy$XaD5q3m{wd7(Yu74t^*u1b^9 z)V9(TRN=2Q6)odRoQA>&sxChs^zh|r>2#E=e{5%cHRE_oJQZyo6v1Mrgd!5yC6gxrZyaG*U zHWG?He^j}Zs2kttT7?q6C>w_Q#45WQ?O!Z~qe8AKw+2}!Dz+Bw;2GaKWW#D~J$iUX ziaCPKUE6{Va=&dw+m=0~6 zTUeFvK(iRxccMvLO}mg!m}*3$8|=jFMg=cRG3dIlvau+#v1;r=-Ns09Xi1Q=d(m-L zHv3TVE7E?H@l~zFqwUNi4xljJzk{e0?_UDywo=(dG>LObLQU9bJ%rlv$s9(>yOlkH zS{+l3qo`?!bPRbjs&UzR1TwB3N2R7Kb^@(oMS2o7qn|v53hj|jqsrrSj1&~W%J2-b zW|n&vJ!e1h96H4NcOE4iR`vqA!A#~N^6x8MLIzxQm(erss4K{Kl$44}(}Sd;WP1K| zRG$6GtLSu!>Rv-er=;u1%3tOFL;D%`Z=fq@l+8dT`OeNw6w26m3+>EO_BI;KIp0CN zeA~NdO>dREhdepIO!UE1%0g8dOWA1qan-nwzNhK94^SbFk%R2%J0GGQTy>9-p^vhU zQEBGIPx4~iA5YQZ>C!XQtdsN{?fj*3FVL>uioHao`L_KlnU z6&r@0=2yAl$d9MOBhXM<9*LIaNTblGc`7#=SvFE^464MHJr-G9Q+6EMdq7!t^thE` z` z&y$i-Y&q#T+Q40L0-1A7o&i1-rg63ZMc=Bb?mraFb((LQw0DupJrF^`?n-oZXuOI`PV618u`DG%Af~M zs#_N2gh}Pl{+G%cpl{qM{JD4!JJz4&(Y29^RX{IRNEOk|rK(X0-M_1HmC^7JWvd{A zM5!wJ6Qyi5RFS=e>ZrsBsRnZ6&Z~*)lvjJT&=!98SQ`~!E?o!p=qlAk8w;pLJyeES zx)HiZKVBa_v6LF18Ksc%xbbV+RrE523;$o zSX(rl`>h??RZD7*ZZP(AK*4u)rXA5OR=bvH?J31Np|FXHbw+=*F`s3Lu5Zxl9L zF*_9CrWkXn(HZnZXBfNtquS%80jT(IX&|b}s5S^S z=T07sHu*V6>jKYd1)Bx%-m-xywGl2xKR^3GOlJW6Gc*#p_q=S)Dp zyL4Pn)GbG`iRfjv>P|x6+Dl%jO#x-S(Z+F#O-5h1>ZYJ2H`U5ibcG&s8u}V6`Jg|Q zRc<=!-b9*#>hkS{nP~MomGea-<0L;+V52k(c`{baM)P}6bnFeqZM0#{B|j}5FKKFW)bo~rEDOIV8yZ+wK7$?Ae8h}3Pu%(EkV`k zK|;`aR!>V&TgJ;}Xw`RVIlBB>Ew4bcHcO#s!BAyaqCQI$TZJxiM}?v0^e?MX^d2c3 zd9u!1g90w7+*&klmSXGBZ=SHONB4QX5$MZeDH1hGR=Evm7k$Y_6#7T8O{g8MY|e{4 zP<9KlJF3`LbaAj^+t8y9ibbJR=3(2>&yLFOK*p>QccM?VrCsQ?rOHJkYv$v-k$WX6 z1`T6H5Q}=xmG&T0?z}kUz^mMg4t7#(AG*a;_5J8O&*tM%NDaO611OzWeh{7KnMnfr zME{qF<{y=k&;#aIhfq0s+rub3OFDwW+e=5${vkT6VUSQ<)WUpF1K!+xCPw5#taaMYc?!J;lI z8V}X-KV%-DSUw-ADr@Kb=r(J=0;mt;Q97WUXo#pw6rp4AC*} z#`0)(H`SJiWgT8Zx)kP&a`+DdHJ)995J433E3|C7HP*#d+@P|x19x~5q zgtl=FHAW`glr=^}_?=o4^ro50nV^D+D%TV_wp6ScitZ$tq7+7m=BVgf#mrDw<~}Wu zc~{jnN3~3pZHdY~QPu(-=89;Ay0}QK(I3|KZICbD7HW%PSberbuOn2qJv#nU~ix1ERW9|w<~HHrffHKftgHqWVcnZ9>~#B<*d+Y zetB+)N~5Ji*`GLw-J z*)u77CuC+tvR6cemc6p~DxUABf4ttW-|xE4Irq8Gxz;(|q~0jPMOjz$!Ao`fppx|Q zeNlngD(8mAzf-Iq+R#%q+|d;$?ZX2V+oEiL^oe=E05olaG!PXTrK~49z?D4+-E+~F z2cu|5WxbFSSE4s6T~M(h=yO+TDEhisSs!%XNU>okEKM4Y__26{FZz#m(hn`DB#l4` zrIa0sR<==W6skwRFdA(+psYVKu%<8uB{E(ci>9xY#-XMsbOZrtU92=7&DbPOKwBHC z+(a~!HNi>9e~C01#Z{1|plVztfyj2A>P|&Fo+=xJF7f<&8p`6$x#`G{_G$*&R7Q1Y zB7S1a5R8hnQfwB=e^@nUqcnQ8ImnHcbuRKPErp;lPgQOn+RQIw&PQH-rBKwdgz7Fp z@eZo75WRjREkfrOsP1C)$XGR&pyAvLOVMfG{#b@K{ZVW=s$NaoTY+BOR^6580j=^X zwB@q28a3o@3`2PfX)9|`Bz=oLAj-=p|R!dbFDMbOVay zIr2vIgU_}Jg>I5Iqa96EZVTG_N!p71Xw9~vMSSw@D5{0FvID)`s_ahG^S5HV&{M9k zD3rX6}yIBa+O?1m&+=ah+JtwZlI$*wdI>=Zwr-6Le*F|yM;Q$ zD|Q>1xl75YEi<4y$hEr4-9>eeDVu^S9@p{RL!-Gr?xRw)5f9Km?&MT7?x^afA&vae8O&dY0bmHQ|Qo!=|HK{Gg$Z;^RT?e`rD%#q$Bs}d^r0ljCW^$~@+ zDfS5s3Rd0E=sat4UyvQ2?JEjm-2M%H8ZUiEbv{c!kSl8xKT!m;?O(`ufnvW=3~T0p z&=X_T$VQ=kmCZqe-Ie`|>d;I6L+#hAoY6#S8Rt0J~)*=(h@??q`%OjP?$eilFP<0Y%Z^w<=c*6=POe92M`Oa;B){ zA;}CaU_GY6t9hP3Dr8DCDD51}$ghq%1nX z?4%ruZKGIu)G=GJ3TQVYfQl$+hO$H%2GA7zP8F$M_0-zRs#jl($qwann|_L(V;3=8$G9AsDo}Z`>c!Zunug8 z9?`bfL-Y6@*!t)X{eA=VhFC+ijc>~yT{*67BlMH2q%pd>TCpZ5jFCc9)PeDu11iOJ z+65huCHxHB^pt}80iTjETKt}XO15sfc)$l}TKPo#2jcqFpM%AKK z*9%=@w&RWFosfp0-k+qQs2OL{2Mz768pBZaP-TasD{+!9n!jD;{Llh=gAu4#k~9*% z4wOcr%-+&yv_D7kNB_pF?igg6seOz^4b<=$#-Uzol?_0NG0KidHSv-3Ka~we zH&_>)g(hB8Y&N%o2@h#ou+pVL0DC+Unv|FZK4`$b7RTcas=|ftym-qW|X!LMOmxHdenK8v;mc(ec6b7cwc1` z%H#+(qxg9$w*^(0ta4k?$arZR`p0`7+fja2t#+W4pUUn;kE=+#P^I14UKFwoP>tQF zO&7(Yb9GF0_n_#L(q7cDkh1&G)%H>hvgH2QkNVw{4j_k2=^!e~TLOpB!9Z>0F#1j3 zcm&-=vFJAa$5Aw!@y0PUoz>9e=;dUUJAn>Vlun`(tQW_jIbo`M3iam7K8;MbDI1S! z(XO3A`ARCAfV%SD^I2rgNdFwVV5D;AQ7u+TFQ93RcP}CrTIx%vEce@G^pH`|71V{^ zgweJC#dA`z*EJbabGo%4MK8W>O|v zz_{cgiY_HRLd)H>mB(lTW5*|G#x!N0qCM`?GgNG*_VFB@kCR>?^CGJI5{-SJ*ef(7 zO%6qcdf6%ryq`+%3)Fi6j)qph!*G{gFQ<6uDXrTbXwlV=nbt-6I808)D&G_thx^9eUj7+nWae0 z(KhCvEl}ABs^N&DSbuAY=JIW|LIr6vTceAsr8cPV0m%tDG?&_ODs4h4OIzdZQ55Nf-e8*$h*x4_d>Mu)fIUpt5erl&4hv zP}VVt|K`Ncgt?&y8p&_J^+#ndD>eX?`>ApRQL#YD6WQI+J_aGHB*g}!3#{9Fp^x;e z-pH8j5cGoYZ74D-qZmume!ncFVaSyCorj}*`Blyrna64?eyB`ml^cO#Svebt`X(zj z3RxUdY&1$QCHbQ%R?3b+LkB1}7TJ1AO(cXBJ%6M)9GGSgm5hb!hGzoR* zdY+7KjFhIJFlKduX!;S=n2OBkhl0>6?zd?uh*8aSl-f(0fdW{wnTd{+*7kzY9?tG8 zRQ#Xn&PFpPDLV(PrA?oU9J$s)Q2Aww%|nHXO7qbj`ukAyVT88At>$;nT{RXWw?B$4 zLMai7Ek@%uDz*fTHCElFs6%CG8Jf&2dpSC=OIm@dOjV7QD3R5rRj4f^?bXPWXINoq z0sZb8RFif$9GURW{91J3jIt4^x}&m@$b`g6`f__9^N+M%ia5Pq6AfNAa7b7wEUI^b%EQqjIm%xznoq z8kObS%0fP!lzoGmUsUWZ+QL}n9ooxx{vLf{WcLBt@RaH!+QkU^6WYKx{Tbc5rtN(} zttj^uInv{NL!W5{zN3Ciq#vkihV&EJZ<2l?ALeMk(L6@He^9xDie;nLJXOy@7n&;j z7xikc>_4Yzbqm92|P6SG6zxEt%CUVN+d z(M|5M2FRE**$~y$C19{euT!K(sCSrZG)4=!-aM*xp+odXZISUIsU7;pn6*6$qDSn2 z7VJ~DBRWZs*a;1KuOo0qn_8<}XH=gS&VY8O2Tu$EsKQBYc|3Cdpx6ZTfYqgm$f}!aOhS$6k0ztfjAW*u zat~D_5Y;=b>{Jx_N(w>=jDe>ifBuJ)>F8PyX$C6QUfG#w2W#}fXg=TXEHtB*G#d>L zk>;S2x3uNC=x1Fi1U;K7%|l+H+RA+NaisPUiq3CQ-390oE&4(fd0DYVsDY8R7%f>N zEkR8xNlQ^FA88qyK15oMI{lDVphb*=R-%=xS+7E_j8#^nDix$Kba1A$1_gNO2*Ocb z?uE5zcuy$;nX!*Z^pyK(9qOGVtw-UHmEDkA?y9!35v}AY)h0BS_H;8^#GH5w+QaJR zR`g%0v<+1*pzL$AG|Ib3b@!l^397pn z-C-qRAKGuNb032~ja6(vI^9Aw4xpN}dI!-$`u#&Fn(^~t)R}XC1i1yNZY;87HTNho z;mSUS(u%6aag^9q35~t8`W>2S4hcBudk1j?kb_TspkP^^% zdXlp!l)1|}w2M*Ic{G|U;sP>TuGmF1(^k5KysN41Wwg1rVpmXMM*3ILcbpg--B9X{dytH7wADWDpitU_yJ#TaTM8P< ztmqyJrv1B*(leBOfMUKXmWsCWDbr9{#u4f0AWzUU&=#)0OthMD(?et^sn{d5v5oW? z{l_Td3Cg=&dWwEDm7byBA654`3a5X2f#QOdeTiE5D)tI(q|JGa%wmWPYG4e72t`b)k;$7utPAvES$r>j!^OgXdB<3S@mX2OS8~mj9xUt5oA3il$F7 z(#P`a%Q{USw3u~gV^po2WP;u@x6g|nbB6MvuJm;I(QDqvD1aPCD^?Kg{H0hS^o(`W z!l-^;Ws9J)%!!MlRAa@8A_lx8oLK_1K@%A)s$^@+-%`cG81JeqS|s(|*e_Eiz(U9XrG>cJSK z5?aoay2@w(J+?LSV{bO7)pMx|TFls|D)MB0Zj0h*i>skUCMs7Qr8BCpkt;u`Cfdw( zUke#|NVU-_CvBw;YDJsPe_Zd^qL4lZ{|UU`DMst{P>*PBr9N8rLa_$uou||gy`Yb` zN3-bZ8ll4vq{hgcHlhi-@kOzwDD0->fSkQ`1kKQRR!*9u$BxRjK%MAK9Z}o%I;xgv zTv?TCg=Vmo)@UT(^bh3-&eqK7b`omCX;f_m}R4!5)4h6vT@it6!1>OW)}BXvV_`=~~Dv_D+29>_IQ zv7V^-8`bTFO0p`{8~tQO#1(D7tymw_mAketvaF?;8#+Vl-47XWc_O57=n`#M02;&_4dc-x#s?En^H^p1V@|)VjB_R-JJ!f1qe_gqrl4({$v~7g zSDK2l7*hwKR(GUnD3$MbI;!(pu^GsLt7IlJ^;I?)eJU@_LXM`&&PKIHNpn!>4rwl$ z!gUaW3enHZL)mXtcRsRoS1c6e;aC4u?&-QksR`lZ0XvH^a59&hexEHN6Q;mJ-VL#P~ zLAROp?niD((g8HTlyndkzM~^Ogr2cJc^KX3qU;f5wqM(eMFCs~M^Qb#g=45S-~MrQ zKT$e?7Oa#`A_LcW92(-FV>yM6lvVaL`pybVJnFMXu`?*|St$YWU!@q%qN|Q7cMjdj z9si*;XJs#-%Z!mOqGo(Ym(cNp(q*);v~&f1UM^ilR~Xw~L#291*HQk9$|j z7TWJkbd}>vLdop+7Fxtw+HF+6uVTq)wT*NKouendiyHDII|aQyrPw`G?4xua^_(F+ zK)p~Z+R92+8XCojHXTjusB8v`ZLK5CM85RD4^d72j{OnZ$9MS{&0eMK6ZHJL>OMs+ zneRVC5BICwbJWjUu@`7=6X_*-)=PC?p~YN7uTjmf%4VUs28z8wWkMBui;OwacgT`o zn|hC$(w=@mJGd`DqBusIpHNxO_-AyL&+!G7q=)#5wz0i$=rrxdcT|0r^aBmx?t=h45dUVRstR7oxzgmn!94=$mN(+3jJ3?Dveq(=CVL00g@#O znW(yDPy#J~S+tcFsT}%SPUXs@Anut8=!TDC6_Fd?krfK#JF0|wPLwL6Zu3;b8d>a9 zIU5wfyKGgE`9{U6q8Y5d*`llO6|07PIg{1VI#xAmppGA;n&>mmnCgZ#(pbkybr)q^8Q%N8M^_D-BS8`k97k`Y>hf(L(OQM(8kejmGHDbCqj? z?vIn2qBB<7hXXoMLFJkuJFdFs=nB~uXgVt$j_8r4)Dq zb)8TmS4mqG^hauk`nan`dvqjRu?}c#mg;syd$_whp+T$@I-|}*rOwEeKE;3r(q45z zrCA|xL93Q3))lR#wfzrS(VliggC?k4cjV!sY!6hLmbxdhxGnWUb+~7Gqf1tjD{4DP zHTs|hqqUX3D5#8LZfGDYhW*g?-m2k_`Y}rLKtEb5)*q!`Q@H`il5b`pYP&)5L<1S` z4ni+zy$7Rn*^(DJ*+KF~r7vnLLr~yOX($R{Ro4gYE~)(vLuFhQ8;+u0s;)1xpP-l@ z3Sl-e0$t&X9f@jlu129MwyH52MX`?Qk0u>ab_{CBw>1`33YW&A46dsHG=TBdcvOrP z$O$Nz8OubJT}+yUJXtlJoGZ@r6tt(6Vu5HsPgbU)0*o1gkSX8lG<1rQ!gSP<_lssA z|9i^LM28tS1)~GQrCDg$6lG^48-62V4)PCE-MOeBt3n~DMoGoyq2`@cV?G+o=sy%) zuB`1XKu1d`wh+BvuGk_pqMWoCHESU)LD|)$rO5TMYAizs&ndPX4NO#Q1*+dqv6bj9 zbG22dHrM!S^fpIF6^3rH-!&+dHQI30-dg3>B7W}B5P@oxlOoZ`M$$Ue$VfHTqadEj zY(N`^OB>NZTK-MQX`Zwhou^IQf>NsK2(}^*daG?{(|T=rJ4#DcxgBUBv!|VC3vV;+ zLR(9zMijdCTH1}C)KE4W9iWHZgFa+wdwbF0wJNs{?P3ie2GwTHv>%lkq;dz)W>yUj zB6sExhfq1r)nT;ipL7I$;TnoX7fe*+D9VgfjbkYEhhoRkRpuWj&`d@YC(&^;DGnW` zUp<9B5j%|*1*%3oy37AIc?J#Ou1G*#{Z;NPIz%si4o#^gokvzYv%Y{1&K@`XPs4rm?~U{TRi!6RMai`HX{g5) zZ8;syV}zH14lzT^MB(35?jfqlwebjD;Fuqys=cKrs4RE#Q#8B3^bDKf@YIzCC+FKFjQ#lE7EJEd>Pk+$$V>O_0{1AV1O|A~UR`+uQ_VaonS zdHU%H{vbn5#j;Ux#uPcI#|PE;i+(bm`-e6$N-|R8=aaq2cY7&5!2tOs4?)Y^rQQ)Qp*YA>=ko*}~{j2dM};xK~G2G`Achm|`d= zL^X<|eB9Nhs5bYH88TxeRstpWluDv=^eX0Ph?}-o3YAP!tTeLaUbaBnSp&C3jn^n! z29;;@T^23vxy&pop{}$iqRRD-vitE1)LRf9>q{--Y;eN9w;fojx3Z+VBLHgf8! zSRJ&XxoXr!@3_zG(Ah%TUOg00MX~y5I-}bLD0P6;5H)Bi*`uVlD%S{E@YY0QbccSU z30ls#)f8oM&pRL^R{EQvvqq}h9N96_Zh<2W?QP54Sg>NP&^pE~t&tzA=55e7 z{_@QU6{A;fi+VDqZHGqxr&xRR#$M$*pjf`6j;I)YSSJ+ExpGD|Sds0Fs(UDAK;h<6 z7j%I4a9z;cb&7RGk;Sx+|IorD#k!%p1y!y)>PrvO1Jz=r(-VzljM59;=I-u|j?y~0 zqN%jYeNYhDz9{jFRjxmJ#2qjItr;K4IhxRj;9)SW%DmxPGd#3Ct^oWu1Xtbla-*DD!&lM_bjF|>Gm$rKaWJZKSg~1X;jbSrtK|6(eBbBw39n;F{=1ZT7pjWRgI-+H9g5P)W$(tj%){NA1hF4 zRJw}}wgFHdiXDRj+4d(yFdWN!?`8-G6 z>A_y0riT=Ji59+>UZE93lzol9+DloeA9ws4lu3W|7B!+5e}~M!>geC2G*%TppqtDr zKB9P@YkfkctE=v3bb|5Z7c}{Y^c4+b-24rFTd%s`(X8#N@dK@;|M-cVc}MaW>c2|a z->41k#-H4*rId~A`Q$lh7Omr76idth4}A>OK8%8-7R;3Mpt!**XN)WvftsKIdZE0i zPKILnkS%RVe&oOzDu8C6SGj`7hSiKhD4x$-7)@Z*Uj&VQEEPo#UzFv?Vf-rDD^?u6 zijYiEL1u7fXj~ns1oGuND2X1^u9+k6OHwH`I$hb)C}gLO&jRhEwY5Ys3#BsXF{910 zX!r-!Er;?l%PEh}?pL-#Zny^R zCsnsp;pjsBw%YE9eT7@caWY!h^b>#8Zb$kpk9 z?6ykH&?OhCIZCGoYk`j3l^oHI7E(*}mTRLGN@hK@HG0)aTW*8)FpqXZ#wC?)i%c@5 zc4);!TYYxs0riF&ZrsRj3HNysk@+JjJ{mZj#QQF ziWV6Z`wu0sy3`G|JEa=k(IwVMd!WgD%AV*}w6eWWRwdQ#jS9v~uBazl?t@0JQ>-rv z;aP(l@*6GnL(^zg+)+*o$pcw>DBB;6q`%}R(EZ}*8wciQ*DL0U`W@8~3_=TrDmxfO zy;s%?HTG1@8zt>jYzPYB*C~dgbG;SwL7O*7!*cak+Z&D|+!XUgF4@|OA2MuJYy|qw zv+t2;Vz{!S&{eLI(I|v5x<5*5sd8gb;0=`G2 zBI3W9HB3SYk5ywbI<-w(o`PobS1^HSITKs&}L6{QqeB|q`Y$z&xSz3U0 z6_OUB+1%5M(5g7qU5q|el$IcV+QG0Cy>d}(8QQX1vE``Y9_?cVGC3rzL_K-`ZWUV4 zPUTjkWz1*7Q1B0F4N5<)Y&beLUs{Wbbde&E4ev!nqC2#D>rnMP(t7laer5y8b49U@ z=vs4W6Pn^DZAM?}tK1gk^hmL-$mN$}+fZG$vK`f-_1=N_Z%zz5Q4HsA7n;Vq15v1Z zOO@M=B7Z6tjrwzc>_Jm_S8*>ovRkoz$URs!VokjYp-sN@vh^zQKgtn6v7hMH!sGbEp};!FhC%w&VgjdO@*^XxS?15;EQ*T}JVC z(iK#|AYDba+;7)Vcn|41D$A%P5zT+8ayL+onabWom98n9gl0UHZlRAnow$wCxI>fC z;wb)(l7KVS^AASOp*SeBMnp|8@;7p$U&1h zr+-l-E%iV2?4M#rIyAp_jGFVHp%#i6BOZzyOi-s!I=;Lp!$Glpx#d!|mHcQ-l41qW zE#^!Gkq7rtA@ny?DvS=&R}?|LYe+@WCsy@~p=RY3D~@h)C7L4NC6XDM-CHVw_P&xz zqN86WbJVf3_E8Ese^;zDsyauqKqK>MAC_nm*G3sMf(NWv0jAk?6w?a4fLFzvnE==ET$InqMxaaws3aqpc_$AU1Y@lVTax^7pjNiZKe9T| zzU=Mz#(lo_USt62a(^TzboPR>ZIKxx&~|7P_dxhcpRJIcesH>PW+OT%n4f@Fm?<_9ZQ;r8B=l*oYD`8` z{gj=8{;pLl5VaXEO+{{82SLb%x&1U`_fA`xj=HjH$`3^Nb*?VWLnuT88 zP~F*RM0;rt3OgmuMdR~IA?Qj!X&!Qq*FNT>9vc-4MMYWFSb+Rk=U<5Y1GJAt$nKQN zEk>yg6kCE$%vEeDD#52*hRl7XhO-iDwNYsT8+H!s$3X)nH4rhS}369-AB(Jsc0@hCaJVrNi> zm-d^0j%F%$7Db%U_Rb-*%Zi;xwzR+(P&iw@h+dmWmrw$4DqKcAxSFn@EnLr6(fryf zcMUb>2(BZ`{)#1{rgfwnC~>s1H<4LSDG9|ecfN(Zxk_%M-K!K!Mo0NOp*v^=?ZI92 zhj~g0%Hg+m?x84VK=)D6QqlvIXs#NmXd`_^8k$yBN=KGFvCTj;m>p*#{%bkILv)L8 z;SnmyRq_}Wq6d3|qP8pc6oqmJJVU0;Kc1s9_Y`}9GK>^^iOSQWzd|;&dauz0?(Qs9 zcamanaCH7VMWkq9YSj_Y*qEn%id-H%r+sXvA05{fZ3f z%6>y$gB1IYO3)7dKwond`-w)SNWV~naAkj^&h#XIP&_SMHrml#u^iNLfbJ8^ zo#Y9dkv_DaCG+GwDA7$aMr#}-6SRrXmKPOjrdU4IfwP+*4dd_k3Lvj^l`Dwe@QA z_E4-8D#1#AX>|3l>RO&WziQ}>T;+aeKMDTU-J~jDxjULy;ekL zn@U!w;bo~3n%Yj~Dx-)0v=3|ait}fK(&ngK6?B;Xs4D8#RE zp8VJ&C;Ey;XfJChjgd`;)C5h^rDAA`N*s++R8|DjTy!$l+9TijkfgB_WV&FuC*~}|1fDR zy6&XxIP}_A3P7Q}KRX_^Wd&mbvM`klhO97icLX3hpBELD!owIsmPn& zB?zV1C_4=mp>3LuTJKhN2D+Or%|xctR4y3x{;k+7RQkR&8{MECpM%PC=gmbc_?z_* z^eIQNdFVCc)A=a7rS=wzuGLj+0lN24`&fvEv8u5M&E>o-Mh6&yE}SQ+pv1AN8;+*>E4CJmbd@4d zH=c_}qG4&$I<$aU)_Qa=QrdtDab0ahBWX7_p)}gb&FC*{XupbqE@UN??Rn<_d5!eqgCFGM#rmeG^)x9&>j@!tiA0;MVMjiLj{=I z$Do!cRChm`%XsJja%RQhAS%Pi=n!gSkPf2}snQX2pW}-~fkvuv6!jXWEgwVmczSaj zRbk5~&=kg}Cs77%Qyi*&SVwgVwP3t)8ue#wJs!>HYC3~vu23ui6<92tMdPYyzvs{m zZVTtpYwNtaN8eac=&Zp>k?pwK5ef~%+nqk?Ow4kM`RsH2~hhz8St z+(1>lwcneP-iY($SyvL#zZ};sw7j%*8x7_@71JKG?<PFVvo>~(K?pLXpW^~ zPf(MWiakZgJ1X`J8F$e3o}&!f?-wYR7V9NC&zSoaYR9V4YqVjVVp-_oS(ST(&Q*}! zqF76ndxzZLDE1yzq{aud(n8sfC~cNvpHSI$I+oAqGe`dg#c}q(qI}m??i;%6sO^16 zGxIC^1NFJ4*iYo`t1bURO<9-xjd})2f6zFt-fWb@FCOKfMvO=PBG>-XKNLZ4YcxaJ zx8<;5IjXDC(*MbN*L zM#-I&wLs4g>G&+sBj%cAP#IdbvZxkES`K-SQn~UdforG&8p=GTA}UM^XoU`0X&;pk zKg@2ZjK&|AtkLkVk_{@lUaEpJc_X(fvWrp776sCJRzpE-uR4mNm#Tqw7LsbBNXCM- zPy^;qwNVyxv^pr7UaBr?*H8PfLo?}z>Y)^_q57!)ebs1ys?#2;&jGDtWuO`I<4JpSbURzI7RZUa+Y$L!Q>-QGz-mw{G=*=W zH7Zs|**0h}J)si{EiAP~y*;FMD5Zq9*B)8(K2Qg=iB+l4olrn^)o?~pw6dMi ztO#Wd=rk)+UC_A>%DN!8t5R3=?})PhA$vx$-Oy8dn(k;aTj_!F9hdkMHosk!RgOPl z^E=Pjtv9OHP&HgpLFQh4kWoIVFZ#r)ksHd2QQdy1aGYZ9$ZChS?1Ah`D%&5;eyi*N zG=XvhQ7zhjPxO@0-XP=_rPyG!o!-X_MGR2Z8@=<>mWQBZA7zK4%_}7zv|_2s4MTZ- zq~R!(U#0Rzdk-k)hbq&9j6lavNh49~ZYnnlE#9c@jYgxHv-qPA9?}@JnY&^v+Qlm9 zIF!kC8i3MHOXE>x8*O<4GN)gdh!!#`oP_pll_sMzJESS7>wDD*L=KFMr=rp26$?W4 zLlm2ad{_&djw*0(%|K3Rip@mTT%};NiR*6`n!>97Y*f6DGzW#BQn|Uv+)uF(G@C8Y zLxqYcHXm7cQ!EtCxgsq_y`*qdjc(La(%^T3AP{lT)&s@)&P^^n$o6&klZFvhSM6a_xF zFYQ31Crdlg`c5jh3-#HcSQK)g#%@&Ws`e3$&UaR94~h;`jlJmMQf2p{;un;SK@B-; z`%xi&+4ulj&UrqFdS^?AP|bSU%3)NAUg!ua8>MV4YR_M$97W%a6+4ESGAcZdHqZ{8 zK;z7mJ&6Y2k>ZfkPi^lMs((qxavIfUv>cDRah04wGih@YP<~pKv#2AV{2aP_RpdkkPGe5RWylpwQHz8d%KRd98|ePlrT!M8|W0H zk(=mOK`9B5Q< z&eb!tf^+&D)uL^BfuiWkUZSujioHS=N@*Xj(fi!-A8OoG**B;wtEF#II8W~1p>$T$ z-XpI~+TI6Lg!bSgD%n9bKB2!{FQ1VIW125$fI)S?qW43kZ|Lqa={s^{4EzJNY9#$c z<0t_BjXXan`v;XWk+RW#?z|in&RFy>da_5^e`pAIp3zLHDlKpxWX#Cd7cFfwp1SdaZ=q1XeZZIMU=wdDDYnb`pqL-3Grg6p)zXCjNckv z{vz3+C47!5XiTtTRnc+!BU{vgchjq(x(8IQI(qw9lCYrYV(w(7D{}kY;9EF zfwFbbf$oacMGtA^?a&%VhxKx^tjyO(uW0KUApQ$PLqjy2RUUg}Z><`QQ0g?PF$!Q+ zs|hmuCpAS=zpJhTGUrHnF~!fE)}lE&%TwzXC}6i@j%XySZY|L}7u9WrDo$3cHL|l- ztPRR!#oY;Y=&Wp8^r)_4?a;YbinT|hZ>vTJ^oA?3Bl>n%w)?+E9#GYY0(Fu4&KTRL|**; ziYKzA_Zx)v@a^;3sNY9Mn_lSmQ^^~(;+N5fAWP2VP&9S3w(Ns4I2*%IL%yToXmO6@ zi;~KyoFB5_+8BYXgOweLR`NH5qfjZnnbGKCjLP|=itnT`Xdh1|$09H8+Ht7pN!18I zm6&&rM~k?RCZGr09}|(Ov0{_Zk)NtD8GU=9*c9}h>mU$yAzHCCQAIHSTJf`Lv?4NJZ92t zeDs6AnhHf5S}3~!6=SBk5Pjg8;v%$-t8Ou>vsGGxTHKeGqN%AWw+xN@BP~a*SaDc^ z8gezQM0e9wV--3~3%43M4^S)&ogS_lYtT3TkG*iTW3}q8MScfWE&>&&4~RsSLlj$w zCUC8-N23Z$8_>%0%5Fph$4i?~&=6@e>dN=A1!YEQdt1>+?v!oF%1=kI9j)Rn+kwW- zR*jvgou{-5t!C~Qg?_YBx!q_>dmTYETEpmn4{FKxyBB$KukJ(197_zkm!;T#lvqMK zfQ;zH52DxH`-hMNPfiabGiF&w(A=WhN-WyQ-j1RZUWy$<8C9g?$hwwv0ySNz&vp_$ zc2g`4t;i#tLcvF+)5!d<6pxBD(SFY$|F7Cd0y24{t(-*`j8)Dd2hPTMbgQ^x7m!nB z=^{$1tgT!^ySgfN8S%#-hAYT|R{kmq=C7u%q1k+*>nOdAVu`5dJni=e`pGwaGgsHO z-z2o3*6bE?IwjpkW5-I#=vA7wcLzOwqS#$DiBVq)I=5cBhmuc7_fZx-*aNh~UwcbM zQ`ah+hH5h_N=F3?OBpD{S;|Bc7?C|h`(G>e2!#bmkC8iV@e}0rRI#V%9{1Zb^vXlo z=jbQ*)(aHGNb4nf{#AN~`ZAV(jYgGIEDM$6`*?#)d0zh(xzW$OLq3dn-lHPS!9Jjk z?Uen9qFzX!(3!>B-e)xKy<%U`Lq@(|(Ix(J;v2Hy<(QVFJEA*?ivaQh!ekZ;S zic3+<3AOF1a&6I5M`hcgmE)9ck3!9*4rs&`eaem~f;OxZ`b>}QjBa#Pxz4B@=fHr5 z@dj2Gbdxjgf+h`9tSfTarPzOHWwO)_wPtqQ9X(+Mw+C8uM%kXo^q|xW9p$_1ja=v# zT#*I6b01W)kM_|Qxidp^L!;+Q{m`V|%DST~JX!HTZ5B%XQL(Ms?*R0rmTC+{^>-@f zi6+}AHVCcUCJjcLiFu*$8`_FDN|`SWK_3RF?obq6TQMJGzFx6ms41UvIQqR-Tk%E7 ztQGhnZ&qhUpjFM49f|&NAB{r!yrt2|ZD?mP^gPE8NKA2o`SxwP`N;4P0v0RIb2gV2$_#CR%t*pF9|?a8kKh$eBBNHi}uIa&u7Jd6k=sDu0tga>ac<5B*15Hy?#0 zN}h4C#^e)lJj#Z{TD6X?&dr=In%06_HkyZ>cW<<6hr7cqI0E+6aatD#s zU+EC)%2jt5y=|h{5j2HXAQnAg1>-2{XQFb)Q1(j2j-wBC^c|f*i(C~uiN<`E;?M-v zMNc8~WvY7`eP%=(kIF@#ZKSzGyny783$D{91w*SFkqsjBfExiZTAfwnp+_7lyb@BW4A)6)D#8EvIM zsO&D)$VMTJr5qGJO*Q_a$x9XchZ-|-Gnyrh<6W^lXx0VAj8S9eekN$w8pZOWDqMg0 z&<5I}{HP*pBL&b3_E8W`=A0Hni~0X{3!^LFlr4hd2Ps<=b#qs&7@EIS<%*-2xr&*h z<*b>TA$~&KPy+SjEsTm8*=3MQR_`sI#?Xg97VFRgi5v zsVXw;Qw>`b&$+LLc)7&D4?X&oKPA;b!^=xG(HL6MTF9cNR2w;Wkm{gcjK}Mu0b$y* z9SZ59SUt3tmZ3g!zoA$IG{2i-4N>_zs$q|M@_eBYO5pr8Mo|N#CTO{%vQ5$8=h}(` zdPAGt3^jkKa?R05Mied3FIq=Ol!v)rOLU3WtQCsoyKId%GP`SoYOI!=PzY^yTa;W# z<=Ua_L5j6U6a4gjbU=-*Rih&+*-7O(A*aoXIinem73+*5+DHZzeNpOyDwI(<7qq*f zw%ip>p?&!eE#XbAZm54n#k!;E7OK$$C7(jYIhv!v&!5ema8jD3F=;1XR9? z>P|$?d8A2bBEJPb8Es}m zwOm?=T#KvRBDCnEVvEtI1l3rAatbN76s`49xn*dAt76NMF)hOiRE6GoB`OjntwQOn z^RGrH-$-HTONzF<294&54M)T1vDcyyOKmvoGl(JFC zn!9^9;y->hM5A;!mD_`^GT+*Zk`k2NhknkHVo(KUO8e0VTE_!uYg1(pq78?YJ%o<1 z26Y$>4pg}#x!IPA#iAu#r$;5d5!ao$+%clrLsk1Yx{#?YoeNxF|B8LK`(^BJ3`qCt%mOGDH8D3*?1 zm}n~*s3#+*Ok~Bn)kEY{OL~Ml(8E1O^LQ`p39{a+*i&ReFYpYFUgw@h7Xemea72V?<@^2`P8TEJcELqtfs0FRqPc(|z%P%y8C$_)Qy-3CWpvad} zHhRzXo`YU<*Zf6SMkw|VZGWLH8_kwp=^sNL^s}qBXN+uPl{G;Vt1Fuq)uJWJhyKxe z=0`Ryr2;6)R4RxDx@aqfkjHYx3L}Q^h9amebBCfRwWW@#7#hG#uQ;m3-~E`P3RNXD zG|EByErC2uRIVh-`K`L<$ikplDfG=r z%F9!#^5|X*#VVj%omH+P8aGcdD-=*ku}WxdjAE71mQ=|amE>NqLA4L5Tou&0y;Kz) zj#kzdS)7!rp$1%G)zO`zQVsOsKdC0V<*d53Q2JfPYNKVGzdC40j#L+=GOx5lncUs= z(6#+ieRQLnvJH?Gv&n|2B4b~B)G$VBgyymC*BITOuUHe5&B|?4be7*ncR=GNNX^iL z4l36iwWzOsv_RcXOOD8a@3JM@%ZhO; zoMP?K4o18kP-*V1j>ykN>V!5Hketz7#)qBJGsa&AbbxE43z}}MmxQ0HR;)W()J)}ipx745_Cy8g&3d7#%yN38dOV$QMd_?o^+A0mOMTHp=J{^u z8SjDgL*-e`a7VZJwmeWYYb^cI4c@XIfcE#*-UgzL7Lq6GZ7mH#(|E=^80CyrT`!cM ztIiwcDK8B{VS`j|C~AIHvHv-`@3@-&IF92+LT0kJ?3rwmWETp_Y}k@jc9AXFL^g@c zG9r`_*(4*1tcW6^kmP6dd%ya})e}hs4acic(ik{c2TCqv!3r`p(qtIN%rl2OQ@1~+B;fi^np>-7VM2@_UY3SP!oy&C8 zfpyjl3F_-YjBr`Q_gwoY1$(%8#dhr$_C)}ww))XE0*g`@eS z=gdJjq9UwqHlba7J1+nQ{8Ww2sF$;1TTmPN?5!x8$Ak2VcZxdX_H)%Za) zml5$0YRH=9Fp6efbOc$Al0wieKEY7LSHf(MA_soGdkn=Vs+HrYOg-sDUX17FVaSW8 zF(=WsA*y={9c(9sBhM$wo<=2psO}l$#VX<~vf|o}K!bTA6^XJeRPG#F87ZAdb7!jD z1?0F(x`^tZlcG>MJSATDp-HQC-0SGYKxJ>B zWM&UH(ZZ*S-9i?{6}yevHB;;kDs@DPLCIFi-bG~_DHe&5+9&) z@zO)I>!=im%5PEKM`$8<-eWZXjq1ju(d86NKtU#Y@1G#67-gTLuA|jTB05Ju^bFPU zRE_5-j-K@eD!fVAmuTo8=@l}#tZWh*&kW@?s?kKTHz=3+dNSI3Mn`*#*0L6Uhf4D9 zrXah2%BG?Nbyed%s>&+%1Dfzt<*edlj{YB7YQ&7TIQmvjDuMjD zXG)@ttSd^P0d*BCjb8I<86(5<%9cSUdnFUpjjO#ZGU%>y<&eiM)h&;zvind0Z5b$4 zMD~HoRzeo}q{^r^qiz-Sey&=niuym5s-b**KfgMfz_aBVD8@~7YoaWEky8tW^is?e zm3B~jwUI4*X#7zc_fmtDt&5E8)Ji=xp4Co$G?+D015~27Vhzz;`q)M&k{+Zn>c~8z z35sHd(iA;DBQ-+}G9)up(_8H|&r?6uFh`aAlx=}ZA5pd?ie0H}D^!3xzBPJ0QLm^C z8q7{`TQt9|vh7g(6}8eHMSCgM0a^CxqnuTKIqjjW&5Jq>|5EPRrERbXc@aV{MR<_MHz|vqYCtd15n8r#T?L1er+@m z4P=$&h(6Jy4?>lF6&sAU*(o*zC9hW9p~%xnb%&uDv@#sMF;qDxw3%ms&S*Q|-f}^& zW+>*0R`9;4Vql*za?36*iuSxrW*QxuzmLiuE-qP_u=2Qp;L^F$?kO4CpZ{n~W2 zD@CyxXgB9F6Rqp2>@4KVTyHjNTtu&Y4jQ^g<-AZ_sN{`majnfoAx%|d9x7la`Jl*L zW#^*+7sVE!K@D{F3sLkJWf!5pQ>Deoij~b0^nQ}G6giZXmZ93rN`2AdOVV=Gg)7ky zo#g&lfkF#OE75_0%C5>QcSki=ql=%UHOP=%(6y)!W5qgju$r_UnX)gi0bS*|{%8cx zjW(j$3#Coy$5JUEFUuT#Gdjk|v;}={ENw+MyGh&7bSr5)dX}TQJMv_r*iMwjzWpvV z<*j17(H*`|6^JGUNqf+zG0Fy^D;1@^sNHX6_aWmnDHxftj^CeGuB^%(K%YVsJBUvB zsNA8vEHmW8=uH*r2&%x`HUxECqZ*-TIr~0GQE{$_W2h*7=W#UBT{?k6OQ>8J3jd~Z zCs7gRyQfeUR_fts&ok*Xdd?d04Dxxe*jdyeOtA>mCQ6D#>yAt3&|2<_^XLlq+XeJ% zl5`Q>4Nx{JuN+tQC6vM(_%fRFT8c)8={K&RCnXfSik_EH>>7H+isd@u3;wn@&~e7v zo9N8|=@yFMOmCyT?A+Z!7Ejbl3<~C4?jmo_FBZkLlJ4cnR@d5nWbCbS50LY1WgnvY z#}tc0D~2le2;F0*@EE0!RW=^klv6eV)nr!x1Vyu|e2SVMQZ^Cga6LamCAUe>(Hh36 z7pRrF^b+~8qx1^B=%I2+C~S(GVbV9`{6*RC$cO$V3#Bop{6H0r^?I{W5svW_b#Rt)P%R7T7iz^-{2zM9j__|Z z)l>R|<}<(li(K4vw124fO2u-KKda+>%cP=J)Lwq{wV28kK-)G;1<`y)VgpntN#zQm zUl-MiA?jCKvBK!YSE&eUQCKY(MfsTv7@_-xRihYM#hzAi^e2G`OUWRt`<#o-U6nvO7}&4PpjW5iMmNRtbeN zs#QhI~|j zURR{LC}NfA*$tglLli_W-v~`?uUKQWgJ%~_P*|?i6b)q`sTms0 z9*-G1z+9y{`kE=3qsr`zwLrIc9@G*|;(Ly*&N4GU$mXi z+zyRoE^3de(gXKH-MEJOqn*r92B0SV`oRG;TBPhiG=Vw4BMQ2va)VHFuA#wbPOP#+ zP*+CDp=j&{)g6Yi>nJ-MC1glWXgQ;mGkX0&azTUW(OuCc-h&aS#&p#fi3ac)jY1!) z>-Sz>IR~uCCctW zC-SM4AapN6*}bUA3uzy+U<3B6Idq#@-+9!UE8+rTi`Dibde7Yxh1S%NE}^3A zq+UkL_{^ixUe?%G(2q4LcNJ|(RqPt-!K=KE?l2DCK#km_n<$yj_ZBL}ZpCeMeU`F! z(6lMa#-LO~#qJ{8E{esXC-9jRz=_KJg)%`A~{Og#&erN9aS6^ceMK z6pu$s+!aee>5gjU3G%ouJw-#9wIm|LODgvanfFlaISOJQ^92g{BE3W|Gga;tS{$rc z5-L?wSKVtgi<#vc@6}v?~sSTl!9j6Rk>8Ofl=r^I=~F&11elsu{2ba zXAU3H1Mbyy)cU8gpOEVa=`%{Bl`p7e11SR;+N!-wlx-t@MTwzmk^&|P|@|4`*h(r?tMp|XEa^)8D2MQ7;w|DoyB z$VK6{iskc_=H*i?Kbmt`u>zzprd@berF_ltAI^9G67Pja9A`%DAHTN~4k^l{H3F*>5U?3?fy| z1l?~Yl|`w&rE+M5smhf{oexMA@?uWPRzxf8rAlZw-x8^e{P`_I73B7xYE(tO)fB6S zelVY`j(&5D8t5_Oc}?_{-l7&7#hS?!buKQ|M*d?}qYfG#Ak{@T`DIo;bcQFb^^pmq zPy^&_pmGgSH4nuaq1)_9H%8yN!kVCwpQNV9`lDV)GqjI;%M5LuEj33?9;lpoUaXE{ zEl^vY$G1ddCo0lcB9k*eP&#>KxZPP zj>s-ivP7|AD%S~RnJC78sp9StBy~oQm={~4;PQ%fK{Z-RUC|C^(%q2j1C{HJeApT5 zfv!DOxt_?Ypklqy(^87rAnSgrYm44-roB(xL5GuucIv73RiWq|0@_7tJIgGl) z(C^QR4M!c;>1a-<+IZDb7qmj*4#m1m- zcNH6pt{F<>(7lt&jz>qC>$xEhR&5i|&b`XIqjSt@CZae`X%c$-RW&A~e5TSA)N7<_ zOhq}2wI1kbfNFT6|2nALG?ZCO+36^b)#nV9%Dq1m9Zr{Kp-OxUWH$2VzMO+zmX^Gb zg{9i_Mtuva#$42%Z=B6TbK0q#4_ZLaIv)k_`7S`)xThDQP1IO~esSk5Mwf%6C3&(| zxus|fxUf8r4`7olv-YiVtKl>3Pr>zyBbYqj9-JUvA??( z4ScTl)}d%Vne}K;NyRpxm=2OZ`ovSHji~PwmD_~w_L2gS^=-Ac8O>Xu*cNnz9fGYW z{HnAKz4|0=M>Z8yV+S&hRct4^cV60smK;%bH}dgTEKt%n;{Gs~*+cXf<8Ba|z`SZN zs$?SVLz!Gz!RRS{(tb4FK{|lOFhe+q$`+Rnp{1;{52JOADo0SAEVUAXoX#j4ith1S z$fM{;RmF~>KN+fV9J#W~eFC*)HXnwruaHin4fLa@(1%V^IBLYJJB{8wm(HN8jDKg* z+AS&W86URSZCct<(bLeLaqf><2Jh8M7o1!KT^3EWUyVa zyC|xqYQ&;Y#-@8{t(9~iUE$7rfZlVAhse2r6o)>9EBgrfw^ZygYB));cr>GtVhO0+ zI>nx#7R-5`qDOp>G!YH8m!2U%?*8Yf%qyMM3$&PC>?Qi`uk0%{vA?oO$SOzK*XZmC zW#6DaMHEX$wdv#DqEPOYcW7Q=DFuz?{8ADB6`bvR)Pr@*2UL_ZO+zk&b+nHti%< zEj%cFLi@P)KBJJAD)$AgYOh!ZvT>0zQ4jVEzoJ5n8{g2-V$yfC|EtPnp%U~-KTtMz zdN#VjSn?BHX4RB~tm&tIAs_Z3{zLcXEA|_iGn4&;j904eU$l*1(Eme?x=Xp})_0Z5 zw_NJZDltDQ-CHVvVs=RdQSEs;t^q1nPBjXlE!;hZ=vpbMFq*~{Rs^- z+z|PWl^UTpr=-THLw(g~f}CqgO;LBwv>BSme8~(&vEFW;m$g&O9EI|otrp0V`@AKp zJxAqQp;OG#S-`r-wwBtUf&-Loiykm1YlmixR<=EA5ux@vpiSJN7HAINZ|jJXxi2lz zCGPl6D3X{JielE^83izMS)+t`QWrFoHCk5`X(x3<^H`mBN4D%h_dwY;iuFW^H&w0| z;=cj1wL#x`HgAiTvQFrYF7g-d_>!egl)y2@Tre{|DC zu>mNPU2X@ou7)%a`CL)f5haC5gV1Ky7=zJZM%E#yD&*6Mqr`8@&Ov`VOJ1nwGo67qdY`OvbJ52u z(mXV3g5-k+HkRh23+yi}K&HQ?h3E-a;v!W0KgAZK27KmA&;$c%DH^s;<(8pRofY#% zUwMkL9R0X2`Jv(56)R9Ovxk)^`iHWsP@I#rI#2wnWeswvr*dmiXU3FuD91xuk3z=j zXdBS6zLGymVAo?KvUgP7O{f98r2)v~nCfmu-h7v13);s#XDgZQ)SKT+>_dT0QZO=MWw9Sk z=QBEhDwb2-gXrUN=@81tnI1+CwG}&p)-yK?L2m9+C@RhB{wP|^nI1!YG2Zq#vhAhV z36yeEu`qOiJ-(A@drzIqDU^S)V&Q1s4V62MK5=iIL7n<4b{5rUT!=vH;uVWTMc9iz zhn!f^oJRpa6uW>va_?V6W#}2A&>!xtOK1ky%Vp%UM~X%p1C_mk+NG%ORn%anV%Jc< z2$j2zb`Ozmpd|Y2o5<#!YTQEnVBPjMI>ze$4jR%%ia|Tsy}pawkEup1Dl$^Bdno&# zV)xNn=H3sGKcmJ&ba1*_jzi12Qy!r-KHtY^KmA%f>cH-B0xDENtvo>w*eQI9R6(rlWYSp-;%Ez0Tk>8qR3? z1tl`;%RsA|t41cWWDfTgRr;;iH&l-i>^s`|L)k18)JoYO=yNN@vQb}Vn?F&VuBwrP zX17=D7wWl8`VXbOSN1o`-(UKJ22YUwqGDZD?jJheQ?Xq1nmJ}ZKg8cf$dA^JlM0{` zoL@mSX}n?vsCgIFD1;vFRn`#A=Ue`TQIWw?5mbQdz9?!Ota3)kiL)<;(%DNWj;gX| zDuJ4YDOM6WGnXobj#w&I8jbK#%oxpLJTHU#(C3(-GhL*zXg}-Ta%e6)UFFeBj#~jG zoK$-iQ4IUFd>PK&mQk`Y^5=T4f>L9ps>ptn+N*{dY*DN_s!~IBYoKB`6|0HTxe{xk z{%4gnMH|eOt&MW0Dpm)*ZKYUUbc)}b)Io!7TIIG6U zfRVTfDq$ftMb6BsnxWaWXNJzwi#A7>4HYv-JKIVv(6fC~OXRm%YK11W(pj}e{FzGI zHmIM4)E50==cgTdX{uOzlvz}<4yegV#VpW}6vaBC3xy<0w8>xUgwCf*R_Mh}sWWn! zD_Ns)tYN#Ln)LTwkq2W>H*}hJqdWRQZ`%Wn=Pv7sif)y9p(BibHpr0oz!vS`GwO{Z z*-7YwIwp^Ps@ybOmsfEK1p?kIJe z>P|%8wktLXU1q&M84YKrgFkKKUN2g)sc6?)$pe|Lmpsv8W**bf!S~X1TvQm@*f|ai;T-v5m4ms7OA==A${;YHtCm z$9j4pim_F85o$kAT8s{kl$M|(H&kOOdQ(g_mZ3SbmGwoA%wLux{tT|IAG*PnxB^ug ztk_DlgnMBXs>&10)hO|>dC#R>;%^1bbpv7d*qQ3N85y**OHAJG1^kL^vp;gj(G@Cid1$1+)bP>H| zRuzTr9#MOj(E1a~UPjw@C>xD3ODcN>J!+@yRa9}6ve(cVMvd#p*f{(wLL^3?3KqM z)9H#mLMPm$$0*{E6p#FGscr&ld`)_SiXT_@DRM6$C8C&D(lfNEqRKr-m5rqr=p8eK zm&mM>UdJnRcbKwC=uD*a8r2vry+IY|i<412@4;L2kN5N)I?Xtfg2t~`EET0Zm)@hI zX3__A^_A+TA#-|_k7$y)>ZYTa%xFKM`;4ofQ4l-nU(f~zDFeNwm&!!dxDvl2KW1d# zkmFUwzN4@7by?_N6X^%ae5i8S=;UANCrW0vnS)9isN65)Usu`x(7zsP?>G9+74Zj6 zd7{`~v}2lL|Il4}E7&zPK=+y96+*rKDQ1Xl zIn%<(kXcI+RDu;oQB-iX&eRBf|0@+k_2~JFqwSo136#Z}t|V%@PAY|taIKX_181l` zV^oycR~fYJoMeJLm?@Oa6SI+WXffj@e@4@N^J--)pcwkPis;fD#VVmj%N66#JG$4J zpjZ_Y&K^%y^s2nF)zE(SRjMODW}7uob5mt&qD=aYT4-9ZvZm;4u(GvL_5-O7D*j8^ zx@bOqT|HEPud?+~0j`_|D2JW4hNx_kVvSIh<5FXkVI(y{omta0MO7oDX2^DxvS#Q) z8>u<^$1%)NeO8|>(Afo2OEe-&YK2}fUbaRX^GR(`*dw*l7R3$Gt89mIhbh}0J%hdAv+hdZQNe6);vgJLJXM z&mQe%z1k18=6dOmmfw&Dpqp(~&H)__mjdu{(N3;97ZlCi=!!l@DK-MV=e`_?2JlIbLTOW^(WsiE zGzR5oRyr2-{idUhL(>^e$D_u~E!y#DUTmt4u^Pqg zlGdO@jC5`pB5K5uI(N>?Sm-zZ8JVFeBTH3V5i- z7Ice#Z7Z63MX_zjgVp?Ld8!Rd*+{W(?ScV%ZznjeNqTK(vqjwLPdDBU2Dc zWDMAgD)3qELj~!JgON4!?EPpmy~+V()k&=!L_0hcJA^(2N{3M&=95Q|BWscnG^eVv zp=f+n#f~ED0g4?%{0H~8$59sTok09>*ftEgO_WZe2^p$;3gu^h8jei1>S(9Y+E1}b+Sb!JBK03Bx4_7FKg&>6&`yWHK6(7YU#dyE3J zRW2U=Wfho^CswIXkURIsQ?!@?L|TM&(|i8(e=$ zX!=2AU!yJYioHP&JXJ_WrG~1Nx5)LB%DqFOJS|N@)8;6fiiXrz-S?<7*V+e^$=|w2 zL#|5|`-pC@RV(S}uAgdrLZ28@KBLxLLtl_>T`2=Sx*%nuP}cTek-L-h4V`2^=R2}A z*Dj{YI9oasHr?She>TUFoUV zKeQoTv0RkRXq9iJG?#PEkE{cv0%#ATUqQ6sf$AC{;}oe7Y8I+;hNvd$r8$6MCPzXcw#PdMH2r zOMSGPSOc_z-#Ru#b=d)GgrewG8l!?fD%S*=F_JVzc6>6;(DAvF8G0NiHAkL|lIG|( zqht$|&AhlJiscz|D>RweNNcozzK+%grSY7kEwbQ#Ylo)$DBB)weWbb_&^WGB3-lvL zv5x2|GX+aD?2pt51#op*q27GAqBBa0P|O-Fe_2?y1Zo zd!WExQcqN$^=~h<@S|jdR$P*7k^MCttvBk*sM`nazN}bZ^pJD5L*tpL+M^bHmi^Fu z2fYXVQ6GA)0Vw|%$pPKu${C1KnaMb!TglQOROO8{7+vSi8-ix@+;k|a#)@C~c=W|ZHQZ3rFSRlOWpE|BqjTF;V_^8y8(rcl>AY1M`WKL7lFsTo6j5*V&6QY@~h2 z$5aYNE>6;Zl-o?_asZuT-F6UF<|;abMl%*4MzcRDb_BI3sk$L~+2x9bqHkPTN0B}K z=rL3$Ky{C!e#ewOf%p@7wqfXok#rKx2~+kIn#zb2jw-WXdm6Q8N9+u$#&vQQ4P^9= zKt}tdNR-YT?;N^PL3Pig_(O_aK$cGwyNCilDi(!SvO2hgP9B#oqs=_Iibk*Ism2xb zVuW-R-Q}9ShT{2U=ymj?kZRmO{;bt+qKgjFEi|H>>fT0C%$M#U!=|bcgZ6Y+_AYV@ zmts*BzNK^zt@M@dql*nx_W|0pypvQa% z`U$e_s#cz&I`gDNwBJc}pP}5%(sN|@R&`$>zppCy60I{->=kOyzF!g=)mD0qGCoOf zP_z1~k&L>fslB(T2mQc1l*2Am3Yx%9QYy+kD!oU27fBz`nciwI4J}|5_7UxQD5aya zEtUO*DzIAnj2xM1e?hmlNg1e~v1(+Zgb-z57FaZB3%MoSCn9sh$OHmTfS^ml;t5AEP}_Dv7LEFP1`ur>k6Pv~Gp6#>nfIVr7sw$1p)}{H3yJ zIeVY{hw$!=yD3&4&G{`=Kw~E&E!9G+;v`eFkF`i`Yxeq)OFFep;A56fu5^A3T8&x0PW)r zXo$AIml~lDMp9$6%}V8(AQP^&rf6X`#hRg!ymB+Nd5W^l(YPCmnIi|DKD9t=X}Kl( zR!?M09>RO^A z^zxn1F781qG>&zCXLS6OWR1RAt6Uf4)l=$j^k|jqiGqps zLI$h|ZBU~zs>`OR`#47G-sn^*sSolhp>lmu8lSWsDv~VOBlmqO*AE3pt6YENKU%Q? zXy{?d0o}`$2BKH=n2zW$W6B^@gHL8KvS!{g1l{0W8;bf(P~Bn3qn9)sedqplLJ{1n z&d7ha@n}E$ zjc(`$-+!8bCi5M8ca+J#&_pzd*D(oYFqTb5W+VG-W#^!;A!^wR-DckGjV>f9I~Pr4#GZ%R z@*eo0T}_mokCqHlYynDSX1ov$9F%t3Y|PdjA;(SJNk--Al_S2hTp;5&_b(Skt5_MtjERU;TpW2Ltry`mpFfFk+J z-v`ln`oBY{7{7Erj0W;q9zjN|y+TmTeU%GEiT4#diW-_Lb_@lv?{^%H;uAc9QY_S7 z7+Mpl*hzHslxmzp?P@6&jxKYw(`XUb?isX+r-5ft#eAv}fi4wRHWH00sn|I*k-6S^ zyRi)R_0`4mzEySPUvvT(P@oW{~Q}qEOE29!g+5x{tgc ztK0)rVUc1F(J``ds3)K5BV^0@Jw`KA)k-|tIaRR)w4Uqq394@{Jw-W;zlrEWC4Dl_ z&>6<_=jh5%WnZ9Cg>?om(PaA5SICgQDG421C%s1IOO<_t#xRpkMsGva%3IVZL3)RB zIhPbPl%1bciS!tTfyG>MsN z2HI0e%0!90@~`MMujm_^c2Z~h9gTUWY!+%;K<)iN9c@%D8znNQ{)r+gs$358d86zv z^pTb3e`vO)%Kb(*%s2j^N5!PSX!gJ$+|k)Ri@C5tMvev7#uIr-4SO4(o+tC@NAaj^41=D1oN4 zuT~Ppv4d3#&GA*NGztikjM2kCs!;|-F`k>CB>Fo3D^~YpM;)yky4OSH%A;y6l&ye# z+p3j{$ihgfgrY7fTNy2Om8u|T2dOGbnxIyyp`v^XvN~$V>!^XAGe@t9=EbXAEtJBp zs%c)95xX`D?5i4e(45JN)kR5Dq~XZHFr6?Es=3tTa2IpM0;*0+sewtRs3Iu9zj7#hB6w&2UpIR>(C@+0N)a zPu8r_Zmx|ks1qZ5S2WaA>W1!Il)9sRxvJ3v4d59}Ph@DOmV2Qd=_+S~+L$V9i(0Tl z)EfoxPWC~j|I|uf6rQY@9Wt|#?9ua0%JxH@mMPXBg)lc8fGm3`=75eqRk?wv4Wqpy zDp^(8LCBfAdoZfc_qc|j!Tf@GDEe4RXT^VA>0W`?I~*7ZTFH!=f!w8#-PXaQe)9*dh~HvRHo z#;EI#Rt=RVA_sPTC!yW+W|Pq#o^DS;8GQOvQ9J(1kOvBPQp^+O@{UhK{Rc_Y(StrJ zHv`!-M$JTVtWIX3yE}D^+2~Sv#pa+N+a)jL!rkqSdZkEn(F@k5^H9bQ#e7gHM#=f8 z`fPwc2Lnz}as>%@?cORy2s-dmA!&u5#Pa)eLC|3TJ0=CyHf;w+l64 z4Bd^c(JKd{=6ni!klhx=g3!HV(q0r}DD6W-TdQ0!@?w3oAGwrO>;S68J#!FUXUE|X zikhYDVf3Mg-rXZ8H&W$7(6uot7m7AkQT8bMQb#q8p@kb&?l`K>-E#t+rEd>IqglzF zL^p3Lb_!W+mBP^y2h}}|YHd^O4BGTmHO``KJCuz;zq%_HiA*`?bI2i4HO`|8l)He2 zpHTK9T2WexLbqF~+$A)uhIAPnF``qV|SE2!{B=_+c)_w%ozKf~0@b#%CyvNuoy z*V;|A!9&?w=qT6o?Y!78#qOYd4b@5v@}h6Qi`v(gVo~{q(mk}oMRo6^wTuf7(A#T@ zJwyS4QXD$R`1=TLovFHy(aKFyJZjC%HvzTdPI-b#vJQQUK3b?;B5Kb5+B39=(eF9x z*V5OH`2F=M`GYdzFMxm@>e(9_|HB_rEaD)$!Uu&#ZF{(e(71vynv zEEUx)BfUqPJLvpApdg+{sMT%imC0)_&j7%9c8A78=T4!4GtinP4_rV0MGT+D&hkZ;iAeL*??L6n+U=0G(!KQxF-LsfGax z;f^naCiAHpqQ87bg^^`Z)hL28xH^lXDjt#%a%65%4Ao=5u6SNHMm0(x2WIdkQ7z^) zrBECG21jZ1gS|9kRE7Sp49Y)BGC_@QNM%uMOC6&eD$hEgJev1N*$Qa3ud)?UI&+#z z$R|sxjIPjAS3$!WqpG5uVv1Em*Q+a59rb72uYtauQLH99*jcKD?la3UMJ*brTy4~} zoMLs*AuE-ui<)q>dMKUUfcj|sBdG!MuA*#16qBu3Beb5~g~n(}ywn8kW(T|}I^!la zLxaCcX6TfU)EwmtlgyD7eJg+E{|%(OZ%dt3D^z}>)EZT%Pi%vRt=GAE?ByjP75=m#@>3$)Ed*^bEMgj%sgHTYCJq20|SD`Ztm+0Mv}S%x)Q#*Cs1 zy5g=FKb3XQvQexXdYh!9bw@8}Nj=c`S1Q*N{m8F!y->M6?~GI4)4M%gJSk-5cGG?TvF19hZN^hCB(rD^CL*Xi^;ab3+og+D7c z6D6~UJPR#mK0X^&=I`3gL7@*7^FmkY(Y?`RVslY!fQ~y4^`?&pyCe{^GA07bhM2qcc5aM z&=^)M0chY*WjCY8j>>L9`(vf8DCUQ<+t5a?we4s}WoZYxR6*r-qD*EjyO1B>kl2kD zPgN{1FE(7UJ!k~IN)Xz4K-s-$;B2+B4-H037#*h8z4P)a06wVCvAZpr1?jfl0(X#MjKlzb_V^oOy$m^JF&_}pv8Q?k!WpQ#m=FX*3x-2#7uQBpoT{j zyNJs5SB)rClax$bvJ?Mj=O~pUA3>l!Khum;Z%MOjPVY6vb-d zcU~-5`hzwyuKq>I=hX5)w6?jFi+($+m3(WZsq9wdN7opS3Lw`eiWNkqm^T@qQSGEc zs98~+vmtV*qF7;6nthNWs59TJDvB(*?u}40zPnHi`EU;w&&$$xmOwL@rIkc3!=+Ma z5m#qvG?MGt7%d+sl|jL8Boh=jST)L`VcVo~Xgj}fERW)+s9Xi~aI|6-QIX+_RYFFL zJ(bb!g*xXd=rvr-FqD=0=-l&zC&a@8-XFk*y z8Q)db4yALS+oJ+;Qa@yoD)mRd*%=#vjxd9FKsL-C2BLS2;*O}=3B?AXRCaI&qsm{D z9fA&fOGD8W)Q5+*{*NldIBrG-JHvhQ5_oxe4e4YcO~8gq~|6I?dkeB=nX3 zc``cmMVf*(=1Nl~eIw50xa>jn+hNHQ*%Opi+vrSoV?wz3zH%L$$RMbw-9!6?+9UDZp-n(^f_ zs=>TD8kygcuAtlJRqiS(Gfj1`q0_W{9hHw(><0SIGo70#8{I;2{JP{e`kSuU9TdrN zV^Bj{zKf#2OEgoIt z=}rQg(p=@9An)(eQ#6QoBN18EQH^KlJNqBc(Fgu#!WXEmtzs`x-^q%-Lcu&ON#Sa*t`REt2JNC3OGa@IrMIZPoAeG1Um&HR+HIv&RJyoYd5?_skL`!Nte;|O=qUZw zN95?KSURfKRr-Xkjn%n)Mltmj`+~aglr#ffx~aOEC^}vGin3ZL`wd+fq1bm+n^7eT z1#;XU$i+a)My=Vo_=z5|a?C;LTclsex3csfGG4P_r}@@NLl}qhqZ2%DDS)!rJuHY)ycIJ*=IllmLYuwRo*`Nsp=@CkJ4dl1sLUbN zEsEYVQ{=ywa*u4Ua>bBoF_kNhcF@3s0;J(^60}{#VQ~t#=nZlj5R?ely9a~8Sx)@+g3q2gQTix0Ap-5 zbk;$tj;=En*Fg8D>$TNHJs#_5wNOv45>sRuuNt*c$A3~C6!uivx+s>uxE@--HCZ3U zF$-ycjChvR5WQQg8jX-E^ErMp>K@{!Y!j5s%#$BYYj08InxUM9k{P;3Pu(0f$*-6> z3Ob`$3$%zauO&)h?a&Gx43=7>c-EC|&_aHR-4j%+8C#jMZ@8MB(~jO_L*YmNLEnYy6O6IHh>>i=5mhC0<#wmUMo zBK1I1PD(vd5Kq>6p_g21Hprje#}@VUm3kxJm&*1*ohm8T7g@4XV}}gR=v?g4FjkoT zklj7S`Xdu&{R2=4FNbkX+Hl*=l73`ZGhZk?2S##YUk$%&$hHonsXngFag; zHWn=zE{#Jcm_dz4GuUBs%Zu?kCZI_dC3h6GNt%c%2TGGr4p-A;w2&Fu6x5}ujy4q) zc2dj(9b~5Mi5{>nnuelz9zGozUsJgm$Z)+h6FE7k#w?V=KId%Iews7~-MS-rp;iwh zZdj{0!1+9twhdWq*ci9v$PtWohPk9?c1rwTJ*tA zT8I9-uk3mhML)R#%}v0gfc zyjM!c(b6cjasq8>D}|wKR+A^u(P+g^p+>CW!ja(&=`^~(U#*-$H<+uOMVnb4N1*Ic zibbMS?x=I9du3(MqeR~43usDD=_1>fS~#o9a`&gO(Roxfm3-T)K<0_!MH% z0oFbD&_70l`>4`7#U3EnJ<>xIz{nJbCiAV{N2ot@n#ahwnPTzClfOKffQq+K_6hP~ zYeRj%|IVfHRj6cs4%myPbiYQ zpHa$IWxpUdu96Hiy@Rrus8nm|D>}|DyK~B#U`-Mic&ifBdqF4EiK0T8DpqUS(zi0rj{2w~lS)WWUTFrQ#PhGD2h}UW* zKT6rB^DBVjd9qdzO?8zF(5IQo7D6TH+v%>|*YmsT!YJmmS}B4Om=6_2J^9{&5lUun zwiv3!SX(?VR!yyxKvkJDltc^XN~O?ko+*|_zVB4d7%f<$mdl{AQzaAR_dqquqPg@N zEWVKx%4XPqFK>KQ_ZbM|m z=+X$SVtv^dB{G&ZL07nsnj*eFY}*V~xU2IsLxW5dYmO2l6f;Nlyi}tFI>^kUCF;WG z)(SP{s%woN?NY1_s&+-OwrC2o@OG#~RjEDtHCWjWs3`rP1*%1#*bz17iIgQ;aY^cg zl0PVGg$~`5I-_c7k~NCr{_T>NJ*@V+qS#2)?S^`$N!|0xwNkbRI=e_UdZLZ173+oE zTkCzcK||O{uto1;rQT>HE66@*74KwURPUT(cF2$Kt=Xg7qt#wN)W4p}^+(~+(g1Y6 zn`$_qp7iJg(T>Tg;fVUWOM}pNR#}6QRS(66pnbG56g6gcGYn;0D?1$3rYCelHYqCS zjM^Sj%mw{qbaq8fk5yv?`pzn0B-++Y8ik%LRJqaU3fI9Hw32!8ShNO>LuULUhd+ts zzJ+hEy5(j071jil!E+RMWaOt-CZb==xF;cpbZIiOqDPv7KDJbBDmol5d7x-^H$72r zN3}N%4dyeSj;!c&W}x4^Ycr8;sIs%rQohkO8{OQX*c`NxG0F>VVK(B8DvnibE^5aIrHX?YE*?k%lF^H}4oLqmTlwjK@k zRcr%#OAqXin)1|jBl5ha>?ZWYT{QwwAjjQ|s{NL>psKuUThS2<)!2qM(JOC9Yh9%s z$b$ZFCyM=|a=TC(JF~k{aqhQ3G--jf2eqfS4MO?uD7F{*5Zi~Qa`yzIT^-cke)NZ3 zwFBtrS!EBR0(GQAsQUxyFzUm);t1N+NoNp(R=$=((cTlv9!0~s!j7TDY{ibFMq$uRDMy*^z@#hu0j3zUCh(-(OC$Auj{)$~i+uuspP*-}} z>u55g#tpQ(p|Uqo{#4bygjPdO`vfM7cKo!qOFHyth(ks-0J0%Hu@}9m%Zp?SzAj54sZZi6ITE}>c#_>tN zL(5rVq@br|^&X_6ZpV~;kCqupA5a`?p)_R9p2A1u7_MwOieM!9gzh;?pHXS9(=X_n zo9bqu-d}XIOw`Lov9D-PHNQZy-%%4*i&b_6ezbN;SV*gO*)r#e!3|2Pz)Tz2x|1RZ6PW+~& z0IJOTqadf))BT^aU!tS{Vx?fT%ixQqnbNSJ$6i%6)Z(^O9a%)Ey&7n)zf==# zdZuhGG`Y57rs&BjsWv+CPT4xB$yc>p7ky#}qaM1z>bO3-YppYAfI@6kqan%(P%Dkl ztF2OF6wLl}6V$?4v8L#%w_0h2)=y9?W~dlrRCBaDSLMu6KSt9Q$j3~rv_z4tKU$%k ztCekyj#pHTHfS!ti)xF0FITo5+LoYfd(@7n!X40y>55q(OYYi^Xv0IbY>D{cx@{-4 zx{KPgLXpfnJEM5+P-~RLPEi-sgV)g&9bug5hI-j5+a1;5-s*wI2P@VS?Wgzdg(|aC zWP_4^C}xZL_mz61&wS&e4{Ap5*ca_#MPP@DFm~Ic=^NBaKV&ms+5V`utFi;ogMyL+ zTFwxlj}RgFQYb5X?xqx;O7hoI)XyF*ba2gQb=THLk6krP*<6H4Lpa7K$v zm32YWo=dK1Z-!bKfg15!pOMIoUVan`u#rZibmmuMP+jI0W08HBG!DHPB#lQwc9I)% zzRjnAOk)lPxOgvZ5k@W z*-uB=J#>CEP%vw?nP@Rr#4L2jQrX#gF+Tk{$hM=hUg(XbVQOe3FM6y@*2%+pzO7`A+E2Qk5RYvsty!*%Xy6*dV zo^$$s&w184Wfc1sQ&6$q%1%YsSgVDiN4pgZL&5CvOhbwEf74OdOlbys!rC+()wr&@ zGttMn(kx_Wp=<J`&A4q;hl6)fqa*Tr`>NJoJqIbUtc6Rj~!AXSQlA zL@^v~5wbN`b}=eaPq8JaYq)tQEFrK;RBe{V6TLN2jW1|a1?ekl!EWt0w32WCJ4$31`v=-J zLUpr{8+~Ussx?dci41Q@zfhM9)%}ewvxoNwb=)wPi+@i&oMj z<o?8g>Dr41!xl*1=k7#*Mo zDT21L?lwXFxywvZ`=g4Pp@9XZqNsMDR1B4_saA@kQQQ^gsL?IS0*&UHv_u!#8?i#> zeH61s1BXZ@kTZM8B~cGP@lxnK^WxIT$wexIzUd#2vgmO`opU)9RZ=k<Yz9moqb(Ypn$UV(0Q&fd$fyHNBz7Q?-4p6 zOL{^_WWuM`05u&eIicm;(+yDvo;f(9*L*H6$URPV8=;>biZw^F}i(OFbmL5%>1I>hvUf@~5J`(BEo`^+u04N*@&MEcHdD zSaJ136&bnuBM;sy8GyWBE9QgvWAYvYkqtAQLCE;BVuMk_D`^NiHBH%}D9b?N4>$Uc zq3;@op1qQWqvE#uJp9lBHA6X*{acO`3qta#c=5bYLDKXazqdFKX-E zdWl7u|LtID3M#lmKhaba%rQby{AgvvP`kB?O+ytp#&q-_-_Z=@%rU}|Kl`vV(f%RI z&O+ZP7lCYDrP;_}o61F^0qhLSK{4!1%|(T~O7qYade8Z&1>gPxG-ae>3sEww#6_qa zclu&9y0FSELB)$JyA1r6V!VH{AK5IF4xq@6YA+tmpQlz5P%-9J2T?G`NJLiU)k+fbvrvsgsJ5My zjHYBuhf$xt(h;=#qv{?-Y$bafL++W%9?vUhq4rLoAKA*DM27V9r_iYTI=|B>CQR8g z$cE?0XVF4F=W}Swap^qjVJ=-jOXw{wqV_#i;}V+3p6g}g@L9Tot`|}ED%x;Ix`y`k zRNd>yjnVN28umlFiS*xgXa@hOYKORqz8*`MWsD4wGOGAa}C!Zn52P&72LU=17 z1I6D`_Bra!uEGoSgRAK!s>AyPuaHA+#a^SoRirnl8rRiZ^o{3V@6h{G(tA{jdCLb> zak63`QQ}+a6Z*h!-F!wCJwk(uEZJg?d#|jo)aJudb^rQ&(zSWlRv*^^Yx0xc-5tR>pX8Capn z7doyr%B4>%f#TU&DTzKUlS&~w#{1GJ-BIPrpia!}%A#gADpwB06_;#~;~-`KLoHbE z*dl&e+oL?n&-GjZwcRLHL^;7yrMwvZX=TKt5sxY;oITvCXnYB&8rqnuY;|P8-ct?q z`L$v-QJoBxtA+00Qp^tZIx5vh(Y=(dgDxIctS&NS7qlMQFijM(Y-K<>qqZI8|!kUY_}BT@%c=Bm^YC9r4H301ABSZ5T(oU04!O;6Jm z84S}gywIr0s?iOl@hx;mt`imWMov`~>w(%)wU%ius{N^ojoH??WA91d2>lY$Te?-#;0Z7we$dXyo}otpuRLd>?_R&q8So zy7FDE1R1eHwvNO;)o&trVRg9)H(M87nS!i%c z#Uc=YUd3ZJx}Q(kNHngD&T0;-$(219ooCN~9@@l;W`16l(P{yjGf%OFXxwqtScKX$ zXI+fO4_0gmN?I)~MP6H_Whj|!6e>DbT8>QLODoVHUuh+J)>>MHEVx%!qk^pJ)}U$h z2WwFq)~V~za(avPD1vW)16s`(6^(A}l{TUW{4Uxi)XY+?Y({4Fq!`qS+0B+b(RXe| zCXBkokxX6tL_CfqLyM8(P1l}XesVm(; ziAK^*^l^t;xrGefRQEQj9;DbE6g*D4iwqJ~;~tvGXn!9K?WgR6ye$3NL-e?uVvkT) zdZZNexuBGa0(j>6I4{O1^aSO&DEk!c@l-4gIWsOiLv#6D(vf?4Wit?ez|rG5x*jFH zK;=&=`x15Fz4lk=)<(r%qyAwYX{};kP{LWY@)eclZLn{s8U4n0WSUkDgo(iL#eH1H#EL%t>D0QWdW{Q5< zNM`6NDvIvbQp?3q&~3$vqeAr5=E!`#WP$!QlPu9DzI`h+l=nNVQ6F|NN}z`alr4!$ zHCL<@N`0VX@GE)#C0a{mQ19+iS#*I_emOL6hU(g&Z|FZX;kB~1$cz!TJj(G_-3sV* z6{#ZH?I%@2zjzv084Vt!8dZ=ttHr9w%}KFp=o>q6)lqh^Vl|N0Sg9sTjhAX6XZkfe zPRop0NFC9aYBnq zE7lNA;)-xab?Kj7&^o@$M(7H&>&B=fZxJ*>p1hUN6!FXM9 zTA&VJm2HXQ_bw=CF6zhUkR#2=f>TD%>p$j2WH`JECvpX8W zXXTA|4PNY1n;n&l|wtu94D0H9HALXz=JpgT|lM>h)N$L1?f3@feJ@txN#B+iZ0wy)))Q9jC&Y59ir@T5n812JRxP>$mg)$$Xg)+HvB2b0WsyiFy)K@GL4eO>Fb5JRF z#pa?r*Q9xc+8vs#FL@>dfUq3RP=ZZWFC_qGJpVh**ECH=Quh>BpTure=ROYH;NvPT{#SWqJ{6xvfcDr;K-Iy&MK~4BBkD}?^)5p-K zE{YvTXIm(C0`X^dJWe8KdYV(nmn-%(GGdl?2E`jIb{2hN2k0Dn&`>qbqv$cx1?2li z*^9`%h-zFy8<{g)Mr|UcD`<6N=_-0ZOS*<8afMw+`Rgcl1DQWndpA*7hI9*cV^8%q zTFk2B4oVxV>|Hc0SFPMb&weO-A6Zi40qVhy>q8XHTp2 zTB+OxWv&k1o-QA)5J9u>ze&j&O{G1jNRm(=mptc zsQpC6dLthbsSk=NC-p@$STFQL1xHBz(Z&pA2cUCn6!SqxcrG+BFUA~h5So!94Myo) zlS5GKBgKZI(#%zS(fl}NhoRc9rQzuPf6DrymU|TQM_>8dTO-g|cCtpIk!Pe)=ni+! zXynQ$9)NyFC>DtB9gxPLQSVeE2vy~d3P#;H##pqMU8`{@p^465Jo>m#nt--2=bwn? zuwDp3RTy0+p+etPZZc}fdU^_4$DC^_GGSI4iaK}KF~ZOQcWD}0&OB#2GBlHBpw!<| zIO@jtHWRIQuj9@_miMFxWW#RMY?R6>KN2;HQQbMHY*%S6T3A-)<{>w4#pa_K%y$={ zztPe{)R?|$5$e@eLdBR%twt$tq%|maoU|5wY^NIQP~vXI)+6^4(gwt@6?;UZe+G(eL}yM)n~)o0 z#b&hRvlN5;_*S;MxVKR_Mmio9b+%5%-y&TyMl_olD4yzT`5>S5Ief z1+C^MzlvURCtpK1&nR{sh1OSlH_%%r#crZ+tetP6eWet;jlAgp?x6Ma6uXN|8FlZW znJuOJ$n&Q30435ZKSXt(DE0{L@2yx0I?iu%r=n+E?T^t&W_?f4dv-dWqKbS+Y3L}| z}yzf12> zOWv${kKS6V+z0fJzVjn`oGE=m+*Tf+QO8Cqmx)~12l;}+W-9g-nID$EA+Ougchq*j z&gBQXL2r?TCO1(m8(m$X*iUqYe)kue#BBIC8p;gn54y*`PY!w&rtDwDtE3+P(9ir* zE~>+uTKQH;j$B~|Xf|`|{AjVgj$w#QR;gS8)X!Mif+(4pz7g8RE_NXl&Wyqs8FrEi zqt;yaMUeXz)i6O`LzFc|X^|MNv0%#fl-rdn#8Py?v~#Ir8E9~H$abxIiWs$zYS4$_OzVQ2Szm)G;FHW2#tQC_8OzsF)G&tJwK>y zQ*@NR(-n@lIZ8#pi-%dwMBQB z-?*Vhe5&rq=bqFKod}ma&==lWXpeG>DCUXwMJd(+y?0iO|0dV}J#)rR=n?m5XXJcZ z$LNB#_$byD{p9=dLXTNJcSEb$HR_HAZj-!G>_#1<2kQAov7V^u4XGD8eM5D7qsGkj z`=H&PQeSj-o$B^OjvTi?dccm;0A%1K`JhC;&4K9TN7WsK>T)FvMst{v4?z=S6&s4Y znX&nz2>Od*s5WnK3`Ya_hW*gXMvD2Pij5Q-ftE5e8Hv6QmPVmXd}^an$Z{Pc0GU`T z8;F*(dKrV}tXH`p)UJ%qJ{TD_RctJJ$G0^OHRR_VkL-9BG66+IDmD>SVCEEpJh@6H zp))h2$*3B;3RBRCbj7A3D{mZ32 zhXSR=XnGT6m!JxatV_{c_6U}tKS$JF6#D0{8q3j4=0Ph^F3)&ZB74?0t59Hn#a1H+ z=DBN7MOSGp>KdSO>(GfUimgYUjLI8ONp||9k#!@*Hlh$q9c>fZzv zr0fH9oK@^Y^q&2)M`#rzW(ulvTS`SO9;?P4pzD6$b6$>FHotn(o1w=jIyuLx=m{3HR{M!@&@%{rS}$nJ*n6`)Pdu^ zN1NG^_<#mKmOdiq|D;c7c|Mi(tzi10@Qv5>?%BV&z@@u2B z%BRVn|4et)FhIVE%Ch9}Pvbr}L@SC(1(2JIvIS8cL&*p=<@c-jvpD|S=c^pQLh0|o z&rukSs2B`+}WpAP;T6s_{*Fx2px!a-Ayjfox1+tE*gRb)gq%Nv_Om*uaFAv4+(e6ho zS05SnRb2S~W%E*u8c|4;HINGi1#e-yD6drfdsj(OxxLqSHf_ZH2C}gU}jn7$&tr)%z>k z7P&4|T{qN^KGq#=442xW-_-R$XW3pM6{#mm`yll~OF8@A$k>li~&QT7*x zqAC+5U-Ua!8isPYSBIm>6xHxU+nF`{qkKEn@(46}jWiNjr%9tw=vUPpjh^St|B!RE z>IR~Y^ju?5ELUt0$_Z087>#13G8PRzq;lg>WPPf=lbFZ`sjqa=LX0)x2juwOJ z(fe#cW6mkN6`8Uw--fc7+s2|ttnT8_(Kga{^d?Z*9cVJ2)lO73MX_C|^>Ar7dStEa z9^}bWue~UV_eJ)h_q?gPAB9wv4j?v%JmQhrLn#3T-=ue<-gz5k=16yt8>8u6)atil_mF9vYTQRjj0O)-?lkEk zDpXQOdxV;fS1bj6IU%K@p4CF0H)X7<~&&XhkVwq@eUFi#Y!I<(Dxdo}*H`KPD^c~HjFZqEsyDOH3N*|E2 z(H~aoKT&=@zhCG!?-%_>ml`Si2hCu0mxHpH!~I3$dH3QU>eWfgMPpy9T)tIOkeOlz z=o8~~eiZ5~8KN_flr4Z(AD0TErmRGa&|a?HLg*Q-7^AYxC<>!?O;xT4I^0AuLCcuw zo1#k7B{TG2yi^n&Yp-&}P`@#X6-Q(4N#^Jp@9tTk@gEhlL`9txvqFD&sIE2Y87P%N z>ll+uqOyNgt`vF}pt_~e1?CZDP-JnbEb?JqQVtb7BH5tj^t=4mX#V5qBW%&RD8c~j!+ci!hnoIrbrfrY>PARSQ8L%KD+>Ri z<2FNeSRXY<73V420&U^%4zxrm>}j?_RWqg5sMLI^4I2DgM{A3`&q;15)m3%f(bbWP zwL^8nbqtR@{gT?F3aOGOs?1J$2NalJH9Dd(%tksPhsQcvXH>vK>VozZle(fo+}&Qt zitD}`+P6os?&vi0I&Wk#U$Gu&zyql#s?kU_dZC4kTfI?(y!jt0bXnQHsK9o$(hqgW zQmjA9=`IaG1KHL0L3Zqj3`BpjRAUfInyu_$)Pbj@Lr{O_VMEcXSIYXLY2k_uLo;|r zG#r_AR@M*IWS#7fvhtn)qqu5{jYOlvRBjY%$ZTXZvfCg9pgz3A8Hj=zKgJ*vu7e=7 zFI2H$w27I~SX9bh*>UI^Z&Z&*K@Q4JK=m16C!+o7Di?ybS5a&dO1maaMhT2>Q_!rQ z(o}Soby+C#nWDO3D4KnmY3Sf?#ipYOuCN)%d%3dV=*1P)or%uIVxri5`Bx%SFuwlqNa2jnQT(_4Eh|RpYkk9 zW2S!&eP1k{N9MN5UO>?urHg0+Gq+1<$_~XY=ZRI(6%-jNT}3PCbFQJP!&L4%y0<~u z8>ks0=S|dOnzFZ0KJLrg=uSPw?x2^!(p|KZncF>dossxHYC*6300qrb%MXzmh{tG-k7_(YJAa<5UZE7BXZxPi*OMZ4KwdxzpJRpWhLx$@En6v#FH5q&zZ za-UEf&nrHowJVj)%!@I*{(_>bD)tq%<9hyvK6Bjf=-C(j96wMIP0&2D(4;3)HY!_M zHGZNNeWhQh)IrtwjkYrG|3Tqbl+8iim@)oE2RW;MXbe4YE_%rLk#Dv1Wrt*dx^oBQ zN2_?#+z@4OM-@O<7+ngYdCX9ZkV}wM2+id?H%4}RE``z20jg01`P1i^AU|TJs02^2 z%upxB(4y!UbNOQEr=POL^J1M;*BreYELos&tVAqP9X=~77rLGV&;(Y!#I8Q?aV30Kbb=4ej9CsE&%V-&6xRGZNQClLJ+^7K-&% zIXjfaU*)Kc4rQub9c0g}zAjqB_fZddxhZRpYNjeyAI)8)m;*Y=x9^Br9#-83$ct;& z2|Z(KLwU zd-QY*CG$hN-DY8WcJLb2g!595p$m(PvdeKVNOxab)n@@5z%I_hqK`YtwU5mPmSB-V3!hfo<9_3^x zwgF9PqgXVG=`C$UB@QXO2@NkHZASAGr5I$-?+Q_ou@cd z>yBdEQLl&64rEwE*`26Zwqm=`5mp4d(Qr@2_Mq#Jq`jyHdQPEbvP;=M6&mEoG0OoLXx6DC$2? zb&sJy-itks><%e*0{L?HoJ2W1KRSixKax(PfI-q36zZ*VXOS`E?>W@svRXNhR{2X8 z&`8eeA~IU7*d=tVmyUZGm0hFQ6*SgK?OjDXFDZ5ntvaRHbu|C0VmHvJG{tVBo9z4C zLd}**x6wK7fIH|1=W-XNypZl817-#H^TbXK#fb)KttG&Dy5pmO$l(=olqY@uwdtCOM)P?BX>*9*L3@iZGTMqW)a@&d4=a zt+=28Yo$i$6+K{M6f#gpYl1#73h+nW{oM{quE?17nxXQ&q~>T5V{r@A#8~B8qV=B@ zYlXfVO0Ch{7E&8jkU4Ezbe7-$azoDfm32q%tkv70%{3MCKm(iTtlFa`+{>P5qODr# zfNo_;9Z~Q~sS{dCxz4EL48^*j7ko2aQP@spz0mW5Qa5zkTIISU{s4oAH+r0?Y!5VW zsLrYlrcbd<{Zqi9QIN1!13 z?~y2SpEL?t+>%D4_x$aY0CbueejqA2L#>QKh0aPrsLxOxHyD-X+8B$5u(BP8%A`o+ zQHj6GPC(1(8z!Q|tZYM24)fAU=s#wyJe>9~G)kI+#v4de(QM}bp{N||i7<4nlCsm# z;^B%-M|B2EGtlyW%7&vhR*KC;gV|G>h3q1v2=vKKKhbQIaYBkjyGkfK2i?t3-MJ{Y zr_OX93QtvRK1yeuwE!9EACHCTB5RvPXeaBU#mJO9ZwZ=QOj?SZhD*zkJH1mBS{kU> za&)1;Vk=O68^uUxwmR@#7Wuzwzn zMl<8si25^%ZbGk%sg=#>Epx3H)YMkmf|lk=ThWG3(l#{EQ7y-!D?`;@96G?veLIR^ zhOh(OuPg0DZ)Qrn(AculZj^jqt?WVj80+?;miLw2hir>V`_ax4Dt7>7-%`1F6hB?D z1k{D^?I0?;P)bD4D(WXnLY!MRAg8tw%YU!^UXV6OK>t|7!E6Scj4fxs4qn`Jq3&@0bYA>P@ zT&I_i&r`L089n4@yMopaQS2(3?xol@b+qE9VmDAE?-Sfa4o1q}Lhkm;-bQ22 zD0T?0H~S4u&p_*_!a7v{~6(KyEY zCwVdUx1OSEO{6r`nQ`zL@*1IIq@!ZR70W;+xtgA%lM7Vi1&U>+^AfEnDZN7Ht19~% zHRO(egF-l~x9AjO$~#mrKsDZ@BxV;M&>j+Jtd zHP_HzWSFjU|4J)|0o=c7oMHy(Nj25YkIpdbH$*9GRIUJ8^hVi&s3ZG> zM(Du}l`Dkif0T^TS3i|2jA}8LE`m09mQ0Xm9my2+n4=nI$l;ETQ53oGnHEF;O;)Tp zYR|WCj<)Sl%mU4FR?HH4c}Z62HSZW$qilYYpacpUr&vk!tEcLgLSGoSN}~bngOx$W zxzEd@pX_FoLkrsLTx?Lp7wJFbSXkw3(GN!0@~G)OuB?q*Xw_+U8%ZZ9LKw%?Q*9oOC4{wOJ(EB)}9kFW9 z1w9?FY$G(oN7=@x$9Bb$n}!7jMNnp+byIoly^-gmpoFvsJDuI>g-33st|XST}T;nFs&vs{g}>k~g~ARqBCu zaGmx;d&v*^xhm_A=5|wT1oC+! zjYLaRrBNuBr}?ANO^zFY=J!xG5H)00H3l`{XhCQ%eMvAH&7R0uWKVA~4rTH*bv&9@ zM6n5|+XJ;S5&aEOECh9Be4B*cY?UUX!HcCSs868EO+{uSq)_ySYb^{NW}Y(*nQ&K3 zN0%9sXCOxd#lq3;y^765SLo4ap|-3@V4G%w2rmJVX+6qhwYUL&o+U-2WUh^kXkoVM zZbEDMjf2f7jjJvOo#b8AE$9m?`K_qj25B1_#3vq$+8ax8$bkENJGz*pay!s_?$w>B zF4x8`w18E@Zq)XNv3p$RH?5P5yq zcbSNi={J(lLgx2}&`9Pg$><07(P6Znb<`2mnbp`)G=|>d7;2lS>~UnuI`0H>px-!& zj=z*nAv<Ylh)Ok6>=G)tQ@V_1 zE|RXG|3<0htLT@RbPaiySN1yk=qcSmd${gzq8ik=g}Ts7-A1Kjr90>mpZHyLhWqUv zT9&Mz=sxPp>iq$F!Tj_g8pb~MBV^A$T?(4dv+7i|mAmILdc9V4pP*6nwomi2tTocm z&IXD-L&v#i(ou}7Vi~CJI_WvOXs4E6piMk6dx;GAtX?7Sma6+2mFC-egFc>C-M6S7 z^QL!*UuN=nk17~RAJ8Lj)%}Rh(zky?Cz<P>mm`%}OZ?Szn`en3Dy0D=Ce-ujrOxg@dw#6N6$ffm;?Vs2^{So z`m$TfMVCJ+n@=B;e;g}+1JtXcV);?uODboG)?ZW01yFz1Oa;*?_M(kY6nnjeQ1`o% zG1^~FDvbK`6BR*gI;%Ys6y+wFBGVQ+t{DntkD@4Q^I9zzLnaMXw>a`1Et#X)E|LYB zUsQ#mev|74y_)NZ4?t5nw+z2v=O7u1j4nMUYD zsLC})Zmcw$ppps7Hbw8}ORgxFw>p}k4y?+XqjijpEzlQsnOdUl>lJH-#|#oD2MFC-6S!Ti2G`phc96IEfZ+yVLCRLdRFjgE?S zLd{01TxaCMN~8;#!fd1~%IU23ypVHmsT<1oNj18oFD5GIjo$25-5w|%^+YS!>F4XoO&Ys6W>BN7nNkyHV-A#R=N4;H?!si zs0hbhh|J7XV-fPHqS#{O_FS@swus$x-SDnHwDbewT|1zI~mT8Son zRCW~_#2KtcG3-#SLH$^Htwq_VlwF6~GACS*YBOuzfEFBI)TbeQn{1pCNr&5s7JhN zoJK{)NN13fv3}mO=$N}==TLYr={)LoLb`z3mX|J~j*L;4P-&jAT}FxYe^-zXJ^EFY zK!1M?*-ld3>&R`B>fS)H%@n(dp0Im)3w7G6>}^zwKIaZf$&~J*28OC}4`nm%-$x-n zs__7M*y(5wku5X$M`-A7l}kY@c~+f@cKuU(k5PJCWuN3_n@Ug72v%NcD2%c38M+>* zY&y#2{f-RO-9g#sD4BOsULdbr#a^NY%oAUs6l-N)qqy;ky+I$i_unEbuAFx$n*Epe zD2ku*1NueZ^brl>y848y*+cn^OxZ8aL^tW-zM!Uk6#I()v5xwN4%L;uBZH}``vawM zWoMzMx0TICHjHXN(H`cLzmWM`={LH;T<;G$!OxL{+?cceMWMbrgMVlcYnNPfs834(x<-EtPGEOjfBCXVg1IazVztN7D$ou?x`{{bg3r1jVtIY>LkE z_JS+A6fZSHvv{u29Q8b|y8Ooz{^mWTmMEsb%C$l+UTUQ^+PF=zHfS`vl5Nq}0g@Yf z$8Y$!Ba3f}wL|f~k_T#CO|7&?i=8D;w1iQ-1A5Ioq9ba_Ro4kMV@}u^UF0ca7v#%q zy(aRu7cAq04WT?T!+;PQB3?o=^8c&6}uPPt@5+*f2kM<_N5-L{rSBNM)l0Ce>~l?z1gnQ4td z(HoQvLaD6xgVBJpDmNA#S|^P|4W6sqcr@#UGy&C1lP03d4pIo(6r~!I(7sEGO-6&+ zZ<>NKLlv8fBD+hW=uJmu!;ryl)t!baIVn3GZTT$CK&Scbpm5}{NwJwIgz;k*>dFc- z0_C!Ho{e}#&m$7OVU9EhS+tVI17byuNIywkH9br`F1YtYGg zI_I_M;7Y~TAtx7=TaQ{ZyWW5*URO36W%C?tBU&1+>?SmkUA4{VtzS}c0$^T<^?Oe3ytS9-HnF)k@g@XR#bb@ zwFc5Y)M>ANw*7fAX1NE@chbQ{eaqjGnU;}YpE+QRSY-a})0NcU0vIb|Q9M)cVa(IgM) z5&Ab;*%TDeRk2j`o-yDt`p)0nd4dWaRk^3=-4p$kX{a|Vn`bDqfoi0q?LJZlibBtk zGd=$clzmZkUm|-)WnUo&X8*5I zPpEna>2qF|nQA7Azprv%&~*0ZzM{vi6#IsJU8V2H{DbrZEy&dwWTD$Xq-@l@uj>9p zvkytX(4dCWZ*;e+%KbqZ>~rOyH{79r(Veks`5$V|)t-ymarflYMeU!(KBfVx#%eY{ z`pMZFqO+USUIEmK9hQRV0W%aMl+3!U5SlwhGDepUN`+AtpK}qE#*D%QHUFxZDVoY} z+L$4SjfxdT^H!*CF-dR4`NYY^iQ3du-W+{p2j2osXWeUwO1UX(g(mtdYmGeUze}KF z^sOaP6#G`CkoPy$Esat+n=&ZwhGJ#Wk#maih{E5Ep2!9nF?;+ErCTXxi!L$#l}8tP zC{_V2;ybK}rn9!Ggq+zAsEnpAR;&uzzE$T}6;+N?tQx9bNve+iZj)-DlI%0pL|L`f zN-dOKQCT}Q*H5j~Mk}f+RtL>s9#j`KVLn_BJ!9;&NA+3H)<^djDCU3~@wYV`QNOE- zH9*q?RL%+gGE}S~8qFHg870{$=7JtSP`O5^jEmG5xwB8)1o<-8YKn%il5$1G`EAT* z=surXbM)9s*%ru{F{dT!I#97zXlYTEYmLgWSI(f|--FpyTXdkUW^k0mG~n;{_bVeo)3zfr`SMrm$Mp#%ugvh8131o>=0yiT(O}jh-XQ@XvTDD7%IZ~ z4M+QE&kr3BSIi&fhia@sovfwRD2H!h4Jyk$xE7r$ zDXl}s%p=#M`N2BI2Gnh*V$sNGuv*@T%5%MJLhBhBHlsu3l#M~Hc<*Wp+I3mwwxU2* zliN@nGptzDELMs`o+qX4Xi{6%-GTO$)Nywrcg}AYdfrR1-Kb-K#rB}i6Q#Xq(Ntyk zp_Z&@_M@C~iXA|khN@gV>dP);0&=0JIf%N`N+SBpZblM1!2I

      fBf5lF>cJp2O%4 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

      K#=-3x&GP?Ohb*G?!c*zg7 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%0AsaBlPoC=C{LYMAKolyXzl?ytOPwIj)Sr>Ih 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

      IpX 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%0Dpgi78)U}1UJK+LplnOzz}~k)ZpO;mqWvqS)~E&9 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 a{ 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

      mv= ze5=ry+0tsXm2Ybe`t?__wW#nSl~{)w-%)Hmy2YDS8_)tq*o|m1^T|!<%nWHWvR|X) zZb1**D7F>-r&N+#SSC; zYKk2}pJG(=Q8ag@6pc#TOUF<{#_8iIxtJ7#ta#FN0$KAeM=T0AQ0yd1-tdPmpON#nRCNMu?}#m|rPALs2{xd5)Gdmc2j)*iX(t15=gnC9-Be z;uZ4axUW&w9HnNWy3vYdp+%!q%Nulw=Kya}N)6Tb4&C65`S)lIPt3AW{XQ!D0bRc( zeMAn7@t;ry=KMM68G8VqQJqps%|&m%EA|B$aesV8uJcvm8`{E*>^u5K*&oP&P9@`x=H!bg?>^2G}Kiph=N+`xP{Ow z+GJsrubor`l?YdAQM7x#R1C4*Yf~JJPt$P?P?14OWedrp_bkZ}rT&phqIKoKdnf zRnWNoO8pNdvcp^z)d*6o8amGEm79+{xrvx+rBg}ETUfZ9gt`N4{@Wwg<`|E%iic4^*NT@;|MZ4N769Zi{BHmb61Pyj4qY z^o3buALPSqq%RuTUNL+0kGXe0)W$`z{>X5yGyt{ZtOlZ{lO+dq)J__N?*CLiM|6{K ze=z#Mr{onvkHIF&=Y&!|NkfriqEekvBD0`jsB9ahx}aWuq2q-W^FWs0B~Rqe&V(1b z!_0C#I`Tzl;ElXle@sAc*ddsR=9E>wNoZPm#U`U_Tn(SR7`@aKWI9a8or~d`e5;`-gfm!$Hqh!;=f$ciwgx5T z&HvDwY^AP4581m}kNO-}z71&RPsKK(Zp^MXp;i+W+l;?~eD`RI$|Q5Qyti|99V+XUpw{y`!-OB+u@vpMc1^nuYJ86`2Nxs0~- zQS1sT&7A)#YB*ZDhP)=J>~)mRK5zv5;B4f_eEb7CR9LAW(W!fieL^RTsca7FY9@U~x7R5(7v<(C z_61EWq}W$g;y^LJz(w_8Xn0o&G^Hc}n&dwe6v+ z@ei3>E0#~wX^%fA70Zvj=~)Y)UK^x>s6-j%tJP3%-lWz?D-mMW1Qp~uH$od(b+GvHXyK>S#;75ytR`sAOvwzrI-n9w^I|qqGvv*g zHbmcsk=me!jH~9T2(76t>dadp?a)fTeG62QajQML z;G|dwWWe3i5e2bd+zG|-%(XN6M<3P&-C?xqiZ*@FXR}16v}`N%gnq3X;y)U)u}19* zN!`%|_PKf>CvVl)6E$N-)(d5`7jAxXRp73+_VUY7=-I!C2}sCy^nb3i$q!63AGisXnwdGl*9`skxiIRyP+b?1bd z&r&TzQOFd@IWHgU{b5KQh~|H25Ib4JQ6lqkS9D{i@{K@qXuBiP{AJ2F3I#Ljjz-^O zBscWpoQ~^`%3M)w4BAM`8H;$$#bz7|VBP3}VyqSOL}r1Cd7;%y6&sK2xTCz$G3M

      dS7e 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

      |b=hi()zG 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�B3+I~S{jC5bo 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 z zsOLqs&8JiAJvB=8@}qz)QUMe~{#p>7;2J7~{#94Z0G;O?6-HAoD^>(;o1j=xl%M;^ z5IymgiXkgs)hmvQGOv|D#Vw?gc`?R~Qm8fej1ij7999~&V%1&-jY(F_813k#SXp#~ zdAuBQ8ZDJaGZ;ZCpyCxI6Z9vaR1p;#CsjfRc)P+BT_jtsj5>47RnUyV>W@F`?cHIS zV%1PE?>kgSW`(30DDjz86ZNu}YN6K7YEc`NVyvr!hL9Q8Mb}H{)9N8x@=Y`J_nJ!0 z(GvEUEl`V5iq%Iu@~P(r$o`Df5E(H_HA1(@Q5vHQj4GC>9N(lBihm>~9= z3t3S+q3|cF=ZsSBOD=gaX32i2Xt-MRM^Cx;UD5RJiVZ+Xuhe27`tn4vLCEZmG#HI% zCE$ka8EuE4L3|rS(Z9#4Hw;<+P%rMN9`C^oN8yE3&jUF#n|h)_kt!X5LK%HVqQU&+ zUZ~9vX%rej?lu}_21{emamGJy)OMnJ8H?&M>-wNLZ++T0RGj_u@u)9nYXTa(N%bb8 z-sDx2&>7DDWHhRZ>iMGXjBr!Xh-e+NA9~wZF@Ln2b<9-M%uBHVHX=wde#dy@> zeYC7J9hD`goq;xcOEb|0GVLH#f4npc^rHATsH=}plWm}L7_rg|GmbYiN zq3oV2-HsAizel6t&s4etdHJh!C)!?7+Jzo*FYHFkGF5L6N@R7q7d0UV-iM~Rs=pXi zp_xi!Q6_m}97-YI*pIfeb8!IiE1CB3XwzxM4x*Ffz=x0<`Q%|_ct)`!=nMNoN6{}< zoyX9OcpU#v#2sH&Y@x)eF6%osnYW( zAA2H+sK+stUO>l3DRvR{GE;v^$cd5R658KFx{Uskm0m%{%=TANNKbu}*U&ol0+Z1! z50$3miM8Q%)cufRH_%8E#cra#tg~*RPh7FLQR^S-?+*GgLb{9UvUa(b7b7dZk4mnT z9-w)a>g6FyF;VOh+VxR-j5cupK0zhNtKL&&{8vgvwfK7nX=p4@o}Zz*WOL6^8P;tt zP@Mx(I%>oIM+S;!b(NW?6^gw?6&w_Mg(foIXQ4gcq}OQue${(}JebAbqP-r9y+c>n zmwb;>8R0&lv`^AURL4X5gnp8xeMV<&6w5|^I7eSlGP7h3a%SxOifoyuzo904L*LQE z2htC8>$*yRqJG(m{X!K}q~B;3-{c>ZMplrE8nVjzi@JwP|4=C#Dc@kpaJK5@M{AkS z3!vZA6f1~4c>Y=l-Qm*=&@is6!e}>FP7!p2jJ7CRF;y}|iIr4Z3_UulSaGzEtGxs= z8!eSYV=VL;rBE+B$p~$juC}F-A-}Ov1~ugz8RykAP^>KKcu=u&DBVmdk7n^bS3vg{ zsTUIzP*AFf>hs%1mC&O#s%MI-^E9C{3LGg_K{J>Gs-ggWVfNKfPp+Kms3bW}4HROf z(wb;?Z>bh4){6scrg{NAyMrRkPv<+&=v(dKbct6!^hgz~CXpg=zmvum+ zk15s>*>K)Eq5CIP+8O!HP|OzHCVTCIhHz%OqE+NWb|}R}S zd(=Bhv7Tt;6t(SzQg|b&H;U%xbwD{A)WQ+jF|+r{E4`w6ebGqP3r=VyKe;n1c~UK0 z&;-s$KV(ey-yc2YeN9(%g?0P@RQ#Mu2cq)bR5}PHRa5C;l!)9=TvOE>f=W!5hN4!? zoWqc*zvPaNe~^ZwD9)e<%4GEML?;;GMxc^w6&s1Hn1#HMS&(9*&^Gdt(Wu20#m1l; zI~DUrwuKZMi=4a_^Fgt16&r`1?AOa zbvz3_Xa1dy5-uwCAKHiJASXuKx#%Th#5}YnLZ2}oE#^tY0yJ>GN*AIk@HCMe5)P`$g6*`ko^+Hhu zqvL9Hbe>{iXf?CTn!HlZ(ONX;mlTfPl0QeF`yHfpD26rmdh~@kbOU<8+CCEb$0)WD z-MJ-gLIGR{QONYWv>AQbCv8E=GgWUZ>i16ChMZbU+fh&r)r&?i&nvbguawbtCo1+r z+J$`9tKM!jny2}D&^%TId(pANs<#hWywEougRbsUX)LPNPA%e)-6O^JBl`|&aR4>r z8jnYte5He^3|Gk^^dmz39Yz71-y>)}`yfZrD#qAjXg)LXanzVG`vlruL@iDtUU9TP zh4w#Hz0+t3GvXOkfa~upN-eI~ITX!!pMctBtL=GIx~EDLQ8KHn3n-KC`64R7b&!M{ zxI-_YLF{u~Mx*VeE2ubY?5k+zA;qpC8?u&URA8Hwf|hcHT}J`jZ#Pgp*X~WU@u|Lp zTWGkmN^hf*H>EqMFuC$w^p0b>hh93V^gjA8Z~qUOme*%IL`JM!AE9MgYVjCNVXkg<)CqW;CDRMeK;k2Lf+KzfE&w^x79Q3UIw7wFV>9ceo1T1Bx8)bqGnWTMMA6nlv_ z@_U!BP;`_^vrvMgVz1H7MAdtPB5YLp7Nwq&-k}_>$@ggAX4U(EOu8%f5#1u={)Cbp zq|azCqe?bPVKwmu-DVcbK|$_{eMNEnMBk9}SGE0)GPkPj4>b3?^b_TDQQKdrI9K~` zRFGZMKWGklb}l-?itjIa+FWh_q3W!y^0`TuyQyA&6tYL91yCz?FAE}%`%)oPxPoMm zSFfW~7(L_s7C|dm@fAheZ>!W0O*kPHL!){2SR8ftSF8lO&pYuYkqh}%Ddfpo+z46o z6udMVVXV(6gPJk!8lyn6(z57SRkbLGrfpG+^5`FL+*UyIC#jwZTFaBaifA%FMZLwR8y=uY8WN8K%sM_mS{Ae+X_8x ztQIzC&TGY5qYyjA+Mv0N@@#>){9cN+M`>KU9ngk2m3Bn0-YC`yH6VNFj3$$z z*rL$#QWw;e6=c`EdOIXLbcr#d8_H}ebw^DYF?%2*a&&vNi{C}>iCT45yTRi#oXPa2J;@y5y+)a|%p-pGg%WGr%grkD@f#w;`r z`H_8%NAKE76VN?ooQY`ZVZ|n)=%Z>o8I{?lm@hipUa={tUlGOp(7ZN^`J*BY)XP+4 z!R!}+Lbxxdp$*%lKotK+nvP0dQ!g`6ZGPUF$dgPa2sN3adb3cQKxsCzWS0C7nP;iq z95m{VVsp_3W{7!tv9Z#8RGyh`0rIiaRk9H6=%Lsm)F)E0#VFqn^|u6lV@PbL8s2?(~hFbFI9RB`L$8$ab){XpK$_}nXS^3D3ba76spEf(P^~8U8QHx zS4QBos4UmjIdrkVdPzX;1}Z&|W-#(6qH*jaT|h;mReBL!z9=Q3p6jGbD2zM#GIHh& zGR%4Ba&=xs27J%g@=9a$6D6Y#t}0DI56pEe*HOT7#crU@0n$xm)LOcQTtcMVs0n|0 z_YQK+RnK?Po_Z?1hd$O)fA>-83yM8JF03jaqDSm~Jwk_@tKMT|Hca)NAR}gjrzmWn zl!`8$)~BVRis6bqLlb98&(Xg~_4fk(=IKZ}8dyxqKts4i)cn?I!-l*@khSM;U3>U~33xJtgG1|0nlG&x%>exhlNaKBJ)kYc})^91P+Iyp(o zMFz|ee^G{s`um6W(n~(w_TDilKQd>=E`U5Q>*p zse+E{AN#5(kl!7zhF*_TtUB@{d#!;Q^--)Q`oNw{EmW9eu8mBFD^>@c<#}FRbb=AM z9!h0pV}?4Cvznt~lNGZ-x5?q^qj!vi4N#d|s@D+RBF|}rsx*-rquz5QOLQ zsJ|wtG2@>#n*N{aHAOiGq-H3E=M~NK>XlTz7U;K!Vl7c6j;a-U%t&K{%6w4U)~NDY z#oD0N?8ml6BR1(s+aUu+r1mJ|yVL=7X)1L@re&l~XkDoK>x?S0X17IU8Be>QLR>># zku9r5J9HsLpV1BdV)v*!nzc#wdgSS<>e-_X>|pdnbDOHP7xGL~tT!6Kz3+gYl~Ji9 zI($XygVr$?_eIOOYn@PK#t3KhkZarp)n~=m57k(z(*Ed2S;-ZpUXuo(huon9(IYen zmEfJ7!RWZ56pb4yz|`w8TuYv8Wu^t`Dl6ER92F(j|Uj*?VD} zGyzp+mvbVT_*p$qLS|#MonocM=m1&p60~isVoT93=ImuCgY0`b zYDMP00v)nbi~N;?Ygk(FajS=A1+5Gi!pwsI853 z1O*qCj-so~_s5XCm14)yJ>DNXfx2=XoJ2h=RC+3}UfvU6^qxEJ42mW*K8rT+T;^O} zJ?@_b^x(5}9!)Y*X(9?RQtSfSd`REHMKq3kGzpbrG`@t+>{PwWs4`D1t{@Mxfvc$8 ze=5C(?7B+H=pmn$f}D7^d>vV`KX?O8y(is7)p|*{&=ObGyNyD#M`$1`^v9?^Zx22}TYOad6lL-qq@oH=ilw1ZTpQ0& z`7zRS^poA;7w9SPT&AO}2*ol`b$cljS+$m4qQj5X_7(b6N6JFa`JP{+GdET54T|Nv zdW#I0ci*9w6%~7rKDCoRAVaR4kLb??=@V+QU;2zjk|AWH%Tf9%zo4UxW;y5+JCt8h zLp#O3p*7?;-_ZkhuzsL4GR2?B?78awLiXf`zfq^r>iG|H;+S($wJy?MG%r>9hphO0 z^L#_4IoA}+kKP4I1<(X?yn?959vxL7)R6qp0Bz>17DmZDe<*?sZ>vR7WK6DLh-&lX zz8I>?%AzaPY`yIHD<%;>Kcs>OIv8?_my(mE*LN2zXJJ?_hTD3G^i&5&(^O3hIy-bV6v!ZqF!?e~ycp@*#`8}#O`>a|8WeD`gT-E8&T7OnA;+M#@m zFYQrAKgBwr%MproM8kROq!TL4Xx16EiB_pCntw&=g6#Ro~w zXy#J2a6vCBOZ`v>_T&2_(~_#^in9C^8-Ut5DmD=Le~<>DTx+!*jHZ%}x}kH7dP7iu zA89CBdPMbxA(wfo=Z^S84fexPLQ9o;piMc7d7{mM(g<|qoJvO`cSaB|^nojz|DfHw z^DmW-Mw#T?V^DEMd2e(tMx|rX;!P^`K@BFTbR4p~t=M?ff3d!`3CNwN(GyX{5Vf6z ze%w&K$!Jf1mHMLp?khG0O=TqXLw^`W{ZYmg)tic}-Y6D;zOc5Lh8C?*ED-(eDNRQU z*Xjsnpt_7)Gf}^m>Lm!3?WTIO(CW9UHye%RH<|uJ!?M+44zlL>=A!rYR5}l>uc6ZU zD2Tga0cyeeZXvP{Qfv{r%JbaC$l{brm!N3&_?Dv6O;v9hI>_p3IVxtN*b4OGhFYvd zi}IcTqs836At-_IZxt$)r52%Rn5ncHEuAWbp>AZ*YfxakTC7C|eN`Hcw#7;j$eP@7 z9rC!S*m|@(Rk01ISOLW%kvXIHMsy*+vKm!}9#ZHvTZx`%B@vM+`qkr6ad(gBT#r7ip(_Q<0sOc~%2HAv3 zvB->(Iu1R~mG&c-3eo{|j4?JouhdYVb`YH)4?BeZdh47YMyVqeJA$HE{T)SJsw#F2 zP4Q8G$I%d;=$$~zMylRP6htO{3jOBWJ&l@kubx3gxqr{1Dm=A0hsN0{mVhpCy_`ou z`4vk3n|B#YV-U}t)S97XnPBl-p#AWj^{mehTYuzD73dq zA0Ssofrn_=WYv3w)+Z|V7+LZiJVAAt4W6Q*UlmJ5S7@7tUY%CY&rsk1={ah~YT^ZI zqkrtv(P_r84Ai5Y&T1wa$NR@GQN&EOeT5Q7t3?(nLC)|R`SG2;L9YDP*IUE|Z2t~r zb(Y?vN`s^iDArT@h(5E^^$B$utk`E{^GeD_g9hm{zMx5F1)dV9}mq+>Bh;SChCK*gD( z>Z5H&iZwtXJTGX7%DbyYBQ&0|voYG;STRfVe3W8V=<#2v2|960vPNIYMHx1|7cf#c zL-%G%&CzYvbS=<}ZBk2QMGn#mHRF4+L8bmktNXS9qeIWB?=3wz@jLk;v6k@!{vn zw4JrV7?gHT@k6k15hPG^D0V$D_70bfgo|Kn*hX6VX(%ph>98OT{Lm z*IbjnsBe%;r=ZYniuvW$<4pS_+h}PjTIr~I0mzsuaT>BCw+KW&1EuMxQ?gpjKsl^{ zW}>|_q##t4^EL}b(DQ5*%((F%^5wgqgFekyY%aRfSFw30i;-(Sdd_IJ0FA3EEkyT@ zsB{t9z?i)lwSA=0CFpQhX(`&t{ksf#v4UKVoEgnlAS3pcR-%)PIl-uWh7^Kg=BwT+ zbSPH}MJayz##f`l4^%G<9b?yE4Vq*jtwsB|L&MRJB5E6f`tX!_9s0+9-Fh_ViApyh zE5?IJ23JBMt@n-WmfIJG#B?(wEfBHFWFx_}a{ z=+iEukL(I1p-N7Ds~Hf*d^UYA&Jr*^wwRvi-I@k=rPtlX!>Nyo{WS&k#$GBIYq3R12dydk2s^=FdlO57@^pu|?1GOa2 z$wUXa>R#r_PrbZCFUe@LQ2%#|y+-@F+TWlT{S|wQKEG7kcW4j0*zeIDW~&bby?i=l-c_R2Hb3%PAQeDk_%;fn zMy*t@5V}n6V}Q<)TNKU{cT^E{H=k4#4eh4SFhnc3){3F;U8Lfu9$9V)G@1LTB(gm% zl|o}SNk%9lR4R=wkj<4rMxP~PG?KGW79C<&qZ}&2UPgH|gJZ6MdgSO>Oi&hCK}EE> znqrmE0?vXd>d1PlGCJ2m{Z&D4+o-fEYQR`r4Xr7y((0%Z8D0%^fDyeWT2B643$-mL z)kZ;~QXS;EMJ?*0LR_cy&?LrPGh}d4rRFH{jAViCN9joGqu{HGH9%dKOAS$aOQ{hW z)LNg>7=0jXu|$RWjYKPyFivWMHn78Djm&-2qA9v)CpANFo2#@ravG^v3)F*EQA>1n zl47mUNp@0gP=S`kY=nAXU z&S)L?v@LR5Aay}kZ|HNoqIu60vqKrp73+phl3jO4!FQw{$jVl-M@F3Up2%RlV!hB< z2es{u{*;m&P%=NcBTDDq?}Mtb+U|?CuwUYY9#vP&87<-7azU>jspo!ZGtWBuqoT+3 zxvpq#EyV^PU&ic#==EE*7=%96mIk94h4mS3Xz)kHhM*xP(op2Z-7^fe9HDyd$eh*P za8z!oKFtF;=T|AefU0M$ij6?+nP>Qq>%CiZ-Fuovrw2R#+A9Qt=V&hO`FKIl=nXXrj9hv=nQOmr)0fX+C zsMHTN=KJ$UwnNo+Dst!Dh5%G}o?_Ebuj^7ES{9_AayqJBRP|<{y`80*$jVRs1)*AT zYB3A7asXg%1o0I(2#~IJ&$fbS1b`FwNif<&;-^@7g6~Hl_sGc zWDl26hll#vE~B-Ke^=0Vp08d-P1p;+h7K@mB%_|qq!bjzwQ(JNBLlsG#*vTTL~s4o z-!1gVP`%tnsq8V{L3cQUyJ#^p(>?S$UA^2#bE6b{fbv;O57D1x(j)YdEc`Lr!uuOf z&`9#Ir|65NVyS2bN1ukQ`>E$=$ddKZbF?#7dVx-!SKD+nkLx}I4J$8YqAA-|`V#$P z)_sL`^pUdAm=e-!)T5&G2E}ntzeOHi(mT|ccR${vt-LM%0R?lfenf|IRqqpOHde9E zXg?!sHk!!Q`2{_xEajlO6IJ>Zb#+zj8`@X+e};Oe%zSY?TbqB)-4G zXv{9D2nu4PE{Y7j^%;i9wwGeX(9eldag@U@L<#hkyQd^_AEQ_)6uwqWtMnIrM}XyF5zG)KOJHQwpin1X*-dtRkBGK&pg3@^?#2k=+@^ zDx-e9!&wDQd#|=tk>dxIRzqFb->8lbzf!CQieQ$kiMkI`i(2Tdonp1omS?J02lZh$ zsxG=bSM}j=tFUpc1Q0|s+S(<$WO^0jiX*qRF_e{7YZR;?~T03f*jB~ z)-#T%Y7?ms>S8AKMb>{+&k5D{S6gSaDp@fXWW$>){ZQN9YSAAhFl)G?uYDC8fJSjt z15x*BDjkFlY*TD7`nFOrHr+OZW?!~Een4~x2rt@vN6OHpybT~S&K=MF$ zE=itf7iVq+3Ot||Bhjre_2`9M|4O4!V^&wA(WaKt7<9y9RZI-B)+2|Kfcm6{I zC#ZA|N@oV1izXCPFY}O_n@Z=SA>>*M(6X0myATC%bu2>8o212P;$3M8O8%-AOHmnS zxMe73nPSUPN#?&5=pDJyO4Q(r+6JR8%+DdHYd6JKp^?#2C<-CZSdF44DHevlI7(~K zughw?7A35g!qI+4*$9+1U0R1mkR`20!y8E(&}>GXNYsH<;zne~p3)}d5U6@lD2bhw z%_!PMEw-Rm4l3P>&KgSF(4r^OcGQ`%KN?vuukApsDy!$6$h4e#*@cpL_P86pXTI8l zvdP%?qT3&&eaPXX>cyZori#TP4|cxekSDAA{b=uE#SWk%pZ_{C291T>Jf!+BJJY#M%$qIT@mB%xdEv|d7Yxt=eh^W<7r z(CM1eRrL3*bPd(xdPzp+jEX6!*EQ)n@?m%Q26ARLyNNb`*Js>9O*<=g8q(PgsdA%kI^#bh$qPEw)7MQ@|~ul0*-2% zhLY{o;u&he&+#0^Gorpgr#QdqD4hH&1AR!9GSOb{kC$jC-_R?RZ?alsp{I)!dyV=H zl-{7BTpMpu1ZV3Vn$<+#^LupUvSJ_5I^Ns(h^p*Ui%)2NbJhEdS}#>B8##HZ-j}?3 z+?P2hiqYaL`p7K*4Xy93*mtyx@9GDt&3OM4RXV78zfgB}LVlxS6{J6?L^FLxE~@`t zvA^g^TOG?kwCT2b$)^F?J0M=lk8YE@6+o6FrGm(Op-KxOzeDQ90Htx26h{8!`bCg~ ztyB~}V;yaXE;5T2LvOCCv^cuJwN?T}ypc+x0m16I6!My&7Dnhf<6mi1g89A-s#Z(& zjL}}kp|Yqjd-UZ{rM;?G9`#`jQ~}NBCpSUO8Sg8iYCigmN+`IsT9~2^y%ejAw()ea z3i4$XsETI%r+U>;x|38Ld6tlBpv!ziHPL=@lv*f?vAs6x$Ir_j1oGa<6;>BHbEfN| zGT&6s4BcRLV2sX#iuC7LtSsLxoXiIxd$uO0v$3?e=X5a#+O!TItyjbg^D zMH}S<ZaPkrlKQkZoR!b#E7BS5*CV zMcZfVSnN<5-&!|xgZ`IH#Q6fvh(AP;$BI^(dPP+2fD#N9qE?$A7kys43|E0?7}3XHU~VuO92Hsc2$dwGBY) zJ4w@!+b$^(4G58@qiTuL3=}d?nu+*t66}LeOeKBBEHrYedY+B`@IPw&hZ?ZwH3uc{ zP>Z?f#cpXH%I5seN9Q<~3sC#riY-LOV-;J3LL(GgjFL(#wglB>b-EPwB`;ov#`jab z<){MR_zEuM!R=F9}6+e@Sn^wdBtR-uP{yP+tXD|BGRVw#BEwZWAG^@enrgcnMZZ<)p1gW|<9pF4 z4{0B|&)JVbX$ev+IyqFm#G&N!I+p!t-Wru2K;`)<)R6FP+S*S6n)U29Z;rMnAba&!8`5)yrA*@U?Uf z&1TF_KvB=7^XPe&l!$Krk}japJaN2;_BB+0NhpW0=@Rn2uGnSNmHhq+y4p;-itezc zzlMI$A{iyVP%H(xWlGmk%lj(5fno+qH_=aexrH*K6}yf4Gd|xzD`FM9i#iUF?jgVW zYH=S$a`qpf-+B2Ts?HOiM<|Y*`Y|#Im7bt)*QKW@nh_)wjbT4N4Ry2D`F(~WQ&jpK zjb%sY1sZf(ZPU>zV<`g_WA4dBMOb0HMCt4syh1M7s+Waq&ZxiF$lF!@y+L)ytMo1U z&{d`HQ0ec|dsLh=^8xi?t@{yWRF^&>k7FwRjCcXkJ{#?SEPX-M7}s);5o^D%=p9$n zH)O$;_#IVjEd4;ytE8WZUxc#%h4=&Q_PRnG`jCI>E!X53M%46^2|8lx#>(q++c_Dy-M!TT92vRxO&MI9fDA zVa`%>vItJ^t%x?`lqpwL-lwsTUiRLY~+f?PR^x2DM30tSt&@FSSG4hN_qL zD2UPy=rC7jN3`pq)Cu`8A9Y4mo9Z)cQN{dnSDqLRbh73}r?#QQ$ zKCK7xXO(4-8gp0lM4!2%dZF=;Rj)THK1eYKWW}}Sh`g>!eNeqLsV}M?t`<(Hz$wL? zQB8KQU67Nbj=3M2GfbuZ(eV$GD_VF-8i4L{1_z=8Z>2%Vnm4)zBP!dwp;;Fd8-kAU zgkdO(TBOops0Y`$I||$>4M!&pRnG%0TcwyM+Qj@e0u8iN+mR^xoaBWXPEfs3D1@tS zG^)>aKL&aCRLmP$?pM!aQH-r(K4{n{^)e1Mo-K_>-&i9~K&Q;5iD=Xul}f@j)u*jM!R!vMM6t|F!6;*$dI>=V zOm!@)kPW$VC^|r{yc(tQ{67pmVwPNkJT|KBTGTDSJ}n$QU~Gy&mP1r;9cs_qvmP}i z*V};Jl37L~6Xwf}$eb&C6LMs~I12q~q|(jE#X(1~1)VCWdRvh_tL<&bI!Z0Jqi{xs zX!MCJV+R_{U9l4xgsXHHs>BZDZd8$RV-IS`j@(`}nd@{PdTF527&LH@VzFof&k*8J z2rIe$D25U90J7veh(}GI>6j0qGTfnu&~Zu+qhqXzkD&NkDm{u8K2z)%ir%c)aTGCH zI)QF*wVy8Q@5AV#x96v&ym zfXXt%UPSXYDwc$NJE`YO=+zOmy^NfA6YmN-zd-e_qM7s5_8OXdRIy}Kewf;(pliG# zb{&mvqS70v#yz#TiN27%-a;+tg zsM1Z8Np< zN;A-mYAVe{`N`#9BI8yneU&GE@+{Qiib`Lj7yVTF29@J#dW+UOsq`KCz@7IVHRjF# z4`@=XNctpEFk_cR9mw#?p_lBYlt&hf8x@c_yZa{S zJ-?w+5mo-G7M0NC*^()0dt9oFJp9y46_m(%tBR6>6sv|ZiB(4@nP+Ms-)Qw*6E&}+ zdbQAnKdM(7`LQ;rgPLwoXPD9Pu9x*jpewL#aM0&KS`EC2_?z zM7<5vOCvOzo$|)0?nlWI9WS7IR;WH#T@zI2m5$UJ9rjSHDKg{vTQg*IOD&qC$?w%m z3sjc*qa||Z4sC@hu%5O-`8F!n8U<&lUK`}az10>a2TJWw#hvQ8JzB9+u@1p~ptjU^MKqO5M=6cG3`3w7vQpijx0H!%z?A zZg*tTLEqJI)Q9(7Jy54tYU_#qG0%)Z2SzD25*6ky^Fq^@qeh|P*HmvbDo^Gy2E{R_ zc%$0fjbl;eafV$w zXW9=LFV(U5BmYB+O+`n@{sYj|=F&7YkntrDnQ&CoQE%py8K~t%X(kHWt$IP|CcVr; z>5MtE(S|B2{STRRl;)r%*K~YyQ9OChJd`j`E#{+zjIj&Q$BHUlh)kI;7oltHXD>#E zT@+h_UgndQqFLV3Mx0|#E73I0cTC|G2jBphDQl$|nnYR+wp}}?3-+JW8oworsVvQ4tDq5*@ zBPz>1vk8Tysx%4(v2(H+S#?ru3vwmv+loASBDM{EWiMzus>M7Vjb?i&wgcr~FYQF` ztXOuTp;OfJZe+txv~|0qStlJrv&dBrqY`BBN6^9+>hCDJ#+u|98f>W8ab(y_^-iE^1yp(xjrk{? zLKz*T(`Y66{TUR%9Df#(mf4>}KHn8fK;`-sWMRYY=XDbPH zBgf=N^&ZK6ei=>mRNE`4ytP_fMI(HrYv@wC>LnxVE>a3wJyW`ld=sS`Xd(H~O_ai{ zb_*>d_r8sMkE`AtRGLxcF7o62-a}QGCGVrNHC6fmjUOOAL?z4%2FDNJs>?phq!y5qjjUy-wV{UkYeem=u#;oPdvlOM1AW^FHwa6 zmA*p5IQlHqmTUYqIz)c|1}$_@>@B+RL3)Sm^YTA*j%)1$y2rllM>LK+;uET6C4EL0 zrs`~EquA=I_XW9bm2!}ik@OXXv{$`vD4VQ6QOC0aPtZv4Uv4qhf`SQFrxcfYvZd z6-M>5bfiU4cgEPFXvs;*5WOJBEQXp_l8U1+b`eV;v(k!{L9rYL-&)C|>S)@_dZj8Uuw3X4^&B{~x&wL(vr<84q9 zS#xXDB~~rkphz;twkU%cu^pO}Ewx9(C#h`*RD!XyBN~^Y(oQIwe62IeS6VS!WJilG zsALtXE9&g5Qakj6v(-(~8*z4J741&+SYP$i16Asza(lFuoVzEoc%pi}&{yu!-YD?5 z>Ny}Acf}mhD!$7;sQ4Ad`l3FUBq!9JcWIsTv{IkufFeS=i` zAIi`CJO}kmQfzKsX&Kd8rLY(HQ3YVDyo^Dg^nymR6xBjBKH3={xnZ8Xa;}EDYrf zSG_f;T3wZ{MXmcw;iyS-l}4bn2huv^w@F%$%!WuCP}h>`FA^oJR%|0G(@@%kjE1T- z3gt^vY%}_FNI&luH0Has72P0%-iDqxQoZfyDbN3-QLSjjb|5PQ#dabtNBdpq2v_26 zWKLGI2Muo~?M2qr)M6iU>=7YCvPVWX zA&E+M*@`c8KK%w7*-<5Kq8q`A-9l&GrQ0ZAfv#U7 z%Ex!!?x2WSswD~4;X7M*Q71;Jd#Ey>@;(~fOZgt4MT`s&(H$?v9-;3ArN?L}bKm6L zn5$w>&?I}+{1nZn2YH5S9#OvM$iOF0L9e?g-wU*vUil?DK!5)V^bLB) zDk2pH^4*`eXxbIU(oiZhn0F{IJ@9)}bfJ`v3Jq3j2FgQynaGM>J_|kIXdh6~&5C8C zY73-~Xk=CC6WV%P$Nh}vcu8MShuk;7=yqP^`-ZG(bFts51M~N`ir7nmHH2jVwRLg7uN8XRU-dUgTa+~0Y3+7h*>A)M^l2O z0?2NeR1jIP4^ar2F_SHfcJX`^LHtM6_C?WL`c5OXd#7T>kc+Woj0W-6rZ_6fw>3(j zCZiQIK~v8tUrAKgRjH*=7_))Wx%t=wDue3XQNFUMDQl&2=%Ke_<&hmdYXwx5Sx80H zW|dS48SPdrrf4hexiVVAw@#{{Zq#Rnc5~IL=8EyH8Y-fTXkQ)WVcu+xOq(dR26A9N z$5%BC_U|MMbZN3m)ItsHq}s^zmQ)8l;D2x7zqK-)+M`%q^slq(vqIJU6|0AuewXT_ zUEHGv=t)tjAsT#6YJ@&8Ry0QEt4U2zeV(4Cs2MG%8G6rt3jf8bp#$y88kP7VwLs&z zlKkwTVIwP$R%nB*Qd^_z?IatNoi4RO#~3x*qKb@1?ND7`rM5?L>~wWNW{*{0N949w z>V)pyR=&2W1uT?U@p)NZQ_b|M;jRT?a&O~67)b_gOtx6J>$Oh zLd!Q0LZ(~q<#_6$W@oA-cqHxwg2Go1C zQpcgl=F)g{g89${^pFx0QEl$(Bs7g3lga2;9cc>kr^QZ1Z+IHLP~vo@PD4wX4^2lY ztku0y1ikVMWLrrkW};$U6`O^OJf+#_$OB!!IcUow#e8y8TPZddIdQFg(agL`ore~( zQ!^j6`z0+v^XLWqkRxNyLgc+gu|?<;e~Ggg&AqSK66F3&v8Bk|pqM{$Y%MKAHk|!( z6v1j}1sXm~3P9;=l)4ff&5;6;1*?fws4(;P)#yCE=o*wwU$PcO{nT;Sp?b`{*P|hm zl)3@E=Cf@?6ZrPgCbWrO>Ob^ktWtwejFl9O!WpMS(3d#Xycx|*Q)~V4F?wPFvD=~(F@ivA@%LQB|1d5qlXcazaN-d80F zrNk@s51Q*P{YADNrGMy5vhwB8vdS=$zirBkjx(#uhg!2&kRLta+800`kCa*vxipdr zAx9VGD~xItRK6l;+$qJ1qCpFk&j{T*AQeL=c{^*2Qu+Q}arAPnN|Zn@j}{-xg>XbCs58M`@+DLe~o^ z)*3ZronnJh>2unk$*dRJqU!W|?U4Hf)z==`4OH0eDORqI_JxuBdH&#k!$>jFR2a(}|KD@?%f92b$JiCG1gwemX`^RGwA214{0ze7(>D z*08-%x{*>HQCs?ACv=~0gE=FAp5#8rdXDnBAcLD?eNnMOiuFTR7EArn5q1#=pagbZ z2BO%5(jasV4Mv?JBv<6INpeGdYwG-lAV;3ip=dp;wqa=R3#AT6+Z!o10`0h|82^Qp z!IhqC6naW~aYuCzv&aIVz~RF|>= zXm;-W4~-bEvVo|=acLF$_e)xh!X8U&kav`7UW;5PyAD0CEv-k%obv{Bgt2EMiem<~ z2^GsxE&rkE+@l~Ab6yHYJ%>mk=#-VT8LeYhx&_sks@PW4>!i+L8*-$+?WhzjaR;)b zr`d^C_$YN3a%FVhjTZ85Y7gQ+kF(#4p8QsQ`%o>$sQqZrU!@*E6?aPq(PvT*<>pIJ z>@bR1B^^O?3ra^(ET8BYa$!U~j;cAR>U8^x}m(zKzgXp6BFi}LnU*=wjV`v-C8#(c%DqmnU- z#iQ}tbhHH2lJ_4s&^gBBo4NU%rCX@pF_pcIu2hr~k<|*7xPyMrk&=)P?fx!$(@kaX zq5VA+yN}}OcORe?tf(HMX7odkPdv^cpQGu6%D$9(K=Dk*l3j-=YuCl$wSDzbf_)&7+OK zM_XR1=5&;AzG4}uEc+3e$f1eKW}y;6(g*Z$yi&8#np28>M29)rClt+U;xlSJTCp$4 zn%?#+`jxKOH#Dlh^c}5E(i!|fmU&e6CkpGM)Eu<5p<=(#Q05@N(KGfe|DfJ3s`)P( z-%YW9$dfT8kA_r(V^78MB7Rcao?+JD!PU)=ZZLinK#S;e3Znfr6f1-t()$!fy-(}> zil7K5sVF+oPN_!d3@xk}VmWMYj55Y3Rvc9>saOeQHc~P{#~Vl`(ITGiQs@kOTBXq- z?p7JJml3Qi+BjILZk(O)Ew3CEY(1TQdM6~RF~PX1$xf;)j|<@Rkk+z zGf}ZRD3dveC5m=ZYF)Ibh-8I|9#y`2Xe3WreRPWZ)&RwrD_=u2x~EbbA#eJe#wbs` z)C8SvsC-RP1kX`3^d?iW<|wU|%37ls=5;O5M@Ok8I?i=zh5VQ?wnjOOoHi(sJ)Slw zgKwR*MQ?Z(+M&2ws--=0zpGdWRD~6DN7RSDt`mCC-Rg|~&|h^yvuVY)D3nj$6}|LQ z*=}g~L8W#_jY}%k4rOt)9>}J)WRD)u)_Nj-+RNSndGOt&UdW&J+#5A>RLl{jv(M^; z+D}o;8Ew6#JXHOhN6PhJPh@|t$Zv(43`=AN1(~W6&s1-nURe`|8DMYR-2I zCZQ{=2qvRsgJM%qEc*vjQLm>uh8HrUFP?_RbdaW_JqgO^jXJa1o`L*pOEXa=R>!l@ zar*YzD58Wk2N`h}d{D0^I_J5l?F7YqQ3`YUdFV7H=A)b2RNn%0eUM^)$cJ{d5Lq!# zT!g;R`z%J^7$ujWeEC&&DT@B1RDU$;y0i>s=Tqu(w6(uVtU$@M>;QD@i&9sjwe$jk zD0GIj3N`p7twz;Mm2VBQsH$4lBD)-=u0!*7Ds?@oGDX^ea@arJh{`c)Y(i0KO8pPn za{YqP`7qTIjIPi-hM)jDmEDYbH<7lWyS!1{iX503Z9_X**KS8Yc-yxFjiC+gL>E{k z>_Qv4m%CA?&C(vU*iC1(7hTjp_WRJtJ*s6t@=lQsAXEC&gUF?TbO^2IS{+71Qvb@(iuM(!_FA{;eZ zDn%eq{?7CaI@4A8&Y~-v)j2fLSUQi&vR;Tpb?9R+pt$QQ8-+}GDx%RUo;NOp!LgZ2 zTtdrueq+$fJ&IjMOyljZpfqDvc;?-APMq}0b~dz50y$S+WOf(|At^(jhYb^Hu<+^5v%=vN2DQc%f< zioHNb8Y=b@y{0F8g$mi~xUUgk3$TBKnzNcnMdO<*^)0GpuUHzozFzs>p+d3xZ10f+ zJxDtG%UNZhEfFe_iGuGbmW3?qtG*A&f^}myvSW?&5%GH2{u8;dZi=DgLXt6hdq8E2BSWI{l|aAE6*EB}SVfmaL(40*6v|*UEsef)RjdpO ziB$>yYf?ks(h~n6pkXNANiL7P`$`p1qmoiZwBnUiDL3C#l`utL$17GDdGJ=c3X0K?=)^v$ z4yyH9`7F^6XQ?g<`XE`Ma*SK`P?hN_Q6J^JlNz8%Rs;>v@lc&XBT3(gi=U?S#zbE% zRI~~D&6C~~onpLdhFFl;H%Bv1>3G&CYKls}`|hw3$w`lBR&r4B&-KI<3*(Ns&t2BFXF zm<&d1IxE!``S>c;4Sl>S4at>*Qiq~TbEILY#}8eD;plt`@Yu3H<&}-gU%twuiD&GRMkXGl1{_yT> zAv#5`xCrqld-jWw13m8&beq4WT8c*VdHqp`!qPJI#zG~QqpW<=3N#~F3P5)Cly4;( zmZkav(Ind1Dim}{TAeFPrLIA}PD*Rh$7U+K4w*+QwjQ1SPuhTdHcJ~(@NQ`nO86oD zhxn?!eGp2e2Mk6Tm6RHS4)gqOM(w&Qwgq`DQ*0|5&_vpXjOt3;(G+^N9jNhpmDq_c z_f%{bvIDqSzr6R8~5S%5tra zpxZXmQS_5%@EF=NUOJ8*hAZ_1YPM1eMc%? zM@E_m6vTLS24%fh>@0dyRXT^l_AB)~T60RZM52;BwHHw2FXf9uFIy`XjYhL(zKGs` zR_Y~WS5S&UrhF^)a&EpH#jc>pB8pu_-zq8=iw<6vuAx=8r8v}hg^qC@1+haOk3Q6v z63`At^cyIP+2~E=#Fe~-Zm}}EjgqFTmPAy*RjGH-R_=Kc>cqE{?xH1URP#OLM$5U6 zOxe$SfQIK$iH9iMS$c%R_}<@Rw70gDj2zildxDzKb3H{BSQ|b=!{|Ytqq=RS6jXWlOh zb>63HuS!2r-X1ze4w{*+62DL?W591z@}2Ytjd>vbMUQBI|8i4X z>a6tG>6+5k@}hsIqY+01KnL)KUbssUj6cqpnIu zsK6qr7~0HpZj53Fscdodu#aLT&};VNP0&eNc1cvCfnuf5eOhd3#Mg}N%b+dWq_W7b zi1L*~#STm5QQ#-30(!}+xFV`Uk6sDwgP$KL1TBsT0R&8{Uv#*0boYk3HqVGH@by44c zk`+449ju4emQlX?s5ZZ_(*Vt4AEzP8_LCZ+3x8CiG0LAJH9@_CrKYHrx6}-!_^3p4 z^dWcthhiowwFTOGO=^keebjMVp;xRL2?yXmm+^wzlXhZ~oe$eN9!O zJ&IVXd>xQ2d)6J%PoCdSXfy4qGs^c>`MRKc#T2te<4u&WD>7#;&<(X>#o8T}WIx3Y z{o{M+JT*3%{jA`@EsAXFz=B?hCtsgf%?#5nDSl4&JF z&=c0jLs8^Zl^urMzDvWAjfFG<6=R)065VAcJqi`KS1s$e-2P1oVcdY$94YL7If7u_~F2ey|dqg61>A zPDLG!mFk5yu#-Lw6+5id>1YLe(cWm&dc|g-nv4}QQ3k7tS*RcRW}`W*N#-CIX68Pq z7-uyXIns)KQQt^u9-3HCsq;~5-s>+wZ`Ug3hb)t&g(!*^y9n8HXBMMIkEA7Nw5_xh zS@S!M{%GzFl~{&makS;=9V^ilD5Z&F0Vsh!aU~kgT?jtT*vX@Ak(A`BU`yc9iPc;XjQdaup!Dv{hQbW+4 zHqvHPgqiskG?uriTTxo9Qnw*@TIY6T$|`F|uF6U~kuT%rF7)oXV!Kh`0F~H-rdL;N zFZvKK?L#|hr~8rFD#Z?kHwI)rA>>m5doO?56u(BpS1aTGDNvOk6*cz1Ce zyuc{G!;ED{ZVE?q$7SsO$ln*oYNqe++bi7ujY^!JyLRe%(On()2T%jnW- z#jcET1Nml1H&L%)I@&Gt ziaz2ta-pA0M0*}ecaRq&NfK%}Pr8e?he-EOch-pa(Tvur?*WP(r`SW}I6?Uyp>*C? zJw}bQ6iY^3*z0(Ljmg;JcH@kjg81ISUv#Oy^bc7ZD>ctJ>DW}o@}lr;#qyzb{!)Hq zaa^ed(7mBjL1Ysm6+%VWttgDFm`N8wHTboVqG&x=$Otv&*(!#zYbc*FdgrECag@k0 zN}!XB(#E-2Sp43ok85F?tRu)w;Q!V8X8}Rn!Q4d;E1+;;c zO-1zhm-1CYp6mgbqRNb0mC>!Y%2x%gd8lKUp^voes%Sm;tr`mHtyp!GF;Fr`UOiPy z4K$rAUK7R7kt|RPdgWT^f~jh$jh^!S)TkR3@_&CXwA`M`VDI|znk*4 zK(3plmgwwusTC^kt$eM~Y1+6A3UHFzpib4KwrDmhw05W)&rEyNY>HAlpyI4+JEBpv z>`tgA_p&ouAEa0ptbT4MyIqfBC~cL$sx0ZpgZaN(@1(_)F)Z$fBC^4MQfMQ)1}e4-U7(NHji#7Ldr&xkv9TBR;i=e%nlUrlk9sru z9YCqps^uVxWTZQUl9~A)MwXLR%MsMmRwa(2My!sHp$qgS$B{Yn*b}H6^V3kY`i=6P zM8UVEQ|Nj{l?X$VD(JYU(NmuD@LVxgM4%GPGR~kF_6g6T3})-+kZld6o<|e7l94Dl zK)Qeyu9c#Y9lc{TYCwG#QAQobE}`Zbip8LLCv<+7Q3_AM6%^V)x{6v+HWqDQ5B?fD zNE?bn=eJ1LQH_I2jYl{6u6qK?-$=TFrd3zIo2VbZ#&HWBWrlnkS)WyEBDxr&Pk9F| z=Py{3P}|8$y^DI7N%xS)F&*tbIz)?jfJ)3#iHFFlz4ARmX_S48CiRk%QG3>nPf%$_ zp{J->6{S8yoqH?wIl9FzP6`^t82NJ`F7bmbaa4X?@{!1#nREiY)P9swv(VTS=>xjTJR%#-<;nYq*3tui zLivv=_8A@Esr`aFomJVds0(w8Zzz`8`gfEtO|c)yhq>8L)U&yigJyV2zfkZu={Nc_ zLf7RFnrNxmU-Wdb^bd6|Cgm9~dDfNkqVu11e)*6Ydje0a=Kzg(C_y;=b~snJ3B@wJ+ETL&>8qY$J4z zo}n=cwN|VNYJFL1ibfdgT$-T`GnB76a_uZxBWL>d7RZxhv_zG8@>-#EdY{&4N=?ZI z`O|l{LHXGSZi}|Cv%@0EP-CNF?NL`gM+fx8N+mj?y90FgozS$eQfIXMrt)<`BY&zE zTV%#LcSU<^Db@{5&Q!kcs0*#h4h57`tOqhVp!)2QExmkCw2wKQ19E7nSTD4M@7482 z)%h(LM-)!)*+sDPv#5boP>^o7~~2=u$YG!nJhrPNWV z#XZR#eP%W{8qKv=J`c2q^BaTS4pqLfs3j|FPvkpCF$40UM<0hm8|wVVqxhvtoq(p< zsl-GyX1Fv7on~)+GRj9Qo`RaMS1nUf(UppMp~4<2F%3meQR;Lwf;R4rQadO%11;j$ zXlA14T<2NHl4~#*k_>28#Kj=e*0BhsLc|>U^{|La_xXBvdg! z^n-V<3(-7wu@|A5e2&G)h#k@;sMB}FmLe1Gkw3EhqS!LDs;^?p(a+p(0HOw7iUpvr z+~1XGZCk|xk<%0%Z5487ziu@O;hwKSEj#FQtVM;ND|H>pG*{|+w6ciGZa_PEm%kBR zY@~dfQ1!;j_aDlnY!F(*NEeK@y^=zZ=Q(LJI>HFC1tl>P+=}k=&UzcNqu1Mxy0D+P z11+R4-ieCvr0haw4W->EhtIYLHDWZ~o2vlTvJaWemG-0d*Q5hz9qY1#=qPK%L#WC) z=`c#8?>vIco~pj1Xg2G&V<UtZTRMS8FcS<#$u(5-Ni=<+Vy94vjVc?4Ea~e` zBP(_r!_j?af)VH_tAsOX4f)O@(*UKOL$B$t&ZBAxibbNq>Cy!>FGHzODC(^gjha#7 zBDyqD^<6@vcrIhme4gaX$c$Ee1v$T$uA(Q5F0ts6qjU|ux+uk=?iZx%s7II-kL-@< zXbET%ea;OOxL>I^Q5SpZ7MjOMcN@i@QY;a@XP$irjpo@(LKlOT?=Bifi@1kAGe^IV z)^N`sAV;3nhv;NA#U7z{%N2W!Vk#(>j4bczte&8sXO;RC)oHBQGvvNqM|+M^ZIzmW zYEj|^`su9LOH_$j-z#*5R{R>}=_I{Dc8pA^Xa%##w`j~@rKX{ZjAif8NuJvG=r!xN zbmTTvu?$q{yh>!Eao?1hg}%~GKcKnXg={o{(cmKrZK<-K&~)bLpV2MmS6|RBuKib3 zl6LS71@bocJ1RrXKhS`K(oeMFgp`APs!6|)=OXDh%3(J02OVJK{EPf( zh;di*qGCL?`Ou?$%9kHSbydCsXvs6FAS%EWDujvzDpnZ1VXamKRehpZQRMVcGD5~% zq++Nid&9=)W2{sht$QeyKryr-6I6ijT9wQdZ;?x(!Q&Mxjoz_?Rt9ybrm|&`C-_rs)epvNVU<10Ez#a#gN}$N3%pDe<@ZM z#jsAWLIK}&R`pQnVT#p9g_!F%KtAkIHAGA3s~e$pj4zE*KK2Njppa#XHAP0riZw&4 z>7AORFlMOMDAb_T7HC?K)Dl&^u6(UfWz-s#MmDGoGu}3+DYH?&bZ@Ziuhe#^AboIq zWVS-;fQ&9n9ns!fQYW;O*-B?rG*jw=oKH%&DF1S)E2^I(bwgR~DRoCxSzFto(SA}7 zRF*ldJ*vQbt|yv7d*>^?h6<$iLIt^(y;0swiB}W`M`ry_Cc}r<9T9sFFMVT8UH&i%D8iK;v1s#gs zbA^T>r|PPCIBL3BsUwglZ&XI2PNSt!XbbZtcl6s?`9>piR*oKMD*Jw8P;Ewwv1r3j z$rFvLFB#AeKjj;TMzD)K9?h{<>I7uV-JggY9F#fzUK~B1dy+9;(w!sq>KscXa{EN3Y|Dn$b!YA~qE47ojw+-(u9>SXzSm(EgU9U)>~s z)SbPPWoSO%W?GJtdaJ|=bjL>uK(lGjE73Nd%RqE5Lf2&#I(S3*R-@6(R@R_%yOnP( zn&G6_I&_n@&3d$q=XV1t%baW@8dpOlHlfq>+W(>PpHw0U#Wz!GF#5?~2819B&T2Cn z!V|g$t>P|hMTh9Mx1pb_72A#q@ZMtws?$rcoyduPXcr2*qtx9f+MqMogZ8p!*^5pv z9_&NKyXg$}BiCDs9YBSd*&RezS)(07`NI`EjB2~;7)MashSE_qhWXMl6hV)E9L2K6 zIDsd6yu2|Z5KF=BF44=Z*V{l_zX1=%)H z>Q&^!-(<(4N2FduJ7%dw9BLV-)a$4meNH^O|5|5|fND*WZlKeQYB$kV<~O&{wL6O4 zMo+ooiO95pVt0@;v&ST~yrg1xQR*Yb?xD@)Rm*+UmcHZxI$cGvhp1zQVvo>X`jW@! zA8W7V+|)mcJwaz#(?3PiCM)$B8X6}(M@tyQl+o%va^vjNkt@nTea)my^rEzsg&NmYi4SNw z-*3xCJ2~f%$YZGV3Eg51{u!+;qu3YJhTYPyXnlfW-_SZf(RcKPJ+B{V%m>AOBAc5! z(;PJ3Q~HJaxk$fJG0xx*s^Oy&f6?QS`sDwRcO%8}Oq9ORW9CJ}X>0jV0<-1(XkR6z z7CrsUC2FH3ky0Jx&Wgbj70XoFy69Rfm9;{pX)pEA*Zfj_bd{NQ z1GJR>sv)XWSZahWGB!3wf9S`Xpjox0rl?z%j@t}{zEi9@TF3cWBYx7;z6Ba}SovC_ zy}Y4mg+?$3X^l#;YO+D^sw-a`h^9CdGQ7|2C@@d-Ri;QBPEy zr_2FOU=-?w_OZ(8jXWkO=7k~PlFh`|2qhajQ_CY&dD&~S-=pXyOs3|M1e#pg3 z>W{*VlsW*lV2@=W8W*70AQa;)4MrBML|suKR?lvzHGR_%l)-z;p{V>2#fG7HW>v#c z3S;94G@+?dN21QwijB%mwUXRXp596wjXu%edmu}ms4?io0Ucv3dhD*4C;C%DGN4EF z7UNJp{(5pe`b*6dP++oBC!#od(Mc$T=V&sT9IezTs1$DmrlOLA6!St2PD;~I%6w@$ zdiYiHMrm$3s~O0Z`!N&!;(L>`P#}8~vr#>E3+A9_d~%=M)P;)8MVFW{`XXCC93ZdAo}s; z$dPe+1**_Wu>f@7hqMy;b(aEBUJGdzim9xcSEKx_V%MPYtCYGHeVnG$b*Ld@)Oz%d zcE16YW{+h#_zuJLfic33@$p)qFLjO3^-6)VZ_j}N1=01B-U2AC{I>TPke$;e{Vh51d zQRyIhG*jnt2$eo69Y#q!Ge^)$#-pPsVwp-DLxH`d<7i$frJg|M8u;u((J1DGCy_;G z#ZIAtt95>1Xa_ylX>_%T6prqE)^Q`y<^n2v27PNRokb~?l}EcM5(@L^qw{LMRawHQZJ#^Z&e}&jk}}zE+fC!id{jCIw^J)*|b$G7Tw{x zTtnOF6XQ_5PKsSef452T$cVj@1hjjp^4&n*AEldUS!L-Ks`Nm*jlQzNNJMpyD|QEM zq5n%lFX)l(qH*%fWZorZBG*|ek%daNQ0xO5#(qRL+FDMr zkLV3^vrov9Yw#JpC@XzIE?mj4$b{MOH?)P8^BsLyE&V`Gm@WN8EoLZ|gA7Yl%P&-F zo?^d|_a4RmpvG+!`-?K!2l16bB=#16+08AC{xbV7g36uOwJM4}F@6}Kn){Vn3{~B(vc@Q1bH$3IMOliKKzWlCGeNaD zMoF}Pom47UtW8U!IDeI5&=mN0{D71%S717pE#VVms%s@?Z zW3-6MD3)ix3M$Vk+6;}LAFqlI(eqbB1!>RKkuT%9IpV*)w6B56adm5=Tb#26+EiGo zg}N3|EwzzxhExYRx+~QZJ>DwSMec4ohE;AV>xz2FBvU2oqr$@#Yk(Tl^EX6IYf6pK z7sj{7sPA}{Xo6hMOHI*r_Ntnp+FmNr9F5>it%GU`!vy(cb4?F=~&7o)IhZp6 zB8p{oJPA$hp|X=v8OEq7sDPa`6?GdZd7&ZnP1BI$In_5EmH4AG@J7qOD|H6C(_1yq zL;;Mtv(O<{6SGlC`pG%yay`X-(B3|Z%|(mo&3sWs-cZj&d+0&tqi+d1?gCV3zT}5I z*&$enjxwq(LWg)8xER%@pIn0aP~TGYj8&FDy3Q{FEJNM7Gs{sd&)W+0oLNBtIz}s5 ziB9KLY9MO2OR-gGwn4S5Mx&Z2bq%s_s?@b;22bNUl&_Jr9(`htv;jS0k7px#YOE5Q z&`egE|Dm!qRU!!eWGQS^d%KWxzurVhne&V3Y<~wH1e9S zyAY0EbA=+%$1X}egWfih&Y~#}NU~qOBs6`C^4&$}rYLp~ zRi31L_fb2(J@Wv4vQ+FL+ICy{9-$c%rN_uNT}noC7!95v7xuHCqGzlTpP_3PmHHgz zbWBz=tE^|TQTrh}myc*%rcytlt*l%>qtm05 z?+fZj|MwN8%vI_)6jWOJo*Ro$>JRj|l43tmX|78SYCl{0g+A4jej}?H(jSzSN5}Y! zjyb88f2bdKA&(v*!(6^IlNUKfDwYq;VjYzqP5vwuK$X6#Y(Z3rnhT+m&!oaAAY7?M z(26*zC~DtZsYYmcF`Yp%w2^t8F)G7;NpX~ip0EVk-$^n-WqEo^A_v|rmqK@oDYZ0u zNv~H1?J6#nMakJpEr-&08q1>syv?nE{(Gmhs)*)nQmhgRpRW?8XbJPC%ELf{#j5k>eN13x#D!yx=iZ*e*>+XBe5h(Jy-M8E7`|5oe;4?8MAMcUhm$Mp^V0 zb5LW}*ghzc`!*MSXI|%vYF}4<^U$!qDls3OaZzjmDp5-L{E#(wbs;K{q;|gut>s)6 zBX>8g@%(wGKs3m)4_OO;ut8n$tnrhziqNY(l$;{fAmJQw>5d3rfLg z1v}OusHdl5n^8yhH@2W|3siP1dO%OJ4cQNpwj+x|O5K5y4(eQXqRKZE+lB7aqwhw3 zXB69mJ`a}mqKnME_n|fim2W>f;w2qGp`TUXL6r7hu|sIw0qHP0`bIi}z9*}eqsY0c z&iNR6#J=Nkv~r2^oj~Q8eTAaNtW!>+AbQqQ=mu|4!_e@3ik(KYn5l*%Z}t=-kSVLD zGiYc7{#hMvi_j5k?74G#V(*4$x;;BK(7~#rf}SgD4V~fxr928P-+Z1 znju|ATNp#HpfGliuARQO37&T1?dT@&HDE#YHO}zJVPhBzt7QC*3&6yYE|WXf&Q{5_!6zN zRlZlKVwPgB(ZIZly+K)L6-!0?nHRrB?mWq9$gHdM4w)oM?@@cknRN8BvXp`5Gk45H zl^RM}D1jY<59lBLWHy@BMc3dXvShXW2?ei{KBLTOD)9wnFlYFRjen5_5qNVir|0I1Q&Yth#=Fz0xkpHK0 z=0z^$bd-F^hxsNyykzj8uP%V%2TBD|A9mdeq40gmR~VV>l8T`D^cO|Z%oQqOgdADr z6w6Irq?j=($~*1iDDjbEB~S>xy9p{xFHsV`=B-jGG(A?a(#VK!qL)F%rmAdNG%mkV z%b`u3r1Gd7&tnBt`=eA5&7tS5g#1{Io1!nSDp48b;Z1fGRPLry%}@?ce^peNF}oUS z&PuO3nh>m*Ir>FEUjseoT}VyTkABnwt=y?tEmY{V^3_It#!7Y2wEB`I+RhxHF4|F1 zF)LJrr=cEN!8h#cqa%E_2IyBKol8Sh^pjE>p{|TqjZx42Qj^?N_D-6j`Hb28L9U_0 zWR-1>me2yN(Or7&7HIVx#af~`7sXnkK8vN+$iYIgK^Dw2+MsMF)!Y`HETLFCWKFwk zj|S5sI-o)wq>gB_i%N7th3Nr1BbMa$U62p+5nI%9s8YM4klu=QLnUKWb9a>TP$le; z?Lw&sTDncC_NXWGxt_@Bu;hShACh{Z$IQ)pqxJqO>xiPqDAfrSy`h*h3VbZ}L1$7V z7ZlE{x-W{dRIDFr$(8JnCh%kqKufsi1Ci-(X%HH{M;eTVf0kU)IeWUiawfEszL=85P*55*=SyF_U+a?6&cpc34-sc0d6 zrWbPOIhuyfyqBgUpKU7Pjg0F_Gms@aVlz<{e`yvPYOU1SD7n4L&OukVNeWl3aP8I>(L12ksDA4TKh)Sh26eQsA8gO`7bxd(;bBR=2L1gs%r)XY2#h#%WJRi@|b5;i_s4FY}7wCE$=_RVhJ$i-eH&E;~%JNd| z4I0n2PtDEOT=l(0&wneHhJNwgns?|DW59dlK|hp^>M=*kK*jGXmWeiAQ@$)TiqG}| zZ9gJqqahPj;v>q#YU2}HG*|kJF0mf_g3`z66MaSd7$v`<*3AFEqwu-Q4qEXfwUfZ`75U%pcU3vVW1GqhkNi?qSN8N0TSR?k7ski$3r@y?p2(S0g{- zp|dZ5yxCVPh+ddWg-~&0r4~l(1EnJ9>K&;l`oKFtBXp#NVocQxv)v?PCl|%lis;@lC&+4E8>iA2l zh^`HnDxq@iB~w(EnMY-mx3gkZP!v7C8LGwJNmVp#gHo%ZP%9myI@~b6TjIY= zGF)d4QWH(TD_Nkk^nbO`Av>uyI!Mc@gF<&IW{K*2P^>Om%3EeDG?4ch_0U%CR(<3? zR3#c9Kjw)IktOTiMyT%}6neXJpLmrVFZNCD|g&1yWbkh8c1yRp$MY z1G4l{tQSfhr&w<^gneR1w4$fvgudKU&Cci~?*aOt#jO={K~vW0v-L$q#;Qa=lxVKh z{>a8kB?cg)IK>8{nr?kktU#22WcY8PhUIkipYREG<4TXM`rlXh4 z>b;TCD`^J$&YsOoWGJuLEL74+vDv69t$hxvY^<0Ma$_W(i*i^Q`l3^nbc}gu!b533 zs`*S>fV}B3{m?B7l~{;UVijA2>Tuk}=t`DKEJ2NXN=wm+vywkr%}jb(uJn)na#W2q z>lDCd>51{G(2W-TgD+gOLnB`I}1y2v?i zK*sDgZ$w8;m2VR|mZR8zs5bBCg3#d(&O|=|C*=3dQFdElbI)V~cs=lMBFSC|o$eqt|9M$z#>Iu||y@ya#^owFA(Q2O6 zQ)rl{Vqxf5W9c-icU-CAsO=lYBGAcE(it@PlTyzjOMVmO9NINd9C!w=qw4RZcyw{7@+F{Z87g}NZO*UMo2WA12D^pomzHj$ykn(A)ZR$>?jQ@E znIu%#Qo4&i6jHu>=qauJKH5(|`2Zabl^&wkw5CVMgZ=KusCiqRRWd3~-}D5{roN}B z(JAG7hDxlLo}(M=OQxW0w8p6rpp=11_LVYGi#}2oTGCY|KA`0Die;k}{B6@m)FxQR z{e(`gQtD@9GfVn{o|sBs(dJ&#H}r)$>vuGQIouDl{I2v9rSw<695k9<`4@_MpxAF@ z!f5{oJvyN?_>0Q%OI82S0q$EKFR35%_Pof2CodoR;-cf`M-{2B0J_sev4Y5xv9=KU zcv32iOc}e2AU{@FMNzX8Ix8bonmycN$lF)>j8P1`;l{tnxVGrHdjT5)AZS@q4Z3tI`Y1%RCDCVcvJ(`_^s5MD4u@90_{(dYN40b z%Ewpl4Bffsbx^+Pk|j!I_oyx!$zKp!p-Uc8J+vl|^3_M_^ym%HE5@>hX!i}N5whn= zX^dw7keVP9c21h2UaVc3p=JqEb5x>=WQ~f@vRk0)jCn0l1UojZkS)h;jr!8F+8|!A z*tbDJ^c!taZ|0)yP!hYz?a^WWDyai1GDYf$tY)ihC-lHx>Wo@7SBWmjiP?xPdeKO! zU6BLNU^mo0Na~K}bNB7g73MxY&^+GN*dq%Q#d@Mw3nT~R&l;>3^7Pd)dZPub_#Dxx zj!Jbx`Dpjfs1yBZA7ouuF&7j`&(#;T=NI4lArETqk2dk9WB?k_PqBf>m;PW7ieR=h z7>#B3!xb$|Q$9E3-$St>Xl8|8K_0NG!sSF zl4haT+0twjH(4d-po^@SeNZi)nYqZpSTSF8WWGwwL)P?(^O4&N#TKBy%(VPa2jKG@jK=lHZF96McuGmVn z&rh*H^qLWI6$*%uR-;9Hwl&C~Ggym)e=Btz%3@`>9__JFYy-N-*>6Or>7_OyS5{;H zp?35>L1-ei1fy9zM*MvCLKWj%sdVvW8OF&LNhk0mcyv! zCgnSVrm@aDih9z*j-g%b(;P=;f0XY8sDSgBpe^b{0+YQZ47uV&=Q&QTBV~i$rCKT|iYC-=ff>v$_V+XjE6l zE}{?gO_z`}`+6~m?P&YUs0sP5p!M9^n- zLry@?STEejjnR+aL`RmY#4VIgYr37A%J`dzPSZN?pxexHlTgeZ=`PC4Q*jTOGl#p6 z`nxFh0L^1}`XOrNsn{dbWrAXlQ5L&k$>@T&^aQOQE$4_i~OiyhGLdE^}?hA$cM955QTTuRtlkp35pd)OZm&EBIpZi z>qXJLV8x1|zKk=)(PZ+;638%2dn<{aKU2L@Xk35AN~1okca}k0_?3mS=sV9Ptx#jm zb2(&MSt^f)Y*MK;>dZ(|0rg?5sED$eOIAWroEID9PexlARbHZ)E$YR%Pz5zwt`)PZ%&~^HV|4#AjAC_A z4SmUmx~L49Z$0!PQ85Q(#c1z{`nOSOeYB&9w$cE7c&^fhX!&WW5$f7q^%^6q6;czl ziEr8or9?~4r~r403p!a&^_rp^d`Hbt;!f?OIeHePQdjh6iqry){iu3w$a9s{5+&tP zsXIDyU228AS?6z!K6^+Ws1JX)&<1U}rM7L6b5)&F1FFZ~JW=OpsU2!JS!$00BGtkR z734bTfE>%IZATQmPxU&X?%c`VXgirgXXH>o>VncjBp)>8q|_Ce%~XqSIrZvld)?70 z)>(U?_RK4KqNoV9=!Gn873+--EYT27UbevD#A1$P(9)Nhc z*f0?7?5q6_LZuHYHW(G5bO?IbQW}azkw*+esnw<7=)n|~8qvgR(g?J$ndFDuGNqBI z&>d+MDziZvjj9yZF^@qu4%*&Wbk?tO+!WLho+;;yz@2#Inm$GL@!w{nS}z5X}`0Pho4I4pkQ)~xo8j1 z%IBdz-=z7-oeW?BTK-G1h3H+pv-OVE1OECWy?W7JaQbV#Lv zXgPP;GITaYT8{FtcC!L~Vs&~YGG`rW6}r1XvDIkR2*rX>xT|7okONooTC|M)2BVQ} z6kCT}Pf6?1K>E`SsDEk2HX>_|c@uig{k9opzLd70M$B-xq73Fe+faY<#1J%qbH5$! zbCY(Uzg^X0CweweXJ{94n5Y)Jkrj8!9(2`9E%u`Q%N5&)E>Bn6P~>i|*nSkuli&kr zE;-0S^n|M^3?0mQ{);-~Qt4sj+*t}oi|D;0P^A~zawJ;G)gFcZTdjIWP(*hf=~48T z^{Zp(XD#VC>a#(mC(yh&wK$22GEa#{<*ij3gZA!H=_%Buy-H7`w&dey&_}-Mv#9+V z9m_fNoa;FjMHW=-Jo>vvu{boJd*K4=NS=KW*?Xw;67r0aE~92|bOiAzFTLoMoYM8u zRaAGdbPe5Q{JoAG8Ov^<5e20Ll;I%VMAdq0zqe5GO6fLg&)AcQ8nsuwB$U)ux`S3c zknSRzTGBl4^XtV^bke$R_P;TR!T>ojQlSv_88eRB0fP~jw|*Q&5csq zXDFT?%zhF;!L+wW-2W0hv1Ph6GRDC)0bKhQPq;Gd}V0k!yr5(5?cjXLps z_z$w?oBNAA_e=j!<$nmoC%5tydLqpFiW`W*al=7q1JZrE-E4YpepstHmS`cM%MHfP$#0sMZTh*cnDr>J6 zMbT4cNX5|b$x?B&(M2kOzA`qIM0fv_N}&|q?JAA7E>NrtdR9eSE{leF=(AZNpWLcf z4%xE~!9TWZyg_eljXF82Z3R@Fd$b~Q<@&6I=F?-@pkMD*uQJ-sI*BbB#Ixlp=m_hB zRnZCVi)zT7-ncsQqra_zB5F!@XfeOPV~;%P(`%x4H`TTlYEV(J|4#q*F zOBPZWEnXzmL&@}>bi~G>+L9yM$BJEjbo8P2+W?h1tI~!jo_Sy+RPnad7&+BfizdkG zzG6;jJnLZ2XcqaQ3-aadqo&A(tfm?I&3S2#zFk&ZSM;6t^je^6WH4@M4`X{v#E;1v z+|hy}s@DqbFRNH5R8UOUQl<$d~mp{y@f9giq8Co#WnWj}9M| zyihSdWd{^QHs28yqCe<_MsTFws5hUyGg=(0SQpfxuwp)F3-4ieMHw7HHvWL zs1`lYvz!bNopMvG7y3*V(i>HEl=`5z^cH``nI>drZxj6N>a zmZu=AEz(qE!?iXIB{8F(j&}3j&B6gxVXcwBrs?ly#r?^_|K@WNMvloqEeBOs@@}@#4a?e(5KRP~NI)IWHAr7J% z-clHfZ>|=HP;cHzIgC0pT7{#1o{B{vFV<2c(armRT|k@YpD&_1^gfr+L*CW7jCS-?EFKxT{;r^zch4HNq?fYrV)$OL^wN9a|)q1}ur-%)FxDrKR2 zu`10*gUGplptWnIpXhWEZRHpGNx$(M6)PeALEjk-{-XY5LI2S9Qc|u-(!Ww_Yl3Fe zZ{$XQLUjbDC?lU@d5}Fb3o|sB8DU;@!BsJHwAN8u$%pd$C}x2=j#It-D1)|^s64Bx z1<>3NDlLdYA1PJ{efp$WVU*NYu_CC$Z^eqD!aN%-hAekW#ZgUzR092Dza`Oo`X>Id zGGkDbVx*?RX+p3)MNQ*ni0GsZ<+{XEsp>bseuGsEa1;RIDEIC5v=Gj<0kCj%fH{mDWdA z{}gM0Hm;W%A}7{J8=;_M690Ixu|B;@6SVNEVooT5Uep;m_tN%U&;;JuZ;EoU?$->> zB{Of1ig8q~=n4He|BRQ>pA5ha&6=<6wM0eu9Pa2avy)b6m#JE`M$>0V9w?}-)CQeD zrM7L+l68t1&?Nd(Pjr$Tjvsw7PF<o$~-XyeUuQVCGdm&9hm+9-KqCBf~%+t_j86^h zRmk5?T8-+Jmx9nI-bq=59^6ukwaA&iI2gJ7RK0a5o_D|3qxXLl+kmP+Qj3kqX@s;1 zg$!5Q&8S{S#kQcbSEQ}TbdK6?L#<{j7J_=rQfxb_#rqCB&`)N^JCVzMmF_~D$)9(l zW{mcGkg=S$vKOV%-|s_LhbtC}%nPc;esr8~`T(lS@f}3<=t08JQgVSqXa(cKVRV8u z+;G&of)s%UFvdrsyYzoi$UIB2Bk0Cl#f~C7C&iATrhHq+(LJ)N6Q~~Vah*iYtRzLF zr+-y11{M9H(o<-`3B^vMVw|-zXyz5^EZWjb_0FLZT#2!$YXR-!JUaJ4u{adNw|@a` z@1YhKkt^BUCDiYsbQw)W@yLNU?5?2VWHMLLu_M~bHPk#nTe*&m-xRxndT~w@P$D_& zP2^3FbPL5W|G161($^)Tetf@4r~+fz9dxRrVt3JBo;}_}g-fZ$eUvs;^&TLX%Zfcj z9_i8}ROX0ElhFpU!^ddI2yNvFGApHePtjo3_n)B>^i9uE9!g)J2K0X~Q4fyq6$<5v zPYU|wt=MbSm)`LW+HWGIqGh%9dDGBO#=N)aB;UfjoLHiij;67?@E%QO{P=)6HdBj_ zD4Vm9fojoXenPd$xiXPyULC<_w3?OgFX%1b{#VpxoAeF+J|KNZ<$|=mEOe3HA{)gq z{{BFh8>rq-)Txj33k@P~|BX!O<^P~$du`<}iod4VKeVckwvubI6h#JVf|~M_G&jn_ z?A;V)wooh&iYTSFX6Rd(w#N^_7%Oa+%u(8QDIYq@b#H-k)ln=zYRgkJOVlu0r3FxB z7sU#q()8_xPzOfN!sr8MqX_b5UQrZXxi1w%Us<&(j!rUymB^{rOe%>+%u&5k$hCuF zrP0{7ij_ebTNEpcdhA!s3YF!GD2Lj+Naaxst8dn5|R&ZG*O0 zNNv%#^C~rZ41@whmuC=n0<3fS?BMMhH*6wK(|?e9EdKjQ;R{UFuBxVw4HhP5adu%Erz1q z3)Ny6ity8ZSztGA=A0T)`L5CkG`XkbhY~sZk*N7p#YUmo-4q**9C%-84C0?mH;hG( z=>Nu{X*o}T(a!gC-YR5cqtexA26K`iv~{5BtwHW*6*y}A8z|ogY6r~JR=`)ng_MW3BOM=ux+@}XswRBC~2^Go^B%_Syb zE`U<$2@9e_Q&d_A4PYyU(N3=7BFN!|R2232Ar(W08>&|v-Mgk(2~>r(|B|Q{d2uOJ zma|bBEu^n2g9`H`y(}8*tx_xW%1LLa9Qwx`yL?Wpm}HH*liOB6FPA7*5q;sFsf6~B zncJXO%oZ!7o?IKY=n8p674+h$VpY*2?y_oVReqILM=_C#)j*|dOLoX7k7SRA_^Mt_ zG>m(u7IL^M{fG8NNVQQY&vEz>K_ma*kD)FyDI?WG&h+vQ=n?PgIHCcZzxt^7AgKZR zMo!ZZMSfGP5pvH^tT75IuUHe*j^EyQLKGOB(fTaO1ubZz7EMtHW)scO0M?9}qn?}% zSG1q+qXlZsTB#eV%NW`cx#yAG(UhUuN-NZp($**!IjaY1%{bTweI*}ni)PVN8&Kzo zk|*-+q89Ct%>>nJk1p}8dZD|+r4A^Id$1!K!`z?~nh+%M57!$%FOoW=`&=(wkPBml z5AwdGSXWew`?nkF%UVl!)V;UV165ip^+bzuNxjhCDpGGWVzjo>2Su=tzNl$wsUHfW zx9~+Vb=9IjYC)bo099C_b2Sj{;7A7{6L)DaYPeM`hUCQ9@=#QryJr~6P2Mydy<(Nb zhz_%IJOZstRLl?ge^I@W=rMD(QOL?t8jZ?vosK~rxO>JTGd|HcG>@Nk_U6t?^OYMaYX!xfoSrrtXjI4ogeW z*)){~AR{xDr6`1PD-aziE-gb#-b%~Sa^|or(A4AF%1ZQUg|rGaqfcCoo{>)mq1TM( zYtY?8(pnVEw-Ahcb7{Zp&=J<4)}!g4r47jClUi&U7F&1;J7M2nei??Scs_IIPRjE#GcF+tjkoasgPq0iU(UL3N2B3(f9rs~{ZL=HvO_7aNWN%dvqxJjk) z=ojPV6;$G>O0S{`_KICY1C}dx9bKgFynzmpb0wgZN}b^L8Vz}U1KR5ee#ihpzn;uKT(lo(l2z8 zb%@{Skg1OE4|>j(^%psl_5VX7=uL9ze~s6AsD%mg=UnAR^O{ShXc>859(0IR9y8?q zTrKhqeNOf4(Nb2vYoa#1?@$Y!%TT@lP&hq8Z4}5c z*Fk2Cj&;$@P}Qr4Z2n3P$hN&o9g#;VsXi)HM5PVTI&q#BMycN~K&}#uGOcb3yevLru|D`k!Vfm2r&)BV)C0+OKO)jBlm|D#)1ah9;8_ zw?uh3FYf5feW?|)>L|5FL+STC(DlNKwL#}lTlDp`WI&h5mOW9?Y#l*6w4U#+J*rqw zrC!MUwbTKvJ*O>qL}#*8uM_H(qEc^EhkL6t`sk!s7c|pW@Vd9uq&?B-?@}-H=cr11qk%@n`XCQ8sV{N}S7|>qk}T5~XoQ^ zBN6{Zs9_X(o|6HhhK%xK&=&6Gv8Ym*G!F46c82lD%t_mufNXv!HWB&I4^2YB^uUu* z1kWg^ps%cdOhv8eZKolAKFly3d9X$>1C45@*h~~3E6qa7zDToCi8|68WXW4LbJ30j zZEqfW^hcVHHuB4z3s9S`+VVm)%2jO_p*I7i#i%~xu0I+>Pq+lVWpoKZ3p!{kOHt+P ziUp!CT=&b+wh_{D^yrba0;RW=Rw8%qqgBYem5ypP%Fi7YgwA;O7QF?1=aX+mdmU778%k`XPZWYo z_N&Eqw4Yhx4s^S!TI@vm80~kV$YRoNH0+?ZvIm8c>+eNv-YK>Z9pefMMa{{L_M^L% zRC)j{<_- zf9HM`jpX~dhMLDHb{#cxRJ|MM5N9m`ou|LLiEh%r+(H}4&2A&lr-~(_xbBK2p-%LP zcaYs4#qOf>8>D-v8+ZJDl#eU+0ea9(r4NyXyN>D+GGok3Myr>q^fB6WN3kcUXJhFp zN~ec=hVJK4>^br)D7`@b27R`d=zVd;UZG)JIVmW#nzsBJjpPl9Hz<}7EEUD)SG_c3 z#hWN^(FSJ4?@%K5WjYGwo_UWxaqd4L=O)re6i`DgGSE?GQlC&2@}^AW6IAa-P4V8a<>eG`NmhWTWZaDL>F_zQLd9be2B(FLaE%>^I88b?^uE zT`T=XQ*KHB(6*c>z`8_@H|U>DP^WHEZnW{GWQrCuM&&_;=o8IQ0M8!tqDW@D=IHNf z)ys!Y4bTx-pwv4$s{H5`Pg53lD0{8(1!;q zt&8Tfj#Cevsi0B^luD28h|*X)sgGK7)ipr-hU=&rqPJX=jnK+jQe))H_}c_Uk5OAE zv}nI#&S>~8$p!sl9Bhj6rAz!nHO6SJq2{PpDaBmT`6#IcYH~z!Lz9>bwM1LF8{N@q zuHsf`Ha%u*v}?NRd7!`^inT!@qZDh4%9NK3sO}z>dZINu6>Epma`Hd4if0#I=x?~{ zbwJbU!#W~o=6;>f%>I%$@_eRxosl-tcZsH`FGN>UBpKxwm?t zX7pD*(PlE9UT7lULT^-sv7!&!#vHpZ`nyu4{m|lQ$rpY6A@xVsxlRY5tJE8aR?^c9 zLN%Fd3`V&bKZc-v9@0=WtG$kI81ihQ*l^@Z|7=88xNAqCG9HTgp}O3)Bat~*`zSP> ztbQ~aGfWzT>@KKuEc$jppJN=F!z`K?&y6N6r3vU@8P%JJo(@-R63XYS*km-7fBAF@ zI#5Wlspw=C?PD6+$h|ck4eG15GtgU4X(nphP@07@lT~jv%JogLIVga&n7OE2LG5E6 zdbU-u`N(OmS}Z`B52b}Dl(Vr2Ww_`F7NfqLD}R)ibGig2at8#Una!o8D0+w#h?@11 zmLbOp(sJ~_v z?Lb9MrJX1}L)w*7O4hd<arog>(?L zAm<80VLbmogwn|M4kHux5spqXdx}8oxMCwwYx=|}mISzp59D zu16|%9-XMHSRBeE@4SHiG8?;yN>)_t68gf`ei==xsw0g@9gQlzf>L|!9;3%a)Zz&$I!m#qXxl%DynUkI$tys0m|PDl$DJr6CJ`8}ThF%=r5bz0aqu zq@$Z>r1$809o74Ql5*)-KBBFSRhofTY*y(fe--4T@tNMufi8a3F}tDglB(Ad8G5RoJL=@8SS$3Uuv)Z6OVU*8fvmZT+o1f@ zw3W8#d1I9t&{Uq!d7@ifL+wx_a<2BMAhT^RG>W-P2V~A#P)D?xT&fe=)KR70D9fl= zXLRfz8)wa@1OKU!#k?97uv$O+8bT?r_w&i zK3&Js7i~&Vy?$tn{$ub($?sI!A6c_{J^)#Us&pWVVEteaTHiw&j9Oh)=@2x4`)DXC z&g$SWbcwrhI6AphGNKk-lOu9seI-9+Wz_aYq8s$`qtKS_I)c%tB6kG`X)M}9v9W00 zcF9@1dz*pk zj!-U{?@uKm>wi*Sq@)?B2%vWp;`ovnsS~RwsV!)yLi+&|UZjjo-N z_Mkw*O?~oxD46Uu6s`ZO(*4LUzhVc_O|r;?=s?c;A2R1|JcOpbkq)D;{!%#l z$O>)*@*@|BL>}}=QRsFP#f~6_P3mu%%cD!ftk;!s&ewF@X~y>th8gLZuJUDE?;s5wfGV zO-7e_vho-u)8Yx*YOUB)WJ-4Z49y6Xo}+qer59)x+1E=nWV`eVT`#Y_rJy1MrPrt! zdV`j;9+8R?Sh-6>jqa%QEh@(~^bXZ7C#9oH^wjTBP=B@ffJ!e^>?4W{lrm8Job^AH zvPZE@)a|17_8ILWoBNWZ44s3osO2Taz9E}%wfK(mBq^4KqF4>cMrOPT@BD%UnV_~yq}(Wtyx0^~;cCi*b~ljB zQ0Mommlw5QCDj~lC(p@;CQgwoP?hmgeso}{>RBQ`My3L2CTk-FQIq+qR|plUr&wW> z^;xkZ=n0>#D6%GtEQSKp6)TPg^DMdqx|1oDM02@zOQC2+`_iZpy=@tk%qn|XWb~D+ zP|lvQa3)SOvi@S8jM!ekZ*5or8??EE?NV{jFaq8d5+2+l{zQYMAaQsS_{RNSL{Dze?@z%jg~Rf ztb?vHYScwNC#zmP)R{5L0lmy6IieSx)uKLXxIpz9pr6)KLliYrYJ?V#ml`8Wa*!sd zLq~1J37J*WR-DmAMr;=pa7}88CUW%6P<&4Qhi1@^yP}5N(=AX4xr!S~-LKM?sKFk^ z+)+)|1zMpx{PJ3Bw7a?Ld7#f^hi%Yd)=Jx=@AM!B6wSTmiEeT|w?p}>t8IJq&s*|B z|2aw>(2J33(Gm6YRf|rj!aBvgku7V7yr6D;#WmCgjeVxJKFE_TcSZJOs@;$&GxhGs zXQE1bpseoNa!=IFMX_G!bWN!@n!ZZvgKo2`(H8}CW%onNn3wsY4X#puw2xkI0J=cG zHW1nK*9wDB>$|Eq7}+qN8G;@*Qfw%yR!|y-s-WS>$x`)#67f+08Vx@uo_rqmlGdGthHZY-XbN^pmqtIcD#(kyQ(64*JS3$jwD3cBtMw zG|g6;kBWYh7NChmwY`NX<)hjzLd)sv7Nd~ws^^bf=1NOYDA#TPDrq4tMQNp zs<#Zyqd!=V@_H$@0%bd?#Y)tjF?1DLI7_9gkvk)75ISX|(lw}Z6UEk|j*LvfXq1Oy z>rm2T)mx96R8njM@}8;KMl{7&=U@}cA`{$<%u6b^1$Acx+lo>@sl_(rI713S*{t|) zN3rF!-yO(_v$hk((Oc|75!_|F(OpZ`+k>urRctRR@I_nMhc>fX8;U&7t8_oAL2q#Y zmF*=RM2AnSUKo1G8rdOKpR;xtO(>yQI0~VEi9kEZEh5no?u96Hn%{Rif*c!5N70k2 zYH;V`K95=*QY;QdIZGGN!%8Z>h)lmrm(bEHD!q)l4N)u}y_u)j6=dI2 zv8!lSA;qqtWUig-Xme%h1}aXrl7I@BDs~fZcC${%dk>`p%K&>7~4^eaO(MM<|xmGf|N-yykt%y_X3CcfPdWt@= z=iouQA$C3=rdoV+Vp2{&_`wwsmPTKD-BJqF1CemYl zMb%Su^xse#J?eMl&v=l9$};9;qZ$Pi`+>$Y%Kt>8IQm~Gy{<}sqhW2@Z0D7`mDu_C>W?cvcaHNINNUq`{h*vfYMbRPpxMDdmwpSc| z*MAHpP%dVPB~jgn+Da*8!YEoAWibmYgA9|TvM6+~u52qbzk*`rkb}8Y9_44`w?;L| zM=GFgJSnb-Ra2{c$pvju13p_76wYW?6`iaqRYR?r+f+yQ8Yor+ zy&z_X%*c7{(e5uQt%)qFNVU+gJKD#8=t_WMwb7p-sSY~RRH}hXVMwndaW(Hpuw!G zHANHM6l;bu>!?L@G&7IniYysbS|BIxBR6DQO{Fc-hR2dSI+7{1LV5mEz1FDRMz!@o z9k!{o4Jz|ev9_oJEA9sLy1hz0b3|X#4ozLEdhJnIjO2ypk5Y>c$UwH-5j7?o=!EVt z=6ItUtRQqo_KZzkP@QIy4?2EE>WWU0HFQI7d3(M)YIRYiJy6jYsVBPGQtE{Uj*)t! zOh2g)GGPYS7ab$k51k_q@8SdnN~~rKK-&hZbYPB{qYXk=d4p&$I!G!1REcrU z3AGrCO1x5R7@EdxZ8&wO;tJ$-Qv3(j~1*{Yy#>>&Nva(;M$mkJeluIMq82;n}T}qe!^5ViTiRIdP#mW z9r>{`FatGtq|%wF2K8p4bvvZl$Q8{&Zi}S3=s#u*^Ux*kxA|zn9ccmT%QL%$=(n9> zi_rRYI+n#~bt%RC(F(H6CFmxZLI9ffS*1%+G#*49Px*zh81W@ZEbla zYRRv#u0qjlc{S>_Q1yaP_h-@?6k0*0Ytd5&wFpMH=t0&YR|{!98oo^RHlRh!H8&!6 zdu?SCxu}P zDSbp!j!PM6cA)eLtz)#xL}4|xx6ddpLZx3&5IN>ol*pORHIZ)tQa{ zF|YW6mXbyOL{m#C_6xP5r~Zx16IA*K-6|{nMFq)i{~;6lzg)AVJdu(K>ex=-LT>co zyJU*e#_9<2ppo3uW@r*)RNfrDmdsHt#{GQgr>kUvdNBUxN8=VLW{F&SO9fD;;c8nD zWiuZugsdY~S{PN~=!+o7tBUawfN}dV#fqVq+@ZzM>K8iF5-66nj*`e_ib_i%%Oz52 zG<&a923;ikFN*@0zgeNbB~@AuoopzTM@#rVtWiyJ^a`jO&qpevB0IIWN@yVcqz!6Y zS1l@|X~iU4)Wkumg5t)gMOE~nwPMv!SejHFRpxBeKmpwQcIY|1iaolJN9Uj>%BmyP zLI*Fa#eZlcqd{%-hBFNX?NyJ*z9a{YKks zf%dFa%neOqtZj+rvk!N)fVoR6^n>rRH7Y@W<$*SEWw$}z%)r~C@S~Cey>OL0Q6bi5 z+oAqt)S^8)9HUY%bittSs6$TaA=T@M7J8^&Cp4nF>UpCwe7~KMTcXqjb+eItQ2uV( zN>}vukYe4?qh?Zfbb6@752qRJGPIALXlYf&dZAsM@!n`Hv-duz=3K@4qLH>zKXkRY zj>;ERVC?RXKJ`{?0BY`{*g$lJf8BBrdP1f!7!~6?8iHn%hYdwdnZ*o4p`8>Pj;tC< zM&$HLrTnD7v1wE7!w>awR%|3H!C%wg$atO>-@3oL6mwQLn8kU5A=>SLu3Ga)@FZQ2ZKcBjTSeFl<6qiEYlQ z7orwh(59{0+g23Bb+rv0qz4W`Cm92_qY(aTY6mLaMX{a8hNlF(kktZdH_AMt(miMr zbKSkD(>ulXA-5rlg`%n4dHd1wjw(HXh76PrqR(fvy)b0?Pq9O&ucvevjmWLG;mC() zqYwpv7@S7E9bg_<^%j-V?Z(oy7JMmmP3a$Oxq;UAzj|?*>|STBQl-I{oBLWMJNX z3pM{K-A38uNQvlm2`LFx=4{+S@qCWE=mq)4J#?S>;C-~5KIZ`nB`17{N={eo5jsyk zo{ZASl^>%SMHPF3zCM+nqUL1H&yZUM#h#;vmvx3-plh^viK;)8UZGE9hbd_PUd3J` zkLilNK`XZ@mWtLeUZ$b**A#n;^0rXy9r7b*NJm*#Dt(X4=_fy+C~|?1Xz?h;GSF|b zf=_5iu=bXTy!fS&&!{%~g0`ctD1*|SRywv_yQ<;kLndfuLfwpg^(vL z3Zrt275p5saW!j3MNu-@QZeMu%(^&wLgrBd@zSuNBpSz4mQrX1<56kU?TJ(dbr~U* zMP^*PR%iLECJJPBQVX@=8vhTOJyU6I zRQ;Y*2c@z8QWxFNP`!GHf41A;fF{tdIU@e}+)y9g;(e+H$e)q3A&MXaZG;AKwKqmh z4N?=dGeUAg2kS}BXuH4Uf-2IhG)2k0i_i>tF#m0irm$M;ic)N(7AS&G?uL3lkXj=C z#NObJBFRu%q2qrPYmJ;e)z$;;3fDPpgJ!H&y|$vxcGabhD3fon6ROX-_eO(XskAd%(MenGg5u99=7X#m5xb&+WI^4~lz6E- znieMYKnLGRJ<)V}yWh+@LH0uf`O6|-bS7EqkESQbZ z++`rzWTNd2LZj&g2BWcjgG11_o@zT3*^-41L)P?|!_l8(k`eu^qOFWTgYDJA58c|V zt&Buv{;1w46jn_djqIIOItF#!B#lM8=mo~1q!QZRc+{eRT1-G=nK4g9O&4n)lhE>B zicLlXc+xoql zqQvcL5r|$6QEVBqV4Z6@D#I1K0tGS;U5N(qY-be;`mWN|XgRB#L1-1FYfy(NimgR= z$#;WMKp$xx%1bV_9<5^?X#-l{MlCj?jhCfO$dk{u8QpuMwp-9$v=zn>X0@=G6O7rTfqy?)^|?a#h-o zjxqZ@fNs)LA4G+Ft27MxFOm)+56;?QG_bQ2j>1?2h(H&3_7sVB#3>eqmh)`(2%5`% zeiTh&J?9vTjMDKPM;Y`@C(szKmy_r*PeP*6a7V>r(7Us$cM8qpJ35UleHA-{rjtLP zMelk_=g{}Jsuzn|@V%W!KI;^VLsiIkFQ9zYuE7iRhlaN|R7> zOSQOzZl6-@E;8^w{XMkBPP&iY5qp5vbJspZk=$F4P`fqSax&rpx8X4=J5RAEs6P3@ zQ#6&l_!;U%mhl|j;B&k{ryof#k#UDgU!iK;`zgp_s6NMQbd@XY4GQ*=Qjs~mV;cIx z(}%Yx^|rS14%Ij=rK4p*Dt(WtZdL39dUIE?kEjf*3mNG9Tg5)12l*AtM4PuupOG7V z;uqA2r|VzQ0D9nWXb<=5cNFtdrCI0~Psy@T7v}uCo;P!{mK#V75qk#ToHdz zZ$_rS$fu0z{X@ksDVA%FbflqLn4l=~-P~yDeAVLz-;ISBd-9;@eQIHbN^X(zqAT8# zIcjoP;-BTz-*Kvi1)6(JvHWQNNy!rJ-mjx7fM!%stROODdxelcEA)j?P3CV!(2lh# zEsAa#6ypcgjs6{^;;0VyZwb_v-l8O`&-Yde&C-7irO`^hqcSM{osOU^n$Fd3g(~oj zz8vBY;tb_c)z;dIHA=fHRX_tXRaz1GG?ywNC)RguP!!i`W%SEi`>;h0iE3K~d6RKh zMNW%US`FFWP^>z-#%e$f6h*dahhm*2dz4s4s)^hfA!?z0%n1HN74xaIHmVb$(mH7G z7O5^eLY`9(eF~KvkWYEZ5e-_QdiBvaR-zlAm7f)Bh{}-(HbSlr5?QVTa!bb?|nkq7_g zqB{yKqF5^w#QobE6-<;okUQt94SL&1TW*UkG2$3dDx;bw8pBA^4n3itY>(cRQavx^ z#<$-A@niOej_3|KO(#^2+{_ylV`aND`u@Mgq2}D@-BAnH zBYL27HKm@YBI{wj&{Z`j5JpCGzQ}3{jc`WL(Q>Eijd|qih8cp6l0bS8YJjQqYR zHU;(L{7psI*~&CzK2e&EvhS$H3{)>&v6-klD-Lu8#x!Q1v(fK1(i~J^qcj(pHYytX-7NS<1`$cFBtHg^@@%oDSqp*F7EkSLns6_xW<@lDOw&Yxa$l|KB z47u@SYB@??ptG?86|JGzO61U9TUmuxCQGZ)-P%$RddRoB2F*ID7Hg5)8z~q)FsgJN zD#dg5^=N!$?PCLCNHALXE4c-e#0e7PJL*$yST4D8xyzZIa%I`#Dk35Ta9< zt8dTI29@tX)~qV*M6db2cA){oRJt4W_@%wt7oI>N%py*re`NE~r~>PuF=z|F#&HVu+@!Xrk%gm5&!DGdo@Y^w zAu2tGer#4O7PT~$&ZEYB!*M7!x9VL$rdJfZh=$M?UP3Q<&V3oJe5zPHs>nTX1ubBf zcoj|mtJpPkKS8nUs7ZNk`36enNE1*nndeP3yQu2jLgN@gZlk8$Nr~t(qgfKl&%Esp zIyF|hi=sI9_s}A~!TTtVHR}gx(jdhiqL>k?_Xr&&hfhY;8%U2){B-T(2}RF)YjK%rUP(~?BWIA540_Z9|LqXIsRA;gfD#18e7@cjWQhvnVcr;sWi=yHc z)V3IU#pf-K0vVf1psk~%lBkNA+Ll5CVihZmzVNK33_3!+vS@>wwqk{Ta8%`TVq~7> z(T@CzS)Q=qBq{bx<^`H+7Lc z@3_}P%gBQqP&xWKM^vA=VSQBLm)bT!6Pc4XM2-oHHA2G=N{vzGER{Av8$U?=NQQAK zcc?RR=JWCzym1asSev3FXB2CO-f+y#(X^V9E9y&5(E?rOuVdX%bMn5Hs2RDwJDM^~ zduxUAhpKIB)QjKH@jwrEDb@xJqi<@9hJ;B56vr&b6E)*a#&)QUuUfQ6-b*Aew4|TZ z0iC$6wjEJB^5IU%I6?A8Np-Z9&gjfL#k!#4E7aBp`8QOoEBf9YGBpNyPgZO!+Cx?_4jH?u?RfNs^D+UI>7~+%=&7e#OhVK6i~Px`6K_yX zL8i0QA1UVoT9L=8J(Sh?(dz zbeV5|Ioi=xr7Mu#Y_(X4Zm(A9DwN1Lvl_XPs|KNOj3jH&272YSr~$K*V05skv<`WZ zp{_^s=>;~RpFG9bh&qp!Hlb5|qRnVktlDltEpAC$QAC)u4OR2jenZe&#(?dJSF;Q| zkTvyoqJRk1+lB77)#u%fnsO)aLADX9w-*)R9^8lK4wgdEQWw?RkGe3oIe?DDYAXkk z3s+(oDmPy`gc{V+(H}+~-zXN2j?0vdc*x`+x^l`f$r7p2SSr;QYk@^dDypgyc0T}37X6}yH~$bzn; zp_$SRRNqcYK%Qr%n<#+$_ZIT!nelDp%e|F|&d^IGq2kQy?x4b~1m8vDJ++m4=-5W- zJ{rmz!2@*qnU3lqI?jsIBUI^>>Lurt7F6sps@q(#Cuk8XD^F2YUd5iF&%8D997T?l zUZ7=dRr(UOXViFwhLb6zpn{yg*T~?f*c)WamQzu?E;_0-)ZR<6wcU(pf#Ku5_Vexh?+SHFqCXK!Wi zQ7E#qpYNxCyxy=^^vQ!s!`zh5!23mIF8pvJN0u_8FwM2o8 zm-gr#XQ&m5A5TY6Sk)Sc_m6}_WAH+0ilsqW|m zJ(mY6U@Cd$#<=5oZP^e_Pw0iL1650R)Od?xJG!TU|?hiu!zNqHGsCpsA zhM)iI#j>1ZtTs~O1g zh)T>v!K}8!(VSa~%|bz~RCYG17p>SFl+E>>i!$g-<{`(e(tK30j>Ie4XT3HqMXOlIy99#IR>p{k8C}f=cw2QIc!k#?m45a+qp9jD9y&>dTJ%6*O|VQm>+)Y0@?Hx2ulyI-26D*bOv+S^Z74WQ9_1p+k&Tx6!2P(jDZ$-pyU~ z?~G!pXcTX{rJ>SS6uXDgIS2Pq4x{q}nTr(5LPy)^8+}9-rz-XdRZ5q#Q6KhDKBIP=wJ)gdV#U6q zp1Jcsw3WTm@5qc_;LAZjJ1E}|w1*kWPxOaz;TLLMPO;x8pOs4dK})_V_7^Q>Hu4Xp z^OjAX8PdT!iseP$LnR|rgQv&&kkb&w@}u3{c?HmZb~y_o%WjGlLQk%!L}4_St6Bt2 zIwloG){K|M(D>$3arE0ksmAC!eWwXZG*YYt8h28$k|>q&qZInac`1!L*hytjG-s_W zN?IY6L)-jyeC3fVtBwlDiM>}-RD?ZHGqhxnR1w+Jud$3Yn9WwKGHR4pWvieO9DP-^ zELgE>Xf|`C>SzqJj2g(OrDEpDnz@e!s%9e9MEMRWwHE4sM)lQ3iOlfopw%@MtBZCs zs?|ew>?2vC9yO%;s1s|52B`Q7)n|p)afYl>HrKo%x|yt08`PAx+X!uE9oiT*c%*zy zkRLOirsyXlyDhQ^QLGtqqDQhrJ-rocj{b2swm{BhmD&=0I;B*5WK&qFtKQTRX+NqKQqE&ka?5shB&mH&)C8Su$#PqWWzV z>xR6pDdv@%&spk@65mKYP*l7=qbHig9zZYDuc3~wH)>3)>w^xRRz7cJcS5oMknwb> zFRD9HW&5Eq%$572BAq246dkJ60VrprG!QN0xyvBbgpqSF`nO9Of(|iH^hGsk&qI;X zCB^)ZNgExDKU!?1*f4aHd(eOi?on(wa#<{mK;^jl0q7R}ZXl{rR|-Na*xBI+>I{=A zsg_YF%|x-$$TN5Thy3R&HWt03JqM#zw6zelmi}cNdbmm&kG6)ZzEIThk75&0uc|uw ziKr>>gNLCc)^w9lg1s~uHD{(Z1$EpnO-131;?vNo2*swOy|kPes24rROcc#NdN^7= zSgEtnqkGb9G=%YJ4l)`e%|+wGRAL_TWlWxr=F>_RpnE)3h(M=qD&InsxLvVGR69_y zMd&;GW>F}Iv$hyjzOT<%f>N02FU^f{q{~nr-gjM&R+jy^t(|&RmJw8KR!|% zYVlm!i+*#>_n~!s+J4mEOR)nefOc>Ybzx885c*7ghf&&3#f~6P<_z&@#a<}^Eqf## zMdsXtiHQHe)+Gr|s3ILhNBF+SQ4v<^Cy*DPmW-OyH=RWHKB&Yg)SF{IjeLlmL05TZ zeHNL}*3O}b7+sn3=;2AlQqXz!{x6_0?5bTvB}+?}kQsA^%cv30qpqO)?5SQw3wRoI z4c#84eAiKX_S1npiUJw=V&mHG@F|EAb;l*#Vp3shR0 zT`n(C3!XE*LQ796-)mHptMvxmWrz7K8ppgi9hGLKnSpHMrFSUZMc?f`YBNc(56I-N z>dQo>!WGLxJDDebMERIod_u|0>a)=R=DVNK!AzxoL8~__^(!j%TKa~1umb;%8q@xA zkacU7_<=gG0{@8$#7V!k>fP23bdPS@>D*8?;gUpzVmPI~hx-#WZOCzP0N73}p6;OY6 zdQFjMUd7B%DXvjP)PNF|P^FbpWps|usDjex>l;-?QyWRu&|9uYbrjQ0HP=9SYN~`e zN@vDxfxhlizM9CDk-ZiQN|0(JuklhHRF!?@x~M15qw1jyb|x&*1WTzt3h$+w8=#59 zBrCKvU9v`T?Ub(}dgq~HrXFT#m#d*Tk4NZ?wJ}*?6*3=!nP&UunywSO0%J(07GFIw~*0FEf4<#@k?~jaa74t!L*h3kB z&Yx3#1Cgbt@(n^?*nu33UU4mlpqOeZ>xWf!AbZIyXfyNN6)4C^TA7=#o>Et#WcFNFqsHv1uR+fbE8kl5 zg(pbsPzb+F9)s-pjP+dqU8CiZxb3q?-`4VFhkvp_Wo7s7PRrIv=z1P ztJH1i<~Ehsj&`wX+JU_3d3PdrN0r!x`fz{mMn;T(dyv&EDGqrv^W2LPoK$unTFtJ^ zezY`LsRz&+cj+Js|E+w7P-)gIhtatn(h;bOz1hjGsllD@o^&{V|n2 zk2Z3yQqZ(0mAHWRaEDw(A^Ay4K(RZh6??dM(Fk@BQqd3Y!Zc+6M5*^sh=pSJQU4Os1GF+# zpY{;#_^o`8P!)DnAEUnL3EIZo=qZY459k^CRZu0KqqVFZUZD5%o-a{z)}OD?4PT|c zMw#ryy+Lmo`QM_c9rYRMs24p#28v=X_zvyKQ0zT=6)Sx}lUcuKq7-J|S;&Yn@gs8N zeS%LYgZW4{^4KnYMzff8eL%B0tvZ zztEf9Hvmz2b`bucE-jS$7ZqjA_Yax=QEDE2xFLb|mlqXcf6E9R4Nxo}%Hpi$N5>v0 zRsh9~Q>-AWKS?Tt%Dh)<%u!C9`ZHrK9Jrr9&vP6a1wXBccn@SB(3)+wsN_A5$ z)@Us)tRX6LRrzdCR-|H$Pz6Su#weWCGZTKpJnosM=wm0z7A3MCYlf~e8?ZysbEW2J z{8*K3ftt5etR*VdL9$2XP%G56gN~pz@^VtF4eHMNy)81LB|0EO3&q-@IjjxaqYBJl z9Z?*sx(=u~-`5G{qn3^+l3uwJGMS_E=ZxZ5Np(j4{UjH3&R^<+JYJ}TD=KWTu& zNN&jNf#i&S;hJyV+WNOirCU{@k0kcO8%(b52X%6-|6)X=%KkZ935xgHv(BQb_bxLx1>PS z$X5!=jdfMNk*GdvMtEC7u zi8<{;6vC(*nVavqQWqgB@1f4sj*iy8iqqGcVk#9M&WqlltCP%8o z3gqvr)RpKtNXV6TH1~lF}K)(8ZbiaM7PONHL z2+CyL8;_214iZqfvFbaD3bVROMEB}TN$4gc>@noQuGVq1ovVKWt>%{_lF@wo;;X7e8uIF_)O#pTe(64n&8K`1&~Nsc9-=7voJT0aSh2^*-ClZv!j>rYDRQ81 ze}|`<3!RrzD3MlD8Wm)Xu@gU`^i%jz? zRu5(MmMqb*`ci$go;#ocis7hO@ET6AlCwqzdh~|qB)y6aD$Ode5lZEA8zZBqQWJE! zhSU_<@qd!pqJTk)HA5M^HDQO0N-EYIO<_&k0(Ci~SWC2?6_q{ezgKF7l4wJ%(UVfj z*9L7Ks?@fq8*SGCZQ;7LL-C;!Kgnxo%t-8r9QfbtIv|%LiaDW;tjjv0lwqo+6B_TR z&u~V&tQ6~vhB4o8K^?dXT~N>as?QbGV&>5m{aLB{+|Z~oD&daI+A5z1@}8$uPn5Ti zQoEsBoM$hTPHXCpsw`H%9>_pH)Dyj5C-p)jd1l-jEgB;AK_R~+Zxm-O{fGDuAzk{S zitHHoLse0K^nQfogYIsV2B4KURAL}noGuMQ#m-8D(SGjBAt-^hhA(m}Ck;h+?&(|l zAqQ6F{^$r}_b^nmhf)n_H?yGOXbdrXHC-Tj=OP861MKRLM6H;wjY1)H zRdzHQ^iTQ5AcwlrSTxK`3Pvd%l`jOHyrbASG;pnsWjyjUQ7jY{rCm)xwem?5k;xV* z4E>Um2gR-;AC z&DNlRr7F7?rG+cD4lU$~PYgQ2DsVljHeR)CKoc0ZHlnIk6x)Q((DTQlawVkAXc7BO zTTo76#kS_={=>z8C@=_*cFuAP$jM+Z&p;-(1{At zb+r7E^4&lltP*Y_FIK|0(D$OscN=YvSL_b@(O9v&$d^$q72Um~)HGCs5&IsBr|-Ov z?(|Z=2k1BZ)DKaTlk_MzHAGkIG3r1s{{+q9`#wcix~uFn#LphNJV()--51E?sPq!8 zT`#@L6{)Y0?GWh=`Z7X#i)u4(N=Fwh^%)tcIM@6g>d4IeJ?g>den9JdRU#AJWzCd@ z@=Vn+e?(r~gP+i-F)ERbyjh8SMz2{u1e%X zb4%!R^CLIzqXOt7BXL3WVzg2Vp*8zewlK0VQ)&@Zn6pt7{brtB49#FnE{^ik{~4q9 z!xS??8<}yJK=p^HL`f9L-BSwP=A4#BU)bv_gBG_@YFX5uUAl7UexzdMQPa^<1vJ1* zB}~z!rIHysJWr_=QCxyzm5>8#p~`5MyFRT7y2;t7iau;oiE8M?O{qHSVkgx=3wejm z9JOexm<75@8?T9;tdMFUyKz!&RF2Q6gGO_%>Y{-YrFv*Rf5~i_8>7#zkId;08la2p zQ(GYq+JQBC#LS~1+Q&#@gT7Is5o(jI)W#@|k*)~}-mTQ8$j(>CVv8)xD76`y=%*5P z$a}f+HAh*!6l;M_a|g6UwNezbM=hDvw?YnUrPipigKBPrqUoF3qLt4j2jt5tupN5A zyOixw-RhDf>c$>G2h=~WN;sijEA(j{QHuzv6LMue?TmKrRID@F#SWhf@?bpbg2wJw zsw>J%OYDjk=^qz2REfEnJBsA`dY}XRWuPb8^`AbY8;YUjc%cCPhlcJb5cNQ1n1}U5 zu8X8zXc5=9Hwteg^+E2umF0~V#wy=`=msNBU*t^h-4EUUrC5Jdmb2!AUfHRZ0Vw>u zVgu11_N4})kMk89jLP!YEkn?5#%W(vpPA86^Mv0-TCNW~0j46DH5 z$bW-UN1zXWQUEGQ*+8_45itn8qV0}E*7UZc&;jOkqftEb-7(0mkn)X1U1=}D=*mK+ zhUBKMRBRlYNo+i7#IAEFilm)RK&FkAIuYgRs?;!)7NXcB^lX6gO-7}ei%vn|3zcsw zdd=Ko8uIs6iRq|A5yfVps1wpmw5Fa?!*j*AoQ0-wjbGqU;o#i((I`#5~l5 z8S;Eo!cSU&OkOB80=fT{79vY}>PYmtutdW&+^eh-QRu=|#TKKxEu|%B{3oR@MR}?# zwk$XGvtrAUyQgB&=)Wt{3e+P=sVh+yJ<=-FkRx4<8vUo(8uYEIv=-UdRO-516_8?3 zdsc?)kvlV^4Jb85+K9MaTs9$7c6(w`&={52jF$61zHLF-w8X8*jL~2l+Rr>^JK8ov zu^nhJe{rxA8E84XP$WIlZd91#+k=YGHsX*Y*K#k~=C9a36n9P9kG60R9zgXu;|I~d zlF}ixV6t==jbOYyf@XJ;;?WDv1Am_to|fw(oC^a=wGH{r_pj|0B6u#6X`69W~4iZc4sMe9xdQmTMAmreSQI% zGHbbr8gqP?Q1bywy^LycCtpE*`YGR4G@0kq*U)cfjMsA&pnNxwb$`WfA|Ga|x6n2E z?Az#gjLP0YFUKk0U6g)aN<}}o(rKu2C+Qv<%ZlYbGB2ap15_u!YI%qPKd9^@lwm79 zMsC5<6VxVBdWx!Asq8ak%3byxwdG!Yffn{r>?OLu?#C;%i1qYql;x+`8)R>$V|j~W z89&ldFV-m;$jDgv-l4SN(tDK5y!Zn;M!U*Hv;9>|7AnC!>?1nEoZ%D7q`hRLsr9AL zD1|+vFX&fo<@<`taoxV52bnq>-_e~|mB>Le-Ie+SIlWhjpQt(g+As8xd-^xxQn>s< zA*|{CqEu#h|4;&BN**;XLwTN)`U55>x$*mL@BWl<0+hstm^%A-Qecq*Wx7bR1){i4d6p?37F6;a+v694J5;n{HI ztBfYwOI47qlj^IAUhsdTR70n?t3-8Fk$t2ZXx~7|9KF1!REykL5yfhv?wqw+=(wL! zYopc7EbE{iO_W*}E#f@aLyg!;utc$(wfe}2`Whgc(u!H3Iz0WiM!mi$)({OQpAGUe zQ>+o7EbwDPx z5+`KD&SFP2hZfce)#o#u(X*;jXLN?E;DWjhQ>+VOBi_Xoy<^_q6`B60Pjf?|?4-J* zkPAxnKrPrU^F#@(QoEt6wvrb*PrL7qPCt@*APcT^Pt>1w)e9ZmC-p|pSb_IJOL#u$ zjq0&e{vR4yTd94K5&IkcP#AYWe{>>AC4A8HnJO^=C2)-fqBt+b2B9Q+q`_!6&y6wQ2T3~I@`d@TBpm02*#w2(qjBs2VRXt|$i8IRH! zEkaS$c%@E2rJ5=>5q-6g!q9{urSjj48X|bwI~jd=Crv>G7AoIVWMZtdIt|sQ?Mz3W zca(1i8b;qg6Xo$yEF4v5bex5f@2Ko-RA-f9bI^;ys%0)3bxN^$=qV%Xe3Z(1X93E4 zS*Z~yxTZd1AqpFz)JS9zsn{Z9d|HY^q0N-K7-jEK*(GQPcgymIVyHZ zWuws^p31F2W*rn;i3V?zR-uxt7gwV+o6%)YrEWpj*umP0jA;kkP}C0P+m0$SX751lnLX}A zpE@aZ7xHYOns=kWl-+}R@!o748uCuDy=W8r&iha~=0^LG?;7asQMDn{%FOHqQ^eUmx%5ZS85Wf@=?cp42@=Xb{viGES*3> z+f+6g-OrRxA`jMgr;zOp=``BZQ1zWbMqQ+{$eX7V=a4^hh4bhi-z^0dp%1=*{#2AM zqQ%_Hm(XT<%FAd5&8J^}hK`kxo}(5Eo z3!1^3)L+qB?(=WxbqC5f9M>4rSr(nSt8Y{e)oP%8<#QFHd==0TcJ@rsYo228-%1(^(C#auRy&lh z5<2!ps*HY{D76ZD&Mc%V+B;IJhHB96t0T+Ts<{SQ!nra>K|#uAfdXhRHBkrp#9F8< zyOy=lRCnd8gH|#JsEbN|lIo#i%z`b^?w5+yN8t-pwgJj!#$knSFh{XQ#il9N5RKq2 zvq1$crABCag47u0v{QXe&>!CTZi+Ut_P0gvU6tAl_4JqQP@Zm5bL5p@YJn=6NG(xy zbIBg9d!<@hp{49fw?==yDb@z9=bmnh-f#sSQ0EM(9m?SuWqUNXspN=O=2L116v&Q* z6EYg2nmeLpl@#lQyh}>X$Sq6ijOKk&J{J_+R_cPlp$rMe>? zAGmlRQ$`n0)Pg&O9}G13bFX@#3*0H)(ONsD_CQ(8Pf$6h$x>U6!l+D!UwgVNWC)1s;-C zAoEYsN;H+Z*($U%K(W>roE(`3BT{pJE$P zH+Ho)p<{fHSY*OoyBS4omA0S-2UTJ#`n^D(yA6f0H?bWJ=l7^s%3G06pXltb?d0_vIlJn55Lh=;;~h z2>Q!TS3G)TBPAf$+&2J`cbsZTL;>YgA_;{Sm5!ll^ohsO3f9&qkk2T^l9A(B=_Fbd zCY?fidPt|yi@wqsbSO?bi>~wj=Q)&3TRV@=b0?>uJfrl@FQDb@E?q>ad8JF}$7Q8n zMq8p)_6mCPL$Ryq8pm=CE#>I1qfU%7H&7!p<-3Uzx%#(|slRj^+3%O`pzpj7c^9>2 zJ(G&cvZtAbLh~x$J>>5#-ABEbNDt78r_w`|6e>MJq0FBj=ce*p;Rz}^L#a- zP+9Ky=V;L&ouL=VgLD59@kin=uTXpTCSId`hn4RQs>PLgi;4_ZzI2pWMan>vE-BwT zup#7ESXnfWJ_!U&O#uCf>S8F@EV>v=lFi3q>GCEL2mt(?=PBQQ0!lBDl^7B z^AtN|s}lT|#s>cLJr^VN_JWiTt#DLoel)nKVg=AF+IT@!E=VebJ{3~F!st4^cM-Ie zwMJ2t!Mdjy8kwZj;;6`5$ruG4QCSo8qmg1IP-A`%xFkA2k6sG7kB~~Ewan_vprf>n zvdD(3S`NLT{gp@8Xmu5kKVyI?%H~%h%urS4B^A+0&QK*(%}ue&=xRl&3i@16s)}~e znyR6^FI8W4REU1420A}Rspe=!Ey)5MStHd%)mR7ALd`BIRvT@sDb+ziEu^|ABUr~$ z58dLfutcW@N%hftYo#_o@vIiDP#^XqtkGG%8`;2QASN?dR!T2NcRRcS1#(!FNP!IYXUL{0hk# zEoWWU8LdfF%mrD{61$+Wt5u6Dn#5?(74bt7E^esuP{|!VV|s6 z>U(&h)ueVu-tV*zODqn9jv!K)m-Tt9`-e|x!)%PE&$11-s>QY?l zhsKUoE&Mc^p{2D-_@E76qyfl@U8{j;Xgz5V>d2WKjLNe+GXy$C>8#jzREZHg6cyg1*aTE{mhw$Res>iM zL)96#CZVGlN}Y^e@J{0t6uM5SQ&Ge7(lk`Et27f{y@2B!DLI>&f zqENA$(qhz%CrwMx0q%gMXeRA`8Tw6cu^dfmFGZu-^eQXRG*iV^qC+ip^sCU*xzcJB zm!Z@(Xz+B!)}mu86_2Hen#Fu$1G00~XKX}oo+)(`y3c(Xi}G%lHlxZm zDzOD!W4*N%ZDjP@hU%y39BfAhVmnX?M!%iNkNL(fl*uT$8`Wp-y$8+hu2>uzXRc$} zi|pnrbsw6TN2&W!SFXnaWU^4H2T?X}Rvkj0co*g{8gf;sN00@-G8B(uSPLbfJ*%Xn zs8D~UCZYzf6iY(im{T7^Ba2JN(cGh|?*wXRq*yWJXQLO+R?)Pp=PgDB99hWhJ%BZnitvA zcN(D|WfaSY3_KaikGiqWD}cfn0}3LacPdc`oqHk`Mia+NMbN|kQc;vlYB9uO%B48k z$Xi~ff6f1!ehbvYRc@B|Ep+D`FS{k|WJ<1?sc6H05yJwWITyAW-R33fJ zFI7NA8>y@*y3TugW@s*Zr4`ZEFy*U+Hndf~%ILvUrB*=|HYl|!y2(9V4K=+jRYx@w zl&=Ol)JA2^Q5mkj1@fiOu8GVC=tyg!M{8B0HX6e{QwN=7#HovtQ9b17sIr#GI##NW z^8ZnZ1}HDz$O_G1+_FZ8{FK@-H{V&w1|1lqe2tJ3V{K#ff_B;jo%yY@O;P)z%4drv zyD7C9syIifb}0R;V$IPhj;{s!!Z&Y;4tA34(O2&7R%ig%w>6r|`#Wt=Y9ZCv7Tsm- z?11t!+iZuD3{rd4m07(bI>o);0o`EKbwYO;Yda!a7kyeMl)tj_IirFP73+-tQPu_7 z4N$BL3Sbwi#*N17=XfTn(s0#P^GK@bXKl`s-j36e&kC0yUpXn!ZwJO)+D zP;4xE*FgD#(UH~qmLcd9M>;My)k+$Va@wjyXs%ePPe3nAslJJ5l&$iGp?toIO+t|s z6`PEr*gu$pCIsj+rlPMYs%09wRbQ#okyV6B%s_nyDK-=3U#D0&8hS+~W+6NJ&e`Zc z?&LXWTQg}cTANS#=Aj7A!FS1lkcVEkvzaD_<5z9q<x&obLy|5DHxvbbK6ihF*8nrkltwHgV zq_wEkCTShoOFtfi&Qwy(>(KE!wB1YEh1ML9cB7%JcJ?5%87dKn?2@FtDAGy!_8}XN zWk0&OMX3kS=Ww-ygJ@2GVux~5q zMiO$M{T)MQ%ny#EKaAohkOjSHa&GEp)qD~qzgNCf=yig08a<JtI{jv z!I<|N{p>8gLBSuTw|e`KRK^pl@aIDO(56wIjh6@6p;_=W-_l=>Zc)|7Hk0)5>NG-|10KT+gJ z#eSjBe8z7yo^|&hl*SX2zo_B~#r~nzuNBL)K&n4QCGw&*1tcSspZ)uMsNx;P@}sGb zRiXfj>ZDjf)S<9c2xVQC3ZuyCDq94-WPQ$m5@=}uN-Bodrzy2K%DYoBpBIXiMB{iGUJ5<5Rjf2x?ktr-rE>TGko`cFErSv^%med(Jjp;%UdmC+?;(p8Wbt*I&+$h}Yv^`*5}M}LM%HP9wTQ*(5rtMXZ( z&AXIZ6V*656Rm15}-Lj}@B3 z%)=U`vSMzC9<5hC8)U*YYJ{dS7if&qd2^r%vSZfQ6m4g0v_-c)RiYWnA)g&u%k^lE zX5Lb)1@a8mk+wtwM<~@EWwBS#3T5OdUu(3C_Rm2gKs+~*#s%q+Eq14eRh14;q?ipz;a$v0EzuGV~86<_E zI!4ks^l6pKjz^EJ^vy%j3>T$NKu@S|BKojc3PWR-sl+7oCqX49qgf_Ooq|GkDs?I{ z@V?wMG?v(OG#|}CX`F+Z$b%6x964{6W}$HM%|@qrhCc@#;%v-C!&zC(LzkEh%ty~x zs>A|R|A!QTs!dhCh3GqDSS0$)>Uj~mc380}l*1nLVl=e4>RW<#GILsrc5yc>L!%2T zbvdfYXGEjzSv<IEu5Lkw(jfOEQ-$6IoqrZzHn3<%a z{L^#BbY`^l2)*HsdW^QDD)t1K^pKvS(X6eXp~bWH z8PAa$Z$rF5>whZWOY}EUdWE{BORrHUN0ohpQp+p$7HylTTGG)p+EoUsTS}?#kh#6| z9;NUk@dH}orCKtP8M|{?xv`$g_Ys|(tJo)GQ%kXI)Wk)x&nSx#?h9JQ?C~o)%@KS< z6F7qJx%v35*BsQxpwu7eBe9<-6a7N@a#Y`Ml+;7{{vcyl#r~r9wBmngOQd3XG{H2i zU_UA^`oUVx2u&oG57nL|@gQao!{tl3!y{IObVmd*-{adpV??p zhAw}RiX;DWk})d0RWd<;=~+vld)yx-(UulcDKwC`KT0F>K*h?SyoD4iixQek<@-MQ29erMKsu;Z&WEa#_F^(YR4+J3bGn5RYkA+N!5_&U6rkl zdYCCz10^vRG)LvHNEXPSrwKLDh3<;gLVm6)Q5%)DR;&)Xe_8d_MNzbadMKx^WQj(- zQ@;9W>NTkWDrF&Aq3wND)*4-VpjbmRcfCH>2A!fGYJ}#~?i-_4XQd`+Wk;25iY9VS zZPA+$m2HORQHvcKMeoxbnKJgYKz&(nw?uAlC3|$Ck<<#kW+%Nhie%p01}#Bt(NpGl z4yZ|2tQ(rdEYl0U@Rz!y%`vL4 z2l7o(iJoXXv0kWuAE`Hbz#elSG=iOUZ!|MjssEwE+`oNMttLwChi=fq`lDg=oj%Cu znm%IyDz!lxi0aV;4?+pMq`~Mi``ts(gq|wvi_+=&hoYUd7eCa4tL2Y&n=9WiG`r1#i@o4`ODHOFEAWcA5_?8n0qB?4_{Uc3;UaL}hkqHNX^i%|7M<%>dPD7zR9=MGqc zns`b}Q7SXMW#~FR!*Uc%uM&;=tyOFVO6D_GqP-;)TZJaIlvbm&%vIJP3w9pYB1491 zS%Ws1JA92DI>%v=QBAXLJ)99HD%%D1|n@85O6UZb4R=(pEH%CsNx` z**_|=9o?bT?LfWu>IinCIQB_)p#?(}+l^9K2kb$Gn3cw%(X^7is64Zbedr3UZa*^2 zkq)3?Jo7w=f^Vz7LueYGaTs;r`yN3#%%tOU^X*aD1hnJ4Vn>k`Gn7Qs@t2N1300V< z)MIE7=jAx^qy3#g0d*BiMvqR!;|g&s5G z`Heb^P%VFuMY78NMVYLH{-IWO%9m%MWSFgdd66;qkrBE`iF_zHQ~C0v7om#rhjRwU zD^fvJie9A<%AjmvG;WGY6hX1fhl--O!}^S3Xi68wilYyoC1bRLohcJ^fOb#<9YiHj z3aj2y$kSCSjZBLuwG3*({&`t6kk(la#j|5v9{u%Ii3(`U0>wuQ)Ild~$pLtGIZGuCg^y2n(RAiRwrCD&hDtN0*r8ezq~>S|eMAdXlfTPr ziHgyy*rQq6UUq4P^52$PqeHu-HYj+i%C<$*dDqDSU1X-v4$U|twMS){{X3!?lVVBhaHObLH%ht z-e}Wm#r{L~b)>%NF}-p>U~gfc9p!Dt(Kd#mP{w2fn!Z9Bjyji8i4n;6tIl5lN@pYqL_4FU zAheJXVkEMrj~Io%)sjY|ROY~AQ1^6w?pX9Ij}(l~an?dm3@gKN=(e*`$D^~PhN8f2 zicLU0`HYDuhH)zlrC(F(BoxkG+GO<5U7tGzO}3GyqA143Y3M)B?sPPup)>=XDWI}5 z(ZrF;7mgh1BW9tdjQg|EG)C+>xvBJ%bJ2sU(mYhRsLIYqiyahOfVT3EMg-zNZFgCS zI&gfEx%uLhx(F3`DMg_tJd;?Ae7P%@pvmmpFGX&QV9QV@SARLG$k~WSC%O77(Boif zB?@I^Uxj9-E8l8VD8FKB(0)(F)}nFrVe8N@R>Co;D&xm`bjeQnHlQ8+vff6Nz`5Uq zzAutukCy_Neh5Gzc z+0!VqwsZ#V=I=hvqH5G~4w>AL&ZG9Ux)jvRRrxNUUW}m^(HAGBUP3YSIhWB*?x-s$ zjvnMH`d&-AhEn+Zr0XcvUb=zGvR`r&)%H;A7Mk}?vD;`j*YXasqUGF0=JX}0=*es4 zOGD8Oqo21${ug zKCZx4b}TCeMi}g zq#RV)NuTipxJJajl1j*YIaiki>jAUzJDm2bDBpBd_${1DKC1! z?v@c6%s8D7#nU6@N8yZM1<(?D$AahtGn7KemiwbH^5`QKK{d;&=A!8Fcc~ca$4s?2 z3iOtY(Nua-6O_icEP)=y=m<)p`HVuPP{RPlN~3Y~aAlA~fK(Rw&|=G>Qdx?XM-@&< z6;R?0oqPTS%y5W3Uo&)s>st{y`6yNiUE+?ajAjp2tO}};PpXRU2I~l_p=(Q3Uv(6{ zOC@Tc3&hOP4rX}#h=U;()kH_R^J<|&%-3q8mh`)I(42uvt&2|gQmh^_Wu9Z1D|(vx zDCdoipaHsGUnQ(i96g*hD$LxcA!<8UC2UX(`w@*$u{Vk}MujRU)&w>0sWLb-)x9(M_pS(SwmnorWeQOVd$wd^FVK>n?ymFT9kvRT&y7jlhO>Ta}@USJRMJFi$Asz)ET7wz6I?L#K) zsqRPN?4cY$r;4e*gJ?=q=@2pwk`AK^tm%#*2S$>3G=t+yK&e$#%Te@&7MqAZMk!ws ziWn~)LpFSmmuDi zHCZ#=MC;1xsBWPHJej(UPE+$8RFs+9U354=B~npC+FBY~MSHo2)-P7e?SYlYco*;Vp%APzW5`W zI!3WiXq2DIW}^?^75j`5_DEk)v1dBcujmQA^0!5edVN{M$w+IU6>2Oi>l)I-G`o&tZIJ$98F=Nz@8LbJL#OkR8 zs_3hHB~ktjij_iZnSqu@Wq3kf1~q5Ts4SYyv%7LAl98!A+RALW0vc$fR8usYxtD9(HnZWN{H7vTq>h-ykS)Z^{cJas^~p4g=%OW{Z(~zo3l{^+5S+fIhy@RsTQcg z6{#kQ<+{~E+qveo(L2ViI;hT9#p(V+U8&Y+ zI_uhoXbtah+Ms5)l&=wrp^s>coan=vAbwEOr74=zTCzoX=xv*!_MCe=blP39=E#no zp#@ssN2x8*cSd`A)P$X}Rw%QA^0h`^|0vc5ZDsb~R?-`ByNjxf1JN<8n%beFmzA?U za;7J8L`&Fz>wwzu4yqFxHACu%{N^cNC)71aaz?2fVQ2J)d87+E!0$(PLBE)Z@#D;f z%6#{(sF=IthU(GBxuX%~B@Z;;OY%fV+4bm##<;13*Z&;dcU;Y19LI4~5?Ku+Nk#}| zB`YiY8d)JxQAi@n$j&Nz@14lV%u3l=MOm3;?>#bq#P9v;ACKqbbH@GNd%xdvKIeSD zU8n*%Sr0U}ujGkL_enib4zJb=<>5T(jkYJN7cb;MF5L&2lev4N2F!4M(L45H`XMJ5 z_2+|XMX8=ITEHHfANo!1(H|wAmIk2zSP}Z8iQEwlKyA3X2BIgtqd~}@S#&V+V?+%^ zlUu2D2+Chau^?1;xOy3ivP&rzjOy{d4MSI#s&qJ-!}uM7a+ps?px><(8;O3@ltPg+ z_Y}j>AwHo|Xc24D(P;Q@m5xDY$iK#-jXc8?j;{TY#-X&OYB3(UJ(nh+JDlYck@E+| zCZXzNVv|v2bH%2hP_C{Bv@Kh)smPtNa2ndq$Tl5SBFmhCY?;kwqUr8Bf=JYp961Wb zczgHoD@`BYUiIHs$I>I%-7F{57T8C0t z5w1sfI7>DlGrqTt$RjrcM3$ba7mXUuQt4)Nm|fKv^poS;f~w|Ky{)-1R;;lojBjQe z8lAfXi0+M4YzOMi-RPZYua6XmqSMviF4Uxlv>Vmiu2$&kLa9I1_Ar{sOnn4py;dv%eJ6GlxkW3Mh%T@;OhTWydXAyr z5&E2uqtuV8cLJGLQ`?iM5G_uj&U_1}Q8liGGw7DLS|lSsX7sbDU?u4sdPP=q9=-i5 zT|h3j(nT~jRj-kP$`+GS(dYJRdkHP^lP;q*pH-TMOqrX~(X|PRT|u8YmaAwrPg3=>Yt%mx0jNX&yK0)3srKc!wvh)l!J|;a!cNk+| zptmK|_9fb#rP5buS4HVH>N{0>g9@Ecy|?J_66qcCu~IMZQEOw>`+$mbR3Fit7}fiP zwy`GtjPkPg^aV{GsCwCGET808G_$ixzo8{O_xBwgCU5?M9tEqHpQ!sG#eShXO;ztd zRD${KH*z;p=^u2JOdME_?7C} z7#+T>7ADAv6>EOvd0jF^(HT+!RIRRhF+&IA6)T8L$f^sW7mP3F=!dE56-K*)q#|fm zZU%@9|5UFS+MB4?Esl2Z`B|V5i~^QuV}HpC1@S(tQ7z{45~wCQXh~$>Pq9)cl2NL3 zZoQL=*`OzULS>LsmRi`NBkWd{MV{O_u*=m$#mXVKnW|@xhCfrRJQ_v*UjcPsX0M1G zzN>8|w3xHb0hv&*GJ4CdbQLt=fMQiq<#wv)h%Po)X*E=^j$+l((ITo>1DzeEm=kK+ zSoNGy*CvY9LQN}x7c$u4{yWYg+@){+0$M}d6P z4N!>!QbT0?SN%0Y9~sRWqi@V~ZYZmT)C8GLlA5AClr}>(+5c^hX5Uw=13X7F5rU@uRBQxF;}jc(2H#ZM(a0`9J&!?= ztyMY}H7+TIqn686Zya*msMvUPmG%1sH0!cr6Ok`x`y@1PoHQBzV&0#E#*_U=pzVBb zQ<2{}X&QQ0K`o}EEn5_ufzGX#W}<8FRT_y*D2+m)e800$KgQ?TXzVD}n}evpgZ4C2FMH8L{!VNkN@tI6KRUu+NyMY2SJmPGx}78) zL?Ij0_7KV;w>^wrGhQ7*y|~AlfSxs!j-m-eR4);|f2?{*=xDZH_ZV_z20M-p#Hz&! zk;^Q6v8P?+iL)rC2iBzg;?u`j(c?p{)1PdE~(}p%+jAo*1}@ zs%=tf3OZ3=ua=6;nYS*X#^m0YQTyYHr6CJHwM|FKT=7@XEQ4ZK(SNMBuAwsI7T0sd ztabzWF^gxQk7PVIQ3hGYEfgK7*llD#S-OKZlk?w2KU=EaJrvqs%0%8=jaewFf^;7R z2B_@=55%fDMX|cbm@CBv?Jup;dg!C6Vy?)!pj02(Fn2dVci3-ii1ubG)(Fkv_!^_N zH5GG1lWR*&Q2B4_xheAC8*GLu_E2eaG@MbY1q$Nsu{)~AOxzO9V=Qik2J?JTYjlq_ zSQ|9tn(DPh*H{_0L(MIu_UHi5-5XFZvVsn1D%opCl*tv}3Eklv?2O8h-FTq)#icH& z+GwdOavCgkLyg<1m+mN?>#YYmFhuf12_2=LD4V>l7s_J&)*IOjle|#x-BKUalzG7$ z1;(o9zG(40mG(pKTopd3I6D}==w5Zj{7~D`Qh&5S{}=|K6jtT_=sSDD0Vq#?#Rj4P z#@In<=SscCU^JJpDG;@eQt1%%JvaYDW@HpYQCHSh!N`_9>tX2XG?flVTaW1z4?(T@ z>_?zpjFThLJTk^m6v=22h6<7uj6%VTb)(S&W`i*(r@GpXMK+tHa1?f1rQ=YZU($FK zLViC1J!Us*B6^#w7L!mM8P8BL4P^3 z7ov518jH|MvcAQr6X(?ubYq`hV<~!kP+EpOSRF4%@oUt}3RL=)v=X(jQ0XePro39L zMprp=)}R1Zm21(56Kb&zeIYwskBs;XHlQSqc_Yf+rFxrC9G^in@@k@bn^9x-ZDY_F z)^uA?$!RLxiVXA|i;T&Yx1r-L6x)vMTT468uTm=AiBkBc;}AcaXV``IzEjV;QI4au z2fc7o>0ac1L$Q6xhojn$UWY0ckLK`d2T(*4=^$EpRHcVd0J+LxRQaUZ9zpvKE0%yN zks%*N3FO6zXwm}JOG4p=6g!3@xL0!=9Su?26KDpr?nz`?RP|1wi>;*7C^}iCXVAev zQZjnkOKs002Q$Uap{~5fd35HBVi%AjtH6t>G8sh*`obPwD)Q$0y@UpImM)_MpVT4^ zm5J2ZnT`%}{#`*et}1pF@gvBFYiJuI+;x;cLa`g@b%{Rao^5k7UM70jm_6>Dm74sc= zkstg()ov^H6Ybq7{Xz?VtMor~jQR36nzlvygY3VmUJiQxS+T#!G{0j1kn3v2^5_Oi z(8j7d`n>2D|I>OtRJfgDM#zY7-xxJxWn+Tc-c>9=y30IhiXM%Z3ZS7M^crSp5BtRh zk>fg*7D7`WOXg@8pJZX=%KTddojs~pQPhV~uNdmZZbfl)o|T9NTGLhaEYTFQ3@g-} z>(?69&ZAffbc%ItNz}nlu~H}_PW4KoyR6D>&{{sVGN?57rESpwM&+_7n0&|%wPT;5 z9IB1%Q9wDVJZixGw+g5bnRG>T`IXvMLZeb72XyDSR2jV?JFJ3M{?n&h75!_YQb$xS zQ~gy#E_~Dc=dD4zSx?tMr%Nd2go-p!%o!bHB&>-ZF-O%xwv52F(e9~I9TdQKUKc&! zYIH#ztkj|&N;F8WXaRXseKdnJu>sm-DK$jZ$TAwCIAV>_PsT(ya{>0&#D)9^d(7ZiE47?wL%-2VOyh2AGK|R)~-@%Th!25YKNTe zsI)yQdQ~w43g;~DfP8oB{dPo$Crh1>Pbc-<85Jkn^g#aK)uIbJm?m{awH8U;P?)D) zqdW3xt5^@@!LGO`3SkA_6V>IK?uB}h`|wluK^H5jtrx2EPo;g3`6K$L-SjxUVrqM=MDy-SCbU;N2}8GE(6ed&X<9x5%bI-WK~DK z3`P?y6$?b`mq|lVl8f2~p`Hnf4MlaiQi4$rzK>yO%6z@;OvUTR4dNG2NL6=qS7;H^(848mANCGMb-E# z%5%tw8RtBj%8u6sG=+84MYM(WWeR%7x0Q-!Y*pzc^rpIEmyy|S#nO=74JjR!Ah*4O z{PIdy(Zu!Y?;5g6RK4pc?|H>;pc||WGLW^MbQ3ubl5QarKKt8f{b;qggFe#BT{P*M zbPugIkus4VtFbIph}Fq`v~sWX0FCGReTe)S{~n>6e3FlmeYWa7LHRlFpQ7vjs`m_y z=Tm!*k~>H*(DyFVOZ1Et!7J2fnDiR$P&+kw<3)Op%;+aW4px%xu z{fN97SwEp;jK!bP=(0M}FUXSfB^xb7U(q_gnQy4{8`b-cHg8ku59GmU_7l~9tylYn z`kO2EABxPq|BLKyDfR~yeu1&&veeV%E)%eBBf?MGx5DD1f~9T+C1yvsyuPFjA$3kO_Cg&C#_4sW38k zSG^*r7V}$C)cJ+pWifPu&!srp=qy>FkAqdu5;>C-TA}ysjaZ}Teu|Yq?nR`M$ds|E z6tW3a&!tfcqr44rd#%zks1)Uns7CK-h)keY0{B_W$jZ$4yhG%PB&?dhBdT3E4$rTmj z8?KK!bKW&Tr44G)5N)}vSR+)Tv|2Pq&)H*fL$N&-Yl7_A(Qb-1ERvd`&J|SJ9NlWG z{#u}^v}C8$3awfxwa%?KQ)+`w_^EAMWW{IR4mtjn+M{#a$1|Y2?WGPV zqOwXmqSx%0bV8Zc73++`FG?P0AM4L9r~%n`S7gCw-wn-YzUq#y9#LrzRGeJe6K&#m zAbO%Gj=mQ%sVVhF?|P`M7fSe}SRXWGk7C|vxQ)~oJtUXzhe|C_Js;!|F8QM6oV|Xi zH@Q}SG>msX04>Ru{E<6r!vJ*3Up)^*-|tF;(3oN>9gK`;Nr7ldHI)uQ2KGaP&~1)% zC_3~|3PuHwNyCtfi!>Z9=1HCqWX3o;0v+fkjYPX0R4)__N|(Y=i;^lGg|bE|HX1$S zdK`n=@okMoYq`$CQQS0ry5rDXR)6EslrY66pm*$>PDH`veUnfmXY6F;L8dqb&FL>i zpk-^Msc0s-)-;sBCpjIxCf}Ta8ZnR0L|3@BB2l$QQWP@fmkDQ~Dq)JvMh@GhIcQ~! zj%6;2JD}J+w3=&rKB~m0y8w;i=occdztSRf;)t{uy*;FQOOP?w$5K?1Ibs>wQdnA! zLI+DLP=2n8m8juDX%%|5Q2nh&nOvc3P>K#We$5ihG z3S(?PiO%-XYn(z0IO|TMyeri93@S&KnT-Ch;yQ~i*OJbmL9C?Cqk3dN7tlv$gNx`9 zr75Ua7sXPM6S=}A6w4D`m(h-iilw1()>1k$uOeMR^;)avtGT5&rE6$F8I@i~N#oSZ z4b+`0IRlj-FSv<(IiGK#8jLx&(FN8WchFcD#qQ>6xQ_H5iu|A!nW%VYDGS99REzuQ zij!gw(BLL&`w;zO_4f#!^;R#B(K+sAK0yVZOHXsf`s5jU*iU+nmIkTk7pTWm)q9CN zIPYJf`9Jh(uTe-P#oi!O-qBm+kR`oCwa|O?eUf_lfNZ#r_Yq}qMSVhc8PaDo?6yk3 zpc_W&IUDsaqSCMEgO&6RdH0aMqv5O~exP2QIX_W9?n3@TRi3Hdf9PX?^cx*blm4Lb zH>4co&a+~FQEh+4{-F_!VR@EI$!*kgUbL-->g7XoIC>-0lo`hu#UGYT(2ETcNp{dN z@-KdPDX1POq6^I#Xy;&-VELhbQLQ~5qW{&(_rNZb*5A|0BttC?^ivBV86hjkf zQ5?mbS3L`~udYfh(W(Or*%e~LsYLO zs>!@s3!QzgSZ%aDU8;kkcd2b%)RU)cUCs8vFwl83cJ7JXH(JsL^=Y(STJ5~TymVUMLF8p3GN3GJ<~ z7M;=1T8ep~1g?NC=nO~I6+LS%bwh=Us$Tcpdf`$JW2b4OFn4jBgq%l<$d^}!<o7% z6Q>r#(Oa&H5R}82I07|iuWcl%wp9v617}EKXj+bX8HF6?C^i~pl$6FG8;)Qsy2c(_ zI6CK|(s5`SS;lzOW2j0epmpr|PeiL)sdN&0-%^^4D)~xN5RdB{BGCRXI)bTa(0zS= z(@?-nl}<-p$l+$7SD&Pr=o&{AiLP@EMj;Q*rdg;i=fP}bD5%&RRPwoco{Oyb?B}7$ z%ro=R%ZjSE0G(zOU5NI!*J~_7#&=b3F{;Hb$`VxUkhBziXI-`|SM?NIj;^pHy8>Nf zZd{2TkfE$Xcgby6Bex*cTZ1OIQZH-K%yvtHVW#&C9SLTmUP zx@Z*3oy5&3)k?1$gC6>*#TGPVhgxjS6=zs1TFNK64Yg&bVLO`IUcKx<$G55NPBiC} z6o*QFQ`=qW;w))5TF_hCg9_c3_M$iX$FL7wV7%Io2G`ST#G^3og&aVO$-WMv+KUuB zgowKB(Av#2+OXE})`=q>ISYQm>nmTd$#% zie~cdUqTi8D0Ueoj#DfR73Mklbd+&VrB{&CDCsIXldgK#&^GSHT}PkUS-FAIPD&YQ z47*=9(bkGO(pxB=PvbUP$gAB!k61(8MIU-8b`PZ{Ntx*T6&*`fZs};n?xXd_>hA%X zY^T^mK z$=4{4zhaz7L5+AvZ;=O|_&c;LS$dBe*r@aa3gepoh@MrFKB3rKI;zj;QKVvDPKN-cMA8zwG#hJoS&^Kh%rS;x~Fqrtk-?sijyB z+BsLB#$WW9ndu+u#Hu`x792sz%mFMtf?gIkO#?@?9yJp}q??Y| z$cAmvd2*Gq=qF>79oocbQ4ZDVAlW06V5vN^zOEJ(P%uYT5xM-ZIc zS}26ir8Wv?cCLe_v0qXbH6v4SL7nI72Aq$bF@gVYpFW@c}OzI0NH=BOV#qb*QpG8A`o#X)L`oEgzup^Jre zEUi(AQi`=fHMT3(7KOG^i*~5@XqC1{_nZ|oprOoV9ZS2 zQ!fE%b6dp*B0EORL1^9sX)v-`tI|O9{Ip_2&_71oAQa4<@u6rrXJRnw&pnf2D4ZRF z;b;a&AA%|}Zj3;#WGy36Ri3a5MKifO5r)PNkVc__Xf#Sbta@WmUlYZ~qCqa|IUGeV zSLrxZ?xAAiQ3>Y82`Fo)ViVDI?#WIUAwzL8zlvj(DD7~<> z3SDKDx*8Suu6k>bE#Kf;w12C#4t-(tS&#DYB)|qVkC|>GvSKy130*j?(rDygOf5F& z#w?^5bbgTf+k#BF0=A+J-1~_|y&g;3&?2(+?Pvh&?j0zT+-E1c>@UTkXmYMysMb}* zcB4Dg+k=+!P47j6_bIjyecmYTN0D4J@n`_gfgC{d8NCmp$$M3L2$j35(!*#Z`x{5l zX3m2IWWs2B6n)_}643+RTM}BEUpj_vlv3N{D2)011iBfj*hw_LsA8wk1aunR=L%$yrool49qOKhF)FN1t!2^a6UxtZ@<9?aF6xE&lR+(qI4C7@?7>cH2jY0T}RDW3Ex0op%z)FWe@3oZYeDupmeU)hiE+e43E$luExj6 zid)xXD3yLe7E4r`jb`LXU(r_XdVE6z_=~^q zXeoKl5A>4#u%GB7W8E)g!)N**YVuUy(Qj0W+3ycZswd^3e_SblQL!QF`5#)!?+xWy zDShO#&x?W>ukxW3dNx8Y82OFS#Qf^T1a;=T&yOOE)t@QabwDbBUawK98S2O`Y(eDO zS+PRMnkU`Nkwsm_3Zr*_q$22Xl3El+w@xZn45j{+ilZ2=3JY{2Ku2YXiWiiu&_bSe zwni0hs$L1Sn9;E$8va=-g-o5*qBIKU9oe8#Efp(+QpYN0i}=q~3}uml+|drDakiI3 z{2aHz9(i((mq(ZPNc@)Cu)r%yC8+YpJv*^5^JlA-AroS39?~j6VB1Xd-LVx@aWV zz6&zmA=N`on0s7NNsgdCTEThW06mzdSVOdnbE6R|#u?Ta)wv?Mp}w9{6J)}u+!S?s zsJ6{e+yosa{@2xEkHjDCYQzs z8tu_{Mr8v^V5I4Q;=|PoKOYtp$~wLivL_4bjIQ^TJkYN%D(!-LbyVA~=swwDH{^6t z^|~YH0I3HWpR5+1= zP$Fv~AGDR6-xqz_FZm&>1!~(L)o|7E4M3Ne1N@PJl}!NZ!(PTf)FhAE4noa&mxEFG zVJQ%8D6JMlQ0XC35W379H58?yU~~lyLuqI@%GY175rUHW)JC8Ze1jv=cMWn zdSp*#z5$JBt$G`gX%%S`s>InIje2xdz0GJ4XHyLFy`cWKpxe(C+loqN>X>7ZPbHOZ zLsMAoY)A2fr5&i%d1)t_$@`5%WeQ5W&?fEy?MBB9(jK&$^La0tSX;4us1e`7e$*kKgaTRMU+k5-F>+|3Gb%lYme)}1 zd~WG|#V(+w?bXXg)REjG1(jfwN<|a5D|QK4va4|!#mA~N4TX?fq@zmHReA+QF?U}@ zMYxWxp`YxZUPsf|!@Gf|K2nPe6v$a}6NS>>Ep(b)joaugf8~A$_1me~UGyIr-aWK` zhLnl!uuGSP`0+i%eN=|siU+wdGqrt)e7T|?p_E{~+G7;Q%HauGNsFhb$W7IIhRQFJ zo+HzZ(hIa|rTTk`!ujRwSE!haVz1F9&Y?G`DI@S(^nsPqJG8(~dXHATQt1cu{krrK zO=fT86Iy7kUOwlRmQ(Bt+AvzNY_#oxVqej~8`3wFPTu|<)s9u{2P(@<_Y)nZ^cO0e zqa*kavCJ_1Mz*Pn{Xu8RV{_0TPqp}qjDl4955=$-nP-*MmXRwjYOq$HK|aKv92tzz zd{&>vXd!DM6ZE{M`pb`6W-4Zi(%9=OfV}yv%uws2QbAONE4dJQ!@9y8C9#ewj7l>; z7eQgHj*CiqB5u}c)htG|Kp91gqwiso1*+;KSt6$t)w4pqOXyXs(GKo!@<2k+ImWY+ zs4rP&DO85>r!?9%U8OcCg(tAepnUIC&lVXm3zS7Ztgh^G#X7nix>8D|_UI_NM|srI zNwErOHSe<`y2hwj358Ek%mG>ak}9JW%qmroBjasVRD8CM#SwWQm8zj1B~@A-`HxoH z8ffM<$qAhx^K?d=nGb5B1aHM^p)usU~A(f?ODHyP}frQa6;%z1Hri9A{k*v~Z|OJyC5kcs~wyCC_Z4_qsLs5j$J zf3)?4+73W}DD_9bPyi~)s|`fG2dds6w4d*HFgnpl3Pkqt>W{|(f)2Tem9;rfU` z-`UHbik`EpFb%Ee4%c+#LvA?(?F*Dvk?8tnDGGV{sB{*3!0L21G9ss#gANVU ztIb7mjBE2yf~zziJ!Id00h-P}#6onCb9@nM&|I;_Xv-VD+7eVek77$v>IR*O%TP#$ zN|&P^dK)s6O|| zHzGD74VzGj3Q{!M&)L2iRp--|M7~N!#^ayIqc$I(x*a<$0-dvOt(H(!4CZUa1iXB6t`=sM&KiB>V zRHTBA;3OI|Ql+O*epY{{(G2z>&Y#pBmXTlthIC-mE(6?@1Pxw%6HK(MuvN6jER(q(ymHbs2|t)eUw4$ z0s8Pry*xzMxXvG;m*i=Wk>?2Y`~;g7jU$a74Q zFXvSO^q2F>4B7JD3ZjNq#YWbgJjov($N}zIlt0hsyZ>ba-$___q%AqxXC3|#>9J4&~=WcHWVLD1$`8&i54;z*FrVFs%>rb z{DWe3&>7Cox+p(K;DXY<6sw17Ka}_*@t`qXR9YX!aeuf$Zj4d1A=<&3r4jN9lNzJ> z%ye$3Z$;H>f(ETq+oq^>X_YoZ?O1s?N0#+euLTN@Q9XCmr>bHt(K~XkR_M<;wP=lM zuv6Fu&FQ4lwx}IBdOOtLMrx0)@tGP>*->iS0kt@wGrJ=y|5m+pLblvt?TpgKD&~RG zQ5UqDr+T}h-hEWB8*0Y8?2a}wWA{Ky$woX;KIV#^DBW4=g`U+{i{5A?vxXPSU^eK3 zvcpu*8(lI{XdH+>xFsjU05{Q3c+EZQ{h1#$J8jZ4PI|j|+dG)aw$WJGuMqi~VD2KbL5vW;$VpCB9ne;St_pCG>U1HRm zflk$xW}+jUosnoW-%J$x#hg3~HM*>}v(Z!L^Et?l@ntUhc}%7APy}b^d{oj)u?47q zZ)qW_oFXkki(I6|=!lbAEJ3UEk6|gA&G)tpWqr_VEJqs`sB{H-lPax5e;TMB&4TW} zP;52&*H&7C&OKAxwJ4DpY#nlCO}8F(8jwgr_wDs4sIW=OH9gO7UIhDNwb+fiz=v;$?3v+hJM2dPCI8uMDEyHNS@itR>2 zhDdwRhR)JnbcEH(KD3goet&K$tAu!zWXEs( z)clUFqjdBzSg|W8h!Nx}$~>spHS~g+_&R#e-op)4kF|XU>XfP2O>{9*x`l?ZCwCil zWX8FJ_`y5FU6jFGdk@*Oy30g)%c(^cYD4bL$rY5$*!}>eZPAfFM5`DHAE7cX(qlB9 zmGu*p!^-O^@+4DuhAug%zvt*$W3_mJOqhjUBHvi)6*3*EdaqFrE5+WRP%@9V$ewHP z9b$22c#r%aOCM18h0;f~m9^R@WX^rx&nS-mz974sQa0MqUiH4BW9&?P%dO|5((mXV zJ4!!L40i;6BC8?#41S^fW{UlX9JoGyBiE6N{Xywbisc}y1ii*z)Rku&{^iyqv&^$b zF&Fk^@}e#+70ZW$xyp=CG`}HXjJ7>jsR?p!s?z)@eymDOQ3g410p#YTdS++~V_iXX zySPdVp||89=BQX3^->sh9WYGonm&V3Ex&Z zRFHMNJ=(yiR~~h7mMS0vS8YW!^^#gtLSNZ8bwDjypI1f^Q`MphTErDv71^7r)DcCJ zRaHapD@xVT5wg-6sG7H8PN)^{*BRwmuJ5BJO8u%>t=xK#q}s@cr;h8Of=3jqi^@Ee zT+jm6&h^lVym}2+)U2yw_0c>=!Um|^b*Ulxc}?%F5%T$|SYvdbYu^o-vodUgQVr^l z|6VyLm`}VJT0cUu=I9=CR10*2eAgZ2?Wa=yv(=yuQxt23HgF}kMiZXub=x5Oy((>s z`Yl$h9g1ZJYmfNBF@ph}>(ZffC4?J<(Cr6IF9if4$J)ZEDdQZQxkE&`!RYJ}8`L6=8xvpR%rlQnWJxiAo|8H(hWkR z7{>>r>4{PxGMlZoL(qj4QV^QWY(Erb6jZ%nREzO+7+S$!5e-Lw9x4`sUY(Riph3K& zktnN_jxQ9=+N07i6v1x%C{&;9Yc#6OXfXz@CaW5YCfrtOIGVz^HV(DRmd2xvN7dg1 zG>GqVB3j2)F$qoOSSF)}yA_*)%6*n1a&=dlis-;F4PCFJ*PV{SxtBBpRpDEmiI(x% zN22r)DGC{{lV%|wo?)Mj)|o3d2VFvQ(Le5H%tMyJI;#1(v2>L#Kv(vw?Lzdqieih9 z1-aQ`bdS5+OVDk0W|yK8Tmj3_c=Fxl=pb3-3gpLCwi3lM%CABT!&SN(bzr_+g9dPR zu0;;4Cf1?NjFaop@AlFLv;}QMz5Ud76Uuv3v1nu)FKtHSdPy;;Yen_E1=Vp^Y%B68 zBE_Pm%r4u|{MD+r9Ub8e+kuu<)@$rU&6xe-ko^#87Yeaaz1`>_bKV|woYl!*G>oU! z_M!cJGy9Qgpi1LWd7hd*fL>2m=|R-VK{|xykoz1)>&K{EgeNK`Hm9N znrBiHa%KC&$o~Rv&(I?h+UF9D21`)F531^ zrT0+q3&k=~A68je$gYZXAFUv_c!1tBt35>hS^GUgfAcB!7(HXJ^a)C1hJA`wG*sy` zRFL`dIeN&a@d9;cM0%N9%G&uAig1)(qqWPWH;6x1GQ360xf;jAozEwn@@wV{iJGWB>OMbkq!Aq4b+oa%?VZG z{W>FG=JT3p2)hflkZx)!|3gJt#neG}$YkoGR7M{cbcvay9@a|DvMoI=W?w-^E)i77v zj>u+!)CtYVRNKxd##r?{P;7Up3kn#ndR@_kXvMmr^?WnkbH%LD107{-@duhtixK9U&)qP)D1A*d=dCj(San71?( zd1R=UV04LH=V53IJNd(rC0RxYnwhBm2A+~8pzmbJ6Hya4z1k$SlaYEda_XbfDJT!W zcN&4bIU}Yb3!Yb+hB9`l-gH!&GhzlR#F}I#>eX3oBatz=R1|V0Bb$Zxusb~)6`7*a zIjA8y=3I1=`F9>_epvP9qnR<%0_4Dqy%4RqE-gZhdG>ZOO6IA9CFmx{ycCseskX~d zDYC=mXkn(>u0U@%|5l<#6}3vDg0db`mqc6;`qqO4N)qEdW*`_NJDy6s16=O`ABj#QNnppraA zbr3}rQ!j_mXU4U|sPSHv9zjnAN(so!Q>91Irap=#qHRsoUlPjcuF_*@J6G*-^uD8F zCs01tDJRj~xzefJdj2Xsjl7c7;tcXWC?%r{D^>3-I@C|^;~aXqRi)?AupH?E3M{XB z7m)*ZrczMrn<`C3U&x0pA!9zZ%c#Y7DGe15l+sbPf`9}>iHQed0lOvqwEZozChl* z^OvafI+eace(x1~jp9wDH>h4G=`C_SKI!WD zGkQ;U^95PZOE&UmKk+MaFQM2saB)!*!7l<(R3|2;J|i7|YwB zAMGR)G?RHeKU%$CF;g^x(gG-clVpaR*s&{!?x!kN2z8;<997}FDU2MsGK-*nT+2n# z2<|!*L(AD`Dvqx3jx12&e2Q73kok&Pp@-WgYg9EzDuEi12bDyX*^4QK3hq(c(&#s< zaT}EBr&t-Z!d7i<(LVn2tt`6SS1~)3(pUA$p)iiw9+l+GFOQymQLF;$vq|+TqDCJS z<1y)=wqqp+)Sf#?mC?z@s#gUCa->YTK{+*5kDtvB`pr&UHRLc!vFfNh*G~;pvzp|D z#ubyC(ZS+sQ4@JF7S=+$zv(q^Y--NlKY*)3dhwd{|yP^skRazez zad)BtDr%*A4bdMP#Tp?i_EQ?8(VRJMh@UVpG(lzUq^4+gidr;7R*a*~(NoUd7APZ7 z_1sZ7>)w{gmlb*|6ixQi8m(qjY=i!tk=ml&e^jp>+Cbjd9u?y=HK5;IT^&$7S3pN} zp4aGvqR3S{qxtNid7#OhFI|u$cOtr?;797E8>-~3Sa)>onPNTAF0MvTRQrx%JyB== z9;Fuw3s8T(QKKxCdLc{3?>=ZA`^4Vp7JoI;7rk$#SU=Rcs01p3B3=#i*vXY~?_-tj)dP->7$N1?_Cq|qpf zjC>3#dse-SMN`Q)!;v}X={WS@f?jt#D#Sha2`Fx#G!gA!oiGUvC5NAk#;sR>Q&8WY zQUsdGPRLZ`-Cp&kA=lf5l?MKCLsWcw-;QKv*ENUxu z5Uu3XJ%l1|ONUVsdk#m?iOp(}fXs$UN6}!evP5*Cjg*AiumV1Y4%Tb|JT(wR90BK9^EZ zv%FF&nwKG6LIqAsmyv5%DGhn@F4NJJ2GSLDX1iYFDw;(ebPctrrPAxU_3BDD(15!t z%|PwnNjFjADCrimXPs~xed7JzK^-}t@1i*7^LwZqBXA}vvp}z#g|@a->3#I#g!BOI zWdwPMTJftzkIZ^`7`8jSS_BT^Npkzs4=7HOJu~j_6qIJ zQrp+)<0-}7puhIgTXbitO5dSn9P@kBbh=7EplzwrM>L5!`4g&1-uD^x^jGW)TFh4a}I zt*2fAbc6S1hNh9j6-4ID?1fO~c*z`Xe;^e`os3kk2pY&)Tom1B&MSuckCuv~S#=}} zRI!L!SfWv%bW~O-e}YP_(Uomd31pQcl|)tD)S?v1(?=?e`ms*6K@0DzUKwOf{%?!s zotMg@rV)}IGB9?QL$Qop_UIkI>{uR^xv$a+$QD&ZKc+~P&<@rt4#Y_blhc2kyE2$o;MSkFl9$Xn}zD7D+(lQ z>4skO-nyeb4$!wl6=t1Y{?g$*d_U)tV%l4{%B1Nz1jfOt(i*w(Yg>R07W}V15tZcB7;y7 z&alC#IqSi`6J&0y(Ytff z8kEhB;#%YvsCTpu4P`B~9+~}7FB{M&3uz-7Q(oGHPBRuqquw1A+l)G}4v0a|*;U{7(wTMOYW~#+Dbbz}j+tEzMk{zhUHUlRZXI9&T z+IlIr7X`A~*@r?o|MsIULKiIBG&KCy*T@%}I2S?B*2my(yhWfy}07P+itI$!HVv z%vn^A*g13}N%hVn$H&qIw1AQDB5J%zuaSZV*HbJNbvz?oLKTwL-(@t8PbdvtZl%(6 zG^)Bvub?~JN4|fkDl?N@M{{U<0|hg#Wgs3`HQYqU8KrKa%It&OM&_K8caYyb z=`IS$qh9Wz3A0o$6U|<%(kyf@U9tP<(gejGpiboS57816wS9zovorq~U2LruPmpJ* zK7*&|$wS4Sp@!ULevZN_OE1u#P3rF@IuI+pLLU=U`WodWt9pYLQ130;`$&3+yk|@A zQ97%g4`|eF=_4{@#`%OYnD;-U7Gy?W(5{KJ>v{tE*mdw5^LuEzszHidmxL^cpkOP-sv`@=jT-12*S-^q;CJzzQRU52O=Qo$b1n3U(Y7`!NA_9=UHL23MO*ki zbQk0>R#t&uM~!fjByKT=y%ZLLbVkr3q0 zI-osrI;j2(sQYxqI-oqP_dBA~{dM%6(0k_9&gfH|T6myE97`9}>ZD4$qTr8e+YL2m z1nG_%Q?Cb_O4jFzy0CZH6BXfX?}e%^lzO8!vsBLuy>eHq54yzYAz+HXO|&&j~>%%19&7)R!t9i3a;i zp{O8ZI~#~Wt2mZXs53jqqmk)gX$+dsP4&j2%_tnb-LGE8p;pGycofTuY69xOTsslv z;rf__o^k$7M*rB0oPyr6E{i~=xd%NJ)n205G}L&7G#%|E8=ip%FiXxvwfN2>(ZxWu zjY2*6TxOvU^%R?p8t^>d98{IDcrNqXc*6X_MxWL72A(e`Hl1eG;^!^agbORZ(b%t)D_l#z#DCmSrZ=om4ReBqhNml6{ zbdYy`7gcYrdiRibCFwp|yH83(b*4!Va%0S#4^j9!wS9z^Y?B_NV7D(^*?mVNqUc-KTt0p&?a`gKBDha75jwVgiD{%YR0B7D3JBSS2XN|V&9M% zdC7OQdAalh6=Br-iTYMiyIg>dk zuCJ6wr^)AIDJd^a(#5oSh7av&#SZnav+y)h(5B1(g-yerFxA~Fn3QARJO9z6oprm z_|kw+X|4zxG?V{*#}-XzSFJgU;0|bku0NJqq6d6}c4)J^j@AkdI-yu=6y02EgQ9** z_GmyG$pOt^=5$26*hg=RdhYuZs-~Jsx#VBOr_mX-UTY{fv(WDC#u1i-3x6vB=tr!XGwjK zAJ1$1qBkk(#RXN&P-#E3kJ+j}YO+nS0my?LDpxd`b-+NhEK)Hyl!vQ$5Sp8)*kBaT z{W}D`(!4yZ7)kB zQ9thPQ7DS6&j&3Yrr2ndm7sdQ=)qjY{E!v(#vuN~0mE2SuAgG#kjG%f#-kjr*a>J3 z_rgSE>910M6xl|xNyw2sl*uTNd2kAqkr!k8 zEEF56*E}0d=KKYqzjvfLXv#HdZf?w4nuj)Vt<6WJLe$Fw^t`-E7ow@o(jqi)fV3Dr zT&j9Y(D(d`Ek%u8q(D@xwn~?wvaBJNBLg#g5b`HSUx8*1)p1v%#?08O(9Gv5U5(zd zR}hRUbLFf-&-tW7&?RGmCoo&kOXk6?sHKZqY(pnzt8_c6 zMb00STY5>K(GKL&NG)PfA@0jK^nm@?ov2BF#daYZ6pwZ>dMBVNx%+>}XO&9#pbS50 zFWSjY);=_*nOf{eJ(fua5I@2-97OqAs6`@L9w8kAs@PrhoBa76%4wt)_fa`AfHd^Jj_N%? zRT5P1A$rAca~`2>WZaLDHMzhORPeZBPbGaL?h$kBGon86(sOjxQT@C?Dbo~7M@~JZ zmuMX;saMF-T|H*xmNK8dMuR)3?HiQQN_va@+N<;(TJczIGtoc(pPA6m>A%to`x^>fguTRLu@XlZa;#quH#e!Z3td9gQ< z9~o*%1#;`L+Au==EXGg}`yOxEK2X{jeRFpNn3A(*lZTW*mKC?%u zUQx6>RxvY_)J7_XJeZ}5qk3HVCD3iwCnb>&SwkuG{*ihyM{^dcv^09g+OP~-T3MxK z(Jsbn3zWvu%ArHFD33ZBsh%Zj%?iB&`p9{yh$8B$v=S=K{%U39#(sPil+L#ys-iD^ zM%B3sfiYokJLiO?{tjX=mM*QI;bmur@bx;C+De$*7sGt z`lwDL#jKGnqf-OqutcQ|QSo0=BlKa6N*f~+#;zu4owd{yov={7X6Ws1^=E_DmsZRc zZDQ}ZIkIF;&;pemqIxY+MRI*RG_|$V3Wbm*wMI@06l;U{VwAxi1-z9UP!;B9M>K&w z$hIi@jY`|0vV~RJ9yxMHbwEjHRoW3vuCJIAir^h}Lcw!X+8H$~E_FdI@2eLB@)@jp zUC~9d?{3JZf#i(3bH{f_?d?^s2O46KdZK3BwY|{Nl4{W#%|v}r0P2e_byYnVv}>GV z{ZLiTOMmp4-HZV!+#tE4JC~$^sN`YE4UJ?sV-RxY4&}c{@p;F{I|TJ4=W$09c%>f5 zn>B_fD$Xb4g^n?o3`I$dT;AwM9SB!;v5P$O!ZwBhpCpqO3Fuy&tAte9-Gt zsy7;iup073&E6{Jhfa{IjzMF#N@LNmJ?do~DwrvaM*(rnbJu1W(? z%1CJrn#fMWT-4fE_2!}JS<-xT;D)pSnQxI6qS0g=i_mNC?!~A=J821uptFrIk^q5X^pD^NPGc_sQ%M6p%q5NBvLa$F?^Bi{|u8WiwL3PI&Y zt3@a}jlxhwyx!YdbcPW)9NnUq2-LTZVv*<*`)2emUA=5Ux3~wlqC$V9ZOECKZaeB(O^QKZ%+z)V@+vCDqQ@hp zIMnHuv=dG0rWU(UT##b%=y*jb0X-&P+Kn!--r0kGR#xd=)Viy*4;AA4?MHq1v<@H- z&g4PVqPdia!d|MsL+DDjVoB)K7wIrsPA+`}C37bqMdl&WF%-_Xe~+W?^l}0TH&-@j8iRw3yUZE|A)k_BY!ru04wDyT&Z_vUX z(pwZ+RxRG4AKV|A=-~w&_dgWBQhJZxn5e}E)QaazA5k#Rh(4hYJ*CemhjaA>^<1kK zU(o|H&~GR^MzQaxD98ALzMoX=CmKht_X{nptymUH9Im#%(FF4KKd8wlmHtKRX!{TK zHdfng)c1(qZw~s!NSH@chtG~ms+SjS<2SMSP}%w_&5!&THwqv}*1|^UDmi>X^n0e- z7D8((DQ1jZ?kiRp&0~kM2nsHswkF8>pN?UQdi_?tqR6P9WQJC;0xpJ@kfRqzrraqd zkR`k8CDHQ<>aP?EWxkV|qPGX7W@r?5g$=S~-D``+u@Y^LLb~V}EzlCip_XXtAhobVab$h1 z&_ebrTBB{OHQS&;PgQD<_Atsjps@auBdVDrwMAnVt8F_J%&Mb(uFO^1A-5hGPe&B! zr&1@hElp>#6B@rxvCb&OSS`As#au526wQ;}uBfiFV%^YPu1;rE)JQG5BmSI%p$8g8 zp4by*l0WxC8_5rPqjF<(v_9x3<5geOx18jH;?kskDD;%nAAPE$76Z_VpNhGn=6ok= zAbL-J<%agPQRyJ$uu~e0I&-fML8iI+AF?J}_dwU!yYobK7_YogV@9N*xv~0^H!8;% zHVlocucHk|-}oCGBTzc8Y9vbIx%nt$oT8Wya$~(U8ig`i_@WK&k{{Z_c^-qjb9VsI z)J`fLhiq-6@hF;Sg%eOU#=40paDwEIT5~l`LYaeAZ!+3gNFa-y3$Rt z1!!SEwOxoD*pFI-5@)J(F}fG17E4en8S+w8itld+q7sZl%g|C*n#)lOd$kBc{25`x z3iOY6xe^V%ta__Z&GFJ|RC$u>1*2KqWoyt?J1GQpXTA(YIb6?S$goCQi`xCwYYs=% z`IT=33Sc~lL=(|EbnQR&w;nyUTz^7tvAj*h^?O*{cSQqiv7irqqE7?p3MJlx55a>cWiyQmj;<2|%w zgmfQS6jEs#s@qwy2WYmf^bnn84t<0Mw$w2mqi@WnPmuQ>#h#)i)79b`y2d+yjvA3& zzd+r|ZPSrOmP%iuQ_hOLLPx5rzYH|LrAl9;w0^mCZ>3Av6`z0auIPQ|_;KZAPyiZ%^V>>JwnO!dB_{j3px zplw_cKXYS`rC(?}=O7EsUX()+MLE3?#JIppafl}CoEs%MGDG9pz#yZICxd>@P%lo%jx4AXGA$%^My>cf zx*)$Pk^xm@^y!Ms-PK<=)a||GjGi+GbVtTXs@DUJkCJ+#cT1#R=utnZHwyYF^+D!! zrM{>xXV(QKd{EE*(4WGJ^+#XF=@qnRMK`4hXy$Xh z--*aLM{WI4SH5j93GLxY@nmEgq|zzqXentby8Ks~hE86WrlVqvi8D|~KBJjvSbp^~ z3l-sg%tk36qyS{wTcvZ*G47+e=%uYn=b=a3zw=QSuFeH0tfpS`LS*+`rHfD?^V?$7 zxQXg5L5DvnwiLZ!H5P~}F_tVta~K_$qaR^<%|R%ok+cGZq)98$T>c8zD)fnrVl{Ge zRB13eN-nG1Up%YC|`zRhtNXmC82<-YI_(Za!npV(TpWW z(e6&FcMJ_;Z}T`R$U5Kzx_?^rPNK9$>g5!wR!gO)(Q(%MXOQI}=`8YR9gvKi8Bfol zNUoCeDE5SO0Szi4T|@`GRqqm7#wePCQW8@onTWR`u?n!{=1*F3LP4-9u)3rTb`SvXqA0Jk;U= z${V2ALv(}VK0@4_hQ}yvnvU@VWnGh=A}b%&dxqXQO3%?Da>5s=k(27Bqw4#lm#7&# z!mrTar#kl;D5#)fuThDYYWoK9XDSVEk!xk?9g1KLmWlc@PydIOa|gUfQH(SnQ08aF zKBBYCji1mD^4-rUXrf|YP~F+;?<@Kitk?1l1v2t~M;FNeexUols`nEWWo`cp&2ds` z7J5Q{^&91Dr_w)Y;a8RZMXNb$|4>FT#j??8AH{Nz4bOn`Y>_VhQ)%8@byhF=P((MC z=0}dK{0pE1H6^3mn5B9th=v48h0yyR>ctqfW0We4F8!5?pkmF{p9z}0UG+?n38QFH zl+GP$hUU^sF_cBdSR6IveUw1!`>M1gYQ`8=3e~rkcr@c<9;JGv(P@rW2Dv^_X;~C^ zK&2KafjhYzit$p6AI12XbX7e|RE%7?0*YmCq#{aquhL5BB-dYM^nJBd1y#3Hi>kR-b@Ou+YH4b8#Mf)dbUM5 z%-GG59c#oEXh3_lZHcB$P^le?;x)HI`B;OsMybqdZO|6RD|=+ZvwR0+cT&ALqQzM% zZHpd9>bULDGC#%IqpG`9uLBxNe%}$5;$Cn<@qBKb&_U+1&d7m%nl9+nZIv2O2KjSW z)MAxl-HSY4*tfbgP6u=zskAlfi zCZVo;D}ORNT2J++pfOxwQ;}V&V$+bv54D|+X5Lh62J-qP%|wUisB{*pnNP9VDEhh- zfb5>DbPl>$Og+y?UJ2VLO36WNyVNNPtiH?3#+f`^9Biw3Kl@T)-^(Nm~gDSsM zECgjU`h=oVb)+z4!*#zFy{xHNIP&ERi$GtWs5BB~F@vo`2YFVx9#u$`HlQH(cs8OQ z?7c>zP-fF;)PgmM^IayhaN>IIS0qkQ+Dl-qb*HT z?*tkeFP%j7*s(csBC%Z9P(pF={$<(e^$F7=^JtP z$Ym}PH4RhEOX#<^%2UvCOT{ju**uH8f;Mu+T+JNtN zm#Du~WYb6WZXstr>)Yr$dsKH&$73qJn_DkOv3tmSg4*6k=3H%Q=s8*c1N8d1^bk$v z9(aTv4w4?D7d+j0f_7C?>?sN&yM2a&$1C<6g^pD(FOVtgm~>R*o?M>@*ACF zukufBJ2EXRB0(5g{+iUre!lsM&D!k{`M87b^-N z^UJDdgvv8}7et#*ONCGrBdRg7?WDGa(fV>KErRxcmQ0W_&!A1wN@lpCXbB^m8R|#Y zPz*VAkcy-GwbWk;bT(7aIrBdj49?2Yq@)yBMqk^%Dl|lBD@?RkO#AHYos1m)D zLl^7l80AqpKgBH3IS!VRLRM&L8iea*}18-IZ9{c z(;_$aN2M*%)lzCmJ_0S(Sp%n^-ZhodbrOP1Op zFIKGW(Pwh94#-4?|Xnq-kx?17^+5X{sf8!< zIw*OeK8$8VQR%aiH#*NuGYpw=e+);RjinLDZMQTMMRG5ULRD@`K4>sw(`fX;T`^xY zU0-A{_@Tu^RXPSmQ#uxPBM%>kM)7HlN9BG>6VN)w=ZWY+Va5DWS7zWz=rQ{clhIlF zn}U{%Q*0_KeOR$+sNpGTI@(ZGr87_xYnGYFoE6tBG~=@B%|_SB3j&a>tuzN!EiTPP zVceJV(B6*HeAJM8e*tn}owX4C;+!r*Ib=19(JiuuCFl)z%2H&@sxA=S{Hf1!8M2(J z(&ea-qZEWTjg(fPL{DiY>KiVtLTAX5R-?l-hvr41URMv}| zP@0QMH=}V?RJsL)GV5+d!Dt)GW>nsetjQ>2P=D60J91+@_lQMX{iHaQ&_gYDqF+3J z-Gvq%REv1Tk1h=fXvssxcB5%?r9CK~F>x=lB1_+g>>Eh?(KW8H1L$5MwK#}26;){> zYSdh@LnyM7l!W5hA3ThXG2S0R=D$^X6ip-BJBDhKJsd}OYN*}`)P9soPonp%J5Hew ztOHM@%s0{*lx?Qcv#1jNC8Idz%X6qE$32f~p$jOP8TKODQ$V_eR?d@B&{p#G%jg?- zz!kKK*K!rDGLo(#2kwCDXkP)vZXkE=l$&UFij;~Pkm21z7f$L`-9}4hD0TSeXt2GMh1_1xnh4%Z|<$X$dvr~A8No@l8t8bK6217ddZ{7 z)n_=$i@Z=iw4LbaK(jnTeTy{f`!)<&raddv)F zf_|7OW{NH`#ui1BdMIXwTJnC2A>#*%6-RlP_e-D@_CrgeoKV#(g*Gpg%#owH`YVlM z8MDivKioZK(WR=A1&U{dQ4U@4lFB1D)?Suq0V7fck-Gzk(iZC&Y@hjL)K$IKDDsQc1})&P2-qXX z)`~fxraaSeMCZ&EYm2tFSI_NGcQT{)$c@ju1G+w6>WF4DsyLyL8d4_|Z>wW;Mnzw% zUKccev}8cxiBeaT87g%{?HCiCQ3x}8cU1M2`s;y4+*Q4vs4gqMUdW#{PH&VREA>Ht zjntwqio77Xpu|0TE&b5T(Tep)_GDTEkSF<&D=NcEejp04Qp^o4V&or$Zu9yEqv}Q~ z9fFRLHM^sgtcpBPAo4`7SZjEpzhoXmQOjkDc_YupYC8-qVD&y6J#$yR5y*@zawNLV z85)KDU02KpjU#s)jgE9z%ollNN`A=BO1+FhpI$3A7F~NOjYH|&=i^Z-S@;B0i}7G0 zim_DB{>Y3SyGf|f0o9v~eEaK6PC={5=B6S?RwvU?`*!MOI-1U1HUs4eQ0Yt*NES3J zw;p@Uv(alZ)c|DdBh5jT0(7*w$capU9%{r0JRdz`q+WoM*kM_S&fZXL5o+(Nwu@0o z_UMTIuLtVbyw z72AL&GtX>9@y`^CLLCk$7L8t&RcsSFS69c_jPA0(u?1yMleQxNa;mot4L+yXcErOn zLkybMNZNrqS5#>%GB9_?p+shgooLcG#de|jbEJ6GVY|+A0*Yt7wHsx%&}-R)UU9wb zMfn-I_Muyx$^FQNmCXUvl`G;PiodU(6VbL}(jnA^Tq+5*;o3NiHgE?VLC={rj-pA7 zddJZI={m-7G?n@21lr3PI*HzHQt2tw=dN0u&aF2@I)hG;9iBxu8C8-|tNzkC)PPy& zJgU=6^)8@$e7+Y^3BCn%3H^yzy%e;wpJJC$-pPtxL6c3StH|+#UduJKvW|MWj^>gD z-9WFHw{D{2%%-Wx)KUH2Lg}{^yNw#NZoGr?@09MM37n04sN^E)KFU*4N<&%fn>|4O zQHni8X6!CJLJ5rgk5P)Z>ODcRCsprhuK0c2GxTh)V$YGOn_9d;^|(LMQ5Ji+FOl^> zmA*nBo2xVf8F?%A8rc+9FKhC|)I7E7n+_`o?pdRc& zeMIYEdHg8V^-2hv~E@U8R@Jy@rD+2}SasvJ~?Gn7X|fzS9gs+SkFUaxxjkTvsL ze&qX0r3FydYRL#KWLL5v>ddHD2$jxI%os&K)Hx`Ode>JkMbJ)uNnnDam{Uwq9>%Mp zXmWkY3@v6KxEQ+4h+Z6}lVg@ZMU=Q2N}@U4q*BO{`_dd0eJGViFDgl8kTElRS@dS0 zUX=wZ!8S#?t$qFsz`m2HNgA?l-fF>QoO!SD3p7lGpasPu`bAnOwfR?v%2ew{uPzF zp-#**&M1(*s_tkrV|x#Df?TR6TEZFcgCl97K9+Rln#Fq+5t8-mVr#quAP`$X{0Jdv@39PJmHMI!oFPAC#XUU+4az5tMQwtmacI1|G#&*qyG%fnf9Yrw(GBief0U2is7WZf zqcj zojK?ev(;SGe3nes~KqZPJ_EkMON8w=6Kwu&u67dz;SxwMak%SUK!Q^L9ylP;XwrUR051)%#F^Q!3q$E(b~n z&}m-PK@>rznuy-<+~p8ze?iAcLhG524x=3I1lL`b=euzj}~Xq27ASl(MfWtbEp<$_IY%ReEb3`!rJsA3ghoa zTtYQJsx$?iVGVm3Ek38%74&|MT3ki1_@CFVp@2@RcOAKN58gmeSl!)3A(@J$qPpZ} zw@_Jf$J;2(Ri$^(WyYMlsQekl?jfV5(*0cVj?&O6Ryz++{%GkT8p{60quhF>b==2j zeGA2&piU9$`6(*>N3mxpn=IowTH&wQ3)E+~l%5;ouaLY%X#*5{h1Lz0GLRqn^J|pS zPq8=X5Hr|Y)T*0G-=U{ZRho$`STX;HJ~}D(9_?XP`+x#t)b=AfeO~&6_)p;spHT(w z&@agBg-XAoSGT2as8$j6{2kq4<^KbnB8U5l`k#<~p?lm5S?J1Xwf&8zT$cWzQH+Uy z(XTkQ_=nn&HD{vnq$%oGS}KZCSE_{>8eu9GL)PeA?CGsViF>Wl|v(W7w50=+IPl|xUtf6JpdGabVc zZK$bO1yqkaxgzSw&PgTomRC?2xsnA{L0f&Ks%QoG0zYo_nZOuZ9X)0r*a~%F6;lIQ zvKv(sz2L5`g)ZikYNKDw>~+v4*3SH}z^6r+`m2W?v-Ycx`jJIiBPXt~251k@0~(^e zjJAzXb?$}6s1ZA8O;FZ5sVQ1@N1seHbeG@x*&u&*2W?T`8&Y$Wk2$^ty1^*W5;Z+5 z*`XcW)2(u~MQV+%Rg~JG-OhR~_Gsu-#T<~+0KEc7o{buBMLgscV?S!ItD%KgL%#gaEiOe4c6v%bo6}kOVtQ&IesF*WK7^YZv^oR_v z2Z}l^^+Yb0q+TfKp<47tHyxxtXe1+7UliC{=g$R==&M)N4;3J@?2j6dy$(R_=Bl16 zTArxbKvcJy^+f^51BvdY+>P<#*&s91F89&iG znu_xDSG{S-f;(V3%Jfye8K`^#X(p=9+HV%>!Q4F?jgM7n0J1Pr=^S*EdvGqg#VTPQ zx}B_g^HEFgyanhCr3;ZUuWAwcd{u21qdSbnOVAXa`z=MD_f#(sUE#RP5MN$1EJr3h z?F&L)$Dn=eN9;hUjI6OJn{{X$npR7(o#^dF z#de_@JiUoW4vfGFXh#{9?w0h8xQ74aJw$)rlJ+8R)QTG>&lsb<9@jNfgE1 ze+s?hYCDbU>{E*~s0`!9S(LI|v1G)fO~W}fqk}%1^QZ&Y=LK}+fa+aDg}90?p@HnN zq@dpmrOW7iS=GCO#vfHLSJA1tD!qofaaOOR>f}5((7-;5-9*(G$y1Sa1NCwXZLg(z zw^7Ou=?;3vIC>ZL2$t@l@1fFtwA@;4)6h3oYY$LG)=Cf2MRJNqs3rOOW0Xwx^8~p+ zk)ERFoXKbC`5);y3bT@4pyQ@$n~th7x4%TyODXmWy-iju0~w!`UZXdAq&Fz>xO#bu zzR>eKH2;T6Gf@=v{zK`#)!%!R$5ycqD5t(+ACVca?-R=6dC+In{F>^0K@Z56zM?|x zMt(zMcPsWCt+0`PpcXtM|A{>K6n>$;-1AxJAS;#MD3xsG4?4zJ{TJEn($W5*YV?wg zN-}=upqK0z=h0>6V?08!yeOP+DCR>o_&oBX7{LD)LP|7e#kj3!5QhuG3;@JY!sO)R?{e63A$gT9icQ z?9-J(uFN3jD2%mmX%x*T%`K#FFGyukG8wrA+I>;=%Aum{wvM`hJ(ggSMR8lzxV z_f62(bBZ-Z^SCdYp@Ym3HYkhpY>Tclt29S8e1a{IDcMR(rH%P6}x=B)N z6mvpqgLZPC+ar%L>e&Icj*}db%XHOii{|irvmF}Db=n@)s3LVhL%CNwBBw%%Iia=u z)yhuj6Kj^vDAiN-x}e^fk^yyPwC#$Vc<0^FWo8IxWXZhN9rd(Pe?3sbLAC9P4qjBf zUg!>4W^eSA)oCBphAXTuy3KiUK@G@D`yo^A!Tum^$c#1V zcyx)(cmmqQvzm!$#VN@jeP%r|2^sT#C! zrA26F9hEN5)hB5QT4GRtOVKgL=Rh=Ei*Ca*^x>+s92FyL4ML4L_bbph&htuSG)u2w z6>{ZltVUJK=(xeC=>o;ppq1nsA*gW=wGBnPcnTDTcJleIMSnSy;fOzZVTeG*_$78E zvS^~%Iy7jw>a9m{k7BmU@%VGGLBSuM6A zS7y#_Xb+$McJ$v3^&EpXRaA=|D8g52NZIUdb6Q7i#X z*EhVEKTz}`#qhD%q9z9NwE}+%SrWer_&e|okKTAqMXZa1%WfZ{7c?AVBUtUEi z=F&Bk!F#)&TW^W_yMgxCRNI^A5c69qD$C4y3$103^foH`TP^OOtVQbYE^_Ul*gZ6s zy`B4rFNPY@Q2s;G12l=%^Fy?vlVXq1GCq&TXo#bZ_5=l!3p_;wjaB*#9hs@N&(U9I z&KGFH5-AS-~e%X|MDdxiJ%eK{v?Zz9Ivk{x{@6?)V**NLB0y^5E|I zi5~bX_6zwt=@?n4K4<(lnzLQ{gF14p{Y9I2RsYcSr;24GTfUQ$gKQeB=RBHXd=i)k z^P*>5o%zs2-dlcDkU6gaN+CBhLRU&l1<`jt=|ZR^J8{Nn8~03Mw3$1g2wGKAF%$Hm zgk*{;yj0twXpfa*d@bE)kU_CxXfo%eIEpMQl|YuP^h%$noiDdfj0B)mVUxE=~fQE7d2k*wYtS=Evnpuv-*hNz0I>NP@{T;q*Vfe^)-pn};Fe*)1bAD>4v zl%LmUgDynqDzQa;jlj34HTv{Tu{P+#OZ8`u z+H+1F(8%YKBRa?aOk1?AwPNkiBC@LX=r*}Z2lTOlN;@LsYii+yI&4&|6Y6_f>Wu#5 ziCGtPZkKv{oO+7(^P&HvD#s){+IR8y%tD#O#59_a56#d;zOUUM(B@VL|)HBL~y zKIj%l>x(wTsni9X;d<_ee8Lp#kDjKh#Q?O@U8Sz5$bH2IB2!+K8>-BGUg0L4Sq}BXjf5{^7zyzu7%FaaI~hQN=Kk@ z?$D8l$=@&vnIRvP$3j57%tY;=stXfm&U3aZHHI2B#ZtJpMjgcZSb)QG1xGf+wHx0%SA zaeNk<%2+oWO&h3K0E!|rnuGF@)67M_ywZ6n&Px5wM~k~Fwg6pYb-WNAZL8QKl*DYh z7@bH_izR3v>!_tDlHLD6w05joEJKdv6TeZl$=ZH( zZmgT?1)~yORk{Yn@~k=pS$5Uy3q>~))glaCtXBmmyTdH&& z3M3O;k47@GZa}5TMmC~+>?cQ|cHAG)XgMu5q4;akW;DHw+HOJjyDGL7&EOqvLpkKJ z+ff924>2f@yR;)$+%vIgFlQqU&0q}Mi88$u+l8JoD#s&Fa-Rfr;gHV3Zgl#KO81~T zg;ly2HNLFaJ`~J(*^lfhDs}*!ca;vJ;_2!o5mif4><}_dm6A|j8|g4=(p)-%e)GiQ zD4M|Ys$(eHQKiSx+o{qCv@}3EiLSG+atdYa($P+%;{NL84D#nU6lYN}a;{{w`Kw~* zkeiEoIgiToE&mIs)gbkE5iMm*yo9##epAq_&MLi(Y`6}tpd;+{T}Azv%dR04^0n(I zri)@X(4gUJaTC28tZ;xYWW$+!h@zgU^by)WMzP1pw4n3^9bqT+DY9}M{Q1MZ?~z zG#?tz7@Hr(vVTw@H`Y%wLY{-Af@sKL9itHH#0Y1MPW4i(FsfZcu_CA^&uUC^V`NaK z=;wNs7DWyHB{Q_uRw{-b&5?>D3-X8(XkSP5QWCY;sa{HQzOBKPy%Z^$wD%qamC>D`dY;pKlFRy1HUDQ5LVN7V7$+N^7I3Jg=yOmfV!;qPyWb zMm-c=TP^CNQJhn2)SYwH0GaVAG(<1?wsRwt6`-CQqmu7b+5{bVA~i(@a;avB|MJIR zgG{QZtu4C1DBm1qkms~OZ5R()qSlNhcBmI4QY-X{k-s%6LB`VtE#_U?BR|GT2UL|E zS4R|U6CEHpc~p5r&4FseU#dENA9Qx`b>V+6Afpds~0NEUVU#g)Lo^0(9XtEUo^Y5 z{Lmx6#ZxGtR{Wcic^pb|4Xg+Co zl<-wD z@|IYpzt$+` zkF1QPN$B1&X)?;LCrv>&??_Wo4)?+|^n$TuI_lvo%|N?YRn9~)!=za#aH(G3Y_x@6 zCIq0zT(NV|`aaTJ^!uMQ4>_|ZI3Hc+3@tz(c=Egu-QZJQgpA1M7NhHas<#B~-==y? zQ8{)i0?~^`DqV(pv%9(+y(K>l%B{zIxdH`dsB|Uz$UV3UnXXZ6HLA(@7mU0U)OHPO z#cC`B?dIF2p{N0wWf=OGsZaHh6unrnt>_Xn;x_b}XU5ynliezfK}I|k z-hnEYQ!Ez!BNvE6i|#A76WOs6-i21pl;TlnW0fYLigTsi$a1Vo_n>9WwR=%)n$FNZ z)Z0k0{pfR&>K#Bqm865H46}G5D%M>(ghJQ_OG2@XFNcu_I~_-IMT?`zVUu(WxiC8) zN8k02;RG_fsAHT&lgt%6g?5nrpGKn%ik(5<$lT7N%hRM}6wUhl9NP6ky_`qq*aNtL z?8pi(qDQ==OX&GmwM{{#;uX7$I&e2$L4Wu@%T>hJ84cG^z-s9_+RnXt1HC36x{0ok zOQoX0yvtkYMWA}QjgFH=-a)(bD0UY`*(r7p&2m)iKC*LC+cXrzJ^cVx=I^aNM8gND z-Xm0fr%E3q2d=OuXv7GWK1IFB6rLf!;wpWPBF?Dv1$x8&WI8JOQT1M;bXNJVkaMz> zfzC58yheRbsqGsyW1?bjQUCXfy+dE_OPRTPC;f*eR8cSQ(FOKEKcMq}75j+Hj;h`# zWKO2_8Qt`jzMy_7s`nMSGY@`4)n6;drQ&myapMOnFi)|c=pl3MFI0kEp)9nXZ0ZJr4!nMJFeC;!dYp4{eRz@;Mk(p9y}?xiNB4OSF_HKNV2eD7}`7=nQ)!mC)1Ss#h81pD$HGCzZ99@ zbzEz-pr&FCP!PXLYKUGk+BQOiN2!;_sBK-Oi{5Wnbo{Vl z-B5nUac6XRonqaQ6Pa5NRGVj1JyB79zuXHwb5OnBxnhp*gG$FM))(Eekz7#TcIu@c z8vR4D{-~6bGyrWFq5fP^HL{F>Xb>&j(1Bpp8-yYm;Rd5(6Qm)iIC4h~-bo%Pm~-Wc zF0=miLgD_34MmS@Ddvr)XGz1*=84j9RFC^|1Zq%REk>g3S<)!9mYmfGRbt&UI=58+ z7<`d;ZOISi=l&RjvI;6T7KL#4j6=a>8ROCMQ_=*qHdLC3Qn}y!(LXZtNhorxG#ORq ztW7}=jHIck&;`BvX=u(~X*x=0)iDDZ#i-s)l$XDtGYd83-kOaPnSTS&>p{{SG?Tk= zE(+x}&qEK{ft-&bJyf~?LLXrw<6LS6vAf|f?k(aEEL^g#0*1+ zIFoB7eIsrGPb%wi}UWiegbHi+dm% z?cJi-CRCjqU^BYCU$HI7^1ZYb-9M~PWE*& zUvKqy3XR|@I*lCtRPPMx&_J=X=o>q1$tc`Yv2$otS?N4F=_p-5Y~LC#qO0T7^Ce`> z&P599I9jEbQ6=)oE9l@8#jc`W+ofx0ZcOttSHxp^ z!#5PeQ<3jz4|m=Vw2J%kCyL`0{6f1~-({hSl~wOI3LxYCgLbik`->VmN&irULG`kc zC%JSEI>)tz3m9sk(m85d6P>QF{%WD4 zVJfYSwx_7H4%)*$XWiTwb8Nlbn1@s!CB~}M8s#vfH$b;8tCxl-&jKB{5xU=7EgGW` z7nL?a8<_)|qT0;6&CszUirJt6iIOeq-(G5tN(@uI7U=W?_1qF|ex>8up}Oq0v_f8; z6>E)ZtWvBE`bkb^k6gMd=76&6NRH?opGRA?`L)yzb-JO__Q;LVu>)%URHYqJQ%}7X zCltc{(Fu7@RcUABz}(&i<&98V1G;uk>Wa3~b2qenpz1lJS)qz`NBwR~Jy7qSQcrZF zn(FmJW8D?&jn13vxP8zeUSD5ie_nDywz)fiXbCxTe`LoUH2}4%E4d;sa`=I0MtQ~D z(0u;F=OAQYzi}|?%()+ePFzqucQntSm%mmN0&AzHUhm*l18E$>?MpszxF8RgRZcqAC0CqQp^{H7S=KR(6XnBjX~$Nc}lypm_lhI6G!4$M?ku()$wpQshG=^TL zqcC@!wHas>v-3>k6r>ijP&C*5Y;=d~B>*jDl`{uzXWcs&m0BjvL$4XH=A)~uXBVKe zE^50F#T-;@5o*Ei!(w#FUu~D5#6c=uif*1%ED&wu|9W4Bnv!oWN5fpDAas%ucm+Dc zxUmu)XfCZn{rJt$YIK(jAQ&C9RL^UW6ms=dSPgRg|rrpC$A4je|f(V zsJM;VMxqCd#p_VDqSAVFmFsx}x^Z3Fh<-CeM4>0-2hpgCg|rEIl3Q#>woTMx3yO7; zwxS-lb=+;J94)q^Z@*L;gFX+CcA(Q_WU;7Tekl$GrmJ)(vYICCLg%^T<56GsIucOQ zaFy;x&Zl+O_Mr8|_M#C{(mvGSfV3ao3=Li*9Y@jRgeOpX?hYVoQcEpPp@yvBPNO=%r8B5tj&v4H zHAShyif(o{x$HoG& z0~JLjOze6su)7lz8w0xoyRjt{1rsF{eE&CJynfd+GrM~>W}cZn9R1s<^af(#+Hez< zDXh|4sD!m*vB>_i>fJ^c{Zx7fEiS0iyJ%8J#qJ?1W9dHf^-$>pbeX&EA@b;_*dyeL z9;2w`(i4=xjNmD9exlejZPOaSELLyk~PCjZ4Q|m8WMdgL*kBRu%S{BSydDCfqgVZnYX28sG_O%(Hw0ptyl|mh>^G@sze6R3f-=% zdR}N}NtL!n>5NuwP%~D<3@B->)D|7**>8v1pVslUM}t^d>43iHQ>-I0R8xyi$cwwZ zGpbfuF>kbDtG3bwW&BgDEBez~v2Mto8Dw{KERSM6P|_-i|DrLVsF~!8;u=alkqbSc zA6m`ZgkGppxMICg9(u<dK1ur z`-)9OrHO^1?|gS^5^`l9lTlE(>POW({%$N+-`=i57BISD{djbTul( zCt8DQGa{}<>13+wQ1)SIJ&I;dvH|74Cv8L<$mTYoZuHrkb7Nc7Vhfu6Qre0ZGJb4B zc6>WvJ947;-hqyidF({ST-8W)o-uS6+Q4VqjfRX-=^j+HhD!IM$&8`=0^|sMujNB}cI%s3&vSqv*g>l^#RZT;FIE%G~}qxm3U)u9_3}syMW#g*C)D& zDw73WLJ`dTFQfj9A6JlFq*`1>MOI1I&};6_>uB;L?c)ZD;SAkGBf3hrP^(I65sOA8 zOSjQ|chrY7C`{)%jpaxM^*1B zdPV6obe&xEIT}4qrEzF0cijtA)kk`X0(m#^3V9Szz1L_OWA~ffdPk(U=tQRKy+eiQ z3E!hMW+L&ZKouzgxfE23L^QjSVo9hYt8^bw2KUuRbbW}FjAk#K(TGVVK} z*~})Yqe^6R&M1cruSRZcjZ_mEJy5+`xuxZ$+9)YPrFBrq1jSs?9C~k8w4eT^F4}ie zv3h7CqrDqi&6DDe#<;7rKI*D}3=Pl?dhdqFo4JMus{TpxM2}goYlL<)k~BuQ$gi59 zM_!6GMXsL|YliCeP>bd$nf|W@iXiW7iLQN6i&n_nQu0DA&#G-}v~06tZBXDwom~TZ zM26B91jHX?c zrl4cLw3VqSt)ybp(5P?HbQHntcm}ezS8OKo<}LFqRGu?F8x?1UF$XpKsM7z?FOFp{ zvYo2ZdC2mT_BJ1_57ALAKpU7RFGP|5sa`npXPy^XEZ(k&>55o{}R`XX&ZZ}`6Jc9d~VZFisxlU2GC zRah-WqGa-+U8pFzz;5)KIq@FUhU{T4@?f0Vhf1Yu%lpwG&Px=!!}U0Tyvb<}qHM0) zAvF4zbQtw(p)DUl6U(c`QMB1nI)+vr)|R7@Wh>P?j_m2zPM}~$h?A%!_r@tyh`ufc zbtOkXjZDb7&Y(pIX!dl)E+8B3oQo)Ls&onMxh7pk6EdYMC}o9? z?<%TVTCr=$nylbD@@p#HK!3Zc^d>T5)ZhUNSW-udMK@PUw^8B&=?<#KHNT7e*vCEe zht-e!=q$7R2k6{v=^^^WUHk||=17lGEbDMj(3_fyJw;)>~D7{42j!Caj(=O6$6yHI5gHACfzeP7kO7BoGf2Z*t#ZS@R;?YCaUK3Dv#)?Gr znKvd$s66_Be159*BihDa1qf4d4r!%v1IiO>ZQ9 zLt#Ut@90a2w(y(Tj+f;N(k6h%$$NX5{&cT#awxr9^#wPX%f61{1!SSfUonSW`N>LHau zCcF_Vi;i|wJsWh2b?S2HGM}u4qvcnJYCz zE=5$@993r}umxIRtyoL+iQj!`g~ps!%nP->CACHaSPgB1yqYOyKo@vp(iXk-m)fCt zp4#?k<6710fPPyj))Dn!ADxgL`AcWi;fLyZqiVIJF36E9*cA=?rdT($hbN^w8qZPn zK-I}!eNf?v+OjV?a!RE=QTh4WuOBMG+Hfz_omo+DbS+%!gZeRx>5E45oy&g6iC@g< zk2>&|ivv&!cilj=qmH&b2(75Etqewq161md#yTj*B@4(yk3JM7@q7$J=g%t^fCf#_ zmWLy+CyI?g1DJmVBF|NdjYJ7Yv^RdrDxfp{4xFH_Le0L7+C z`bJ!Ym7>##W(-zzIsg7 z844Ps*mBgpg|q^7;ci=rzVLTCt59K%el<#atk@b9k);-E(R{|@b*Owr#nz*2R;4$f z#mrAOqL$P3IX0o2CZ^o$H)FLEH`-G^GoN&8XndMb@VNu?D#fGjR6b`VwITpdDh#;No$ zy3ZQbkzBE&a};eGr6WCt7Skdc8P2NSaWpboI)VB#cAi9?So1%HhA&kt27Tf_IE{vJ z4$h!+UMf9{YE+lbA-jRndGsxxT3kR=`l-c5)Rg(eCG>zi<1!jdFLnj3_@mfW)T^>| z4b_|=T}O%Ir5ng7N4kk#6j9q-s4UN8EV{}we;avODs~6m9IDt|WY5vxL(91y_j60l zRPO=0#@fU~^sAHf2tB2rdW>4{lb)a&SEQ%NT>luJp`(q};yFrRpjaI0YazWrNrAcw zFHtuq)q90bj8*AtH1ea4SdyNJykCY*>+d# z53*q<^%p&HQ!G2T9=%UaZft~F{6p0sd8gJ$F>! zOIxXr_LH$SKvDS>YluR4SL1<<7`HspQ#+{N=>j75dJZ^g>MLq*@ud?MIE@u+o9L|T7G-< zJY1z6(1O0&UPsi2v7!??$DPv|nN5+r(P^@uF32ZIv94$i0zIfd(QU zbj(`vMI$_Lg#YUmRTqatKl3s6hebr+)X z%&U?APiYN0!Dm~G)-pD(Lx)loTaR|oJ8nSD$@MlO`ytXMw6c@58SSXAdRtHx zdikv=j``v?w40}5JE~}+*bZb*PqPzQ@$M`V6=ZDOh4S%jjoqj|D}{T|6wM6e1d5*^okV3=Ej@({{4Y{5=+I!5o2 zx{zCs=i?%J!g;=gLKwj=qtWOJ3PV@XiD>B>x>ZcNj$*>48>sC7=_cyDNxFq@u*w~a zEOKP7ebkMd`T_Exzj}xQ8IK;JALLw*b7RckpP-5x zrKji{ebX~EoILh98piz+ht5`0=?ip$C;25B&wTq83g8KSjka7=>>1PzeNRomg zx&Km;?v`e9o|G3A=Kjlvc2|`0qc%!34F%ApNZo4|Xbb(C zWp2IdDz!r0czz3_VUAKEw5_X3t&ue&abYygQn4baKK*!6O%>% zfcvi`I^`#oLNz(&(#YIjDuZqelFFjbagq(Pq4z0=&h(e~DaQbN?oL}&uBtwf9h$`_ zs(^-)tye_)^0M+j^w3hOjOOs9*duq|FjPUI%%~jDvi6cAntEKHw<^l$tnF1p&sn)} zLb3eyZgmu2MKNde8r48$H%m29BR+X8w1U0WMq!H-tApB7>Voz%_PC-H@{PKvLK&$Z zI?5c!4f$s1sN7LsRw(PETio{z(3PT6Lo~xkr5t$iBA7jtQET9DtV!$eN@^SmA<1`8#IC~8&F$% zi?-+;&v`qPN?y_)<-M&I9Z)GJsUw=q+EXXgmo?JPsLe2ydZT*ID(!;IA1Kxp4JoR6 z-H<2QS9cW3tg;8X(orpZ&r7gA}7>_gvos&qd}Sfl+$p_We40pzetI*2CG#~wnP$&3!8 zf%Jq&(8eg~D7sNaEsmiMJOR-tVy;S$qmF#?6Nn$aF`Pt8c{gdj(}N4qipA z7`LvWLT zsO<|>lv&41RE#x`SIDKZ>b*w04LX81XezzRTeQGTrSDMhfol66Jtd=!N6%0KnqEap zL>J?y7REtk&DC^^&QQ2(OOF<2KWlRqh%ZMNEYZtF+J_aIJ>v?sZwz?p3hqXt*P??XC13J$qcSO^>sa{nS%d=k%IdiW$p_$vI>Zrh7$r;&m z4r(AzD;-r$PLRi2%RIVZ;Wzyx7-BvU~> z%d0BwfNY8@))Cb>t$lPtv4@iL?)(^A1Yr}+v|mv6;!?6Xa>DwAM`0)=b$g@%}l8u>aBqB~2pm2v0> z{rz~}eI1SGn~^ur#3PE`L?;WX z?JcyFemoYnFtB{4=y*lw!}(IaVO!&{*c;FHjXXmA*tl!=+bfYh{(bMvYUow>RkA zPL;kztNN?-9a>aCdXFB{Q^%urK~e(R{6%dO(GfDJB$Sk-Blv)fJE`qQ)Rep_8D+5F zPblcK+J4TBg-9u=S9vKF&1Rhbf{v8XmcOD9&d@jX`kVIg9a->P{y>{wsoqZ%#^1-K zp(U%OU#KBZ)Nk}?sbcA9FjqPQEpnGKQ7ZRj77F1zV1H0FW6EDN_oI}J7Ppad&~JLP zf5>Zuj>SkfNWcWL%{=Hh&#y5mO3!M7%s9`ch_4IQE3p9%LdrQ>GLM^ON2cE%#D3(5_5XxZn+#1<1au!An_9#{a9a^MV zQS_J0qZsN%R$m({aK0RwybeTJ%8hUK6QYX~h1G#UOYNE(MsTQin|1?$`jikq{ zgKlh-T+mf}9jPn2(o(Uys6FFMJ=B3b)(zdcuTpn(ypvQP?If#jfJU(D(h$92mgRv` z%SxVT2y>=JD4H>#F&g|wYJz6cH#J3FimF93xlO9baz65hosKP zi7Vrc=5y}5AbXy{uE^?y&T}_(?SW$5QHg8XTMyKyv0^@G^>4*|(YP_%TTe6w`JteF zD(!_j4pXc*nq6IO`=C9n$@E2i=Suz1=@n9cRlXJ!z(++Eunj3SS# zg+F@82sT90H{ym|j;qnwV?1k}_+ zVwekM67;jIVoTB403FLRw22XTIck_sr7O_b6Vgglj&WlZ@*vk*jb@Q= zu0aEjDz+Ax^wIX#A&ZCF-g*?mUA_Ue8LAc=(FE4KHX+|HYOxu;^q01vjqA0&t;m`= z)i%_PdB=8im$}Fel$XCG*@@Z@Q)wg`Z>-oZG?Bh=H}d43-Gg?Hl=h;#S*o`W-9!7) zM7A7-#?ezAKwqz`^dK_ptkOeh=RK7kMm)RZ3ZEQ;khI)`d((OEl>TKCaDE}%ja zq>Cu(t6E$_@19DR(T@Sr6;y=JdlmI!J^mWXL)+`fcE0M}K#r_A+(heH)4YY|^By1; zjToqUw~^%{=?-$>+}}k@>0$06BhLMO6qcyi19X{L;zPtEWO#%;*veznytqoApiiMX zs;4NK8TB(%n?C(HN;;}o9NJY?dV%gy?KW-Z+Cs1W2Km!xzC|&&RQe7b zNYgoej~v-@JhDd#$e8ceB%(J7m1d*#CW_@CGbMk9f5?X{(?}ga zz-`_amqnE>DrSSOk}a1*FL<`fqr$xRwapdp zF6>akW0h7wpK_#%$e&quCA67mwK6i{y4jYBhG>2n$pcm3>G4Fj=-V41 zx3f}XbpD9c1odW(uPMsIyP9UmnKl3B=p0vppRNzsVJEdj&uU4nP?opkg$mcz_FAJ_ zWCd-|KHkF{(7V?vZHul^+78{_EVW0=!=w(VJ|kU6^t^y#ols?Fz@1Si?p<%R%0jU& z=vxP=D>^tv>W13+NZnB~`E?KE%{B5tO}LAF(OceY^+Y}^6!SyR>92aBIXnx!Q8?S{ zgKX%B`l1o%rGBU-_f>z?;<;K3Kpp6_8QueeTdH&rnw%*OMoSh;{wR`t3_(ANXfL^PqU+J+(Huc|i*nepUJ zMy{-hOhJWNC!UI|YD&{`OYO9k>F6Q-=?rvnnT}v4N^GanS!iGt#b%=ykEA&$FEfV! z&_vdR=b}brjPp<$XLmjd*efkSYdzI=A#&KRSUCE{JURkhqX$`pPP6*37|rG`UV?6t z0W3vbCrisv9o|wcM}}{Ttw1H4ODmC$vr1PX55}m~=xSH(V+|U>uQIPiC79{0LkBp% z^@yJoGi*TTl2p18RpGjALYuFvbTj(fRE;4pGEa}n{^JI;t4&E%*ci>pzmE2yNGJ8QS1_`*GamJZt?tH zLDT5vucAH~(lwOEtn)hRz}veUsP07RCMtMBZEvAW=GL)ji?MVY#XeH$9W<6c>@KQz zP;Kv_{R^f0XmO-UAD}5krH7~ldW6n1e}9Y$y-@5)Zs}Ql-lym`>v_*mN7gx?qh#{L zI26S_`2x-KQoWbxUw)OoLch7|UZb{8RqqY5We)Zhja;G@@6b|u<@abc-`|NxAFC;r zfZ9Y$iO6N8l!V%~)K)&AA@3CXh&FVTl2H-H_)louM%DX_Zjz0pAm74LDvG(K(l5xE zzW6KZJ5X)Ep|Xse-%-YIosA!8u&L_(M03VVX()YxN`IkKj7-1LCs(yiM-Ay6Gf+aZ zN;6R-`qM0A#2Na7Y@&25f6*j^V%f-#ek}*F;A{AY+<2dBr1U7@CwF@u^kcS4jZq@M zzHWk&n30+yPo4lXw3c^v<|v9cr+HBa^3#0CZIOV*=ilQ1#bfm>l4C8chG{96XN}xKd^p`}t zQdC+B{bQ}DH0nX_QwG&1cPxt%A4xW-6#YRtbcs8nJo0L&7PhFsKyAeiH8xeO0(#6` zts;8K`c@?rn5^TgjCu}I%s#i2KB5X5@I^5PG=)3X5#{@(EmuWOWI@%?bY|sF==o%+ zI%>fP;f&_93Q+@2S1znfeHHb%6F8h-#37j6{#=fk&aT%#%l>7L3k8D4p#Eqd>Be5VUKa>V={u^uS}# zlwm3zi?;Bjj6*9=t8_f7J5ri}a>(W;qLPKQC&0y&hIR-*f?f~`W9R*J1gof&o4px*QcYf;m((mE8)HCmsmHi~UPq4eGxQ38F$ zrd)ZebTcw1Q`mys8B?~RD)i6WP{aPxb~JK<+U`KB$pChu0`y#wXb3ssF7zixrMrF( z9!Jp>a^+)aaExNnD1*D?I7%?q_D;Ajk|M)H zRI8Ts2xT!de2hK^DfR@FXNLO}UHYlmGgO)J_c?0IH(TP6AycszXe;ZJFOl;SmS8q{Y`k{BIBKhun^m4gc#G{R5ZV9M=vSNuS+fT71bibzBen4%w z!#<+J!BR3>jXt3_F48yDx}ZwGqbN#$pnQy+ zKT&)7$u#to{@@p?!Me|Hw3Jad9SsPTGLS#_X(pOyCuO01byfNY{iR3$iw5)lD;wF9 z`{W?!mC`?S{k~)rEk$tzdC;OwI=jYbPjhYA1SPgnsVQ<|g}@BGVQe%@@+whU@dhFlia`mU|mpkjR6 zfd7&$!2FY9<r@= zje_a<>!7dnVJ_(XF4c2IF+6W|(MQ&I>!G%+XS<;p)m7?_PMWK|&z%oBB~D>XvVmsQ#rZMdhcG(r21NKH{(8>t!MPc9A3(K=?8Ezmn={w>kg zd)iwoba18Wc_9mC4z1Bh#v>+s0o|Dk8ITR5navNqQq@!u~PI-ry^)$53^ zc2}$udc=10sKqnIx*<2L@m~! z%iLjWQBXydu0#Dmy|Z3zf;s=Bl^dEx(O}gx@|_~>F>9oXy$KQ(d_n$Z9^OL zs@`_QSFQ{@(C$QOC)!0G7KyCb@-B2BOk3HF8ueD`9yGm zP{rqp9YC*MNC#2pk!o=W&8x3^hf!=n#g3r$zonz-AZv%m(ENUiMI$H1_~Yo|1#RyH z%3|f|Bx=o3okA~}<;S4XtX7;x_y4N&400$SokhRs+s~m{)fGFBijX5+KoL(AyNH^4 zYAct}Z(3YNo8KsQ1y$#~Tt)l4DRvDNd#l)Wbn>Zm1N9(BzlmKsDjc4mA zvN4yQp;*@Xo})s1lPnIE;d;EtRd2;!qFwYzuh7XPmA*y`LKS<1>e3g#MWa|Ve}{_f zlis8Ld>1etrF~N@0c|d%tt6t@nTjQ$cg%4sZ3YO2LoWX6^GhK|i|0$M(_^$>H|4`kpl99Ul zfT`pHdC;Ix$rwHPD4C!-_a#%bimcBJjrNtyQ7LkoyvUABIv=v%tXO_z%RBG_=<#_S ziv?O+O|nFJ+pE+HopF&0qRe_KEre)))vAom6HHZF1v&B^SO?UFXTcFgmsP#0D3URt z8d~vGazg&arRr!HZJiN+5ND`?-grngQC>3STIlS2sWzI?Rr{!ep0VoUg8DNKx}yK4 zN_CMX`>2QNF;j9we^?iAM@2eoEA>$U6U7>!yPSiD$dR1d0~vi&%oELtQN2cJGArec z(RqVPn;<_{Y?>ms5{flLGwDT}qa&Qj7H9|kRZBGKgzB|IgP7BKq0GBdYxI%ls115v zTQLJV!ARE@J*1a!hx+o=wnx2D2UNbN_S;d?H{$9O?L^cjL)+<$9^_ZKH?q5>Ep|b# zoK&wXI=WT$x}k^kE8Wp1a;P5YG}p!ldGkqpQGfE0o@m!H$q)H+<$9sm6;f|B_O#me zLA^SvZC_NNfJ*xzzw;{Xk7lq!G$2>J>l%n`!W0{XPNhqO(fOx3dVkc7vp)o-a$Sca zJKk0fL#B*00jLm9+;G%xqhcda{7xwlRkW5yqVhYWQK(6jG#cHb9|%I;%r=72A7UZs zRuw5Ux1PUB$Dn*arLm~lOl@Txnqwu6M~|6LOhA4+RBs|$cv1>OOX*Q3p^NEiF&VjW z4yK?-7gcX6ieQCk8nWmAkeH5ancvMo%PMOtGtmLA)-3e8o-`Y+Va6~A&F9|uFE_S9 znv0rq&(1>$T#xz4t&Fq)S=EykB2(sf;b<>+Zv@)F^Ro!~+)!*WiebHR3Hr+V^ip*6 zno5_UQ5?Z?bn26|0_6#pR-!1*=_)jtesnb&&Rl&B+BRFIYf)S~X&o}q6Rk&2$(uKz zO@pM3XdCzQCNz-Ms?Dg~CB?R&2ejP|w@xerq;63tkz zdb?1s>bf4gQE%o6d(i4VD&32MxeEJ`SAWI!qdVl>QOJn(qXXzeGwC2&@>lf^p%|Xk z!)Vns#g3rH2c@IPcE5BCZEvc2(J0`kV#m=LFX;qw^wrUyL`&!+P9dKFmByf5>s5Lh zoeNa#44T2)th2~aK`qXqSOHZE{uY9ZDJ}y+?uME%C^btR?{sB9@3cUzU>4 zB<}VPsD-~`ACVhx4w8`v-x~Xb){^^vMoX3uFwr4<+V}mJr_e?P} zG?Pr$9C>o* zEib21YqSOxMoGJ*BB;?LsVGWk3@wJT=v9iN6y`A{P-%LBlIRcTxfF`xnfmMYv z$aSjPmPOh9B^y-ol}gK@z++N*)F@c8MI|V;L$-{e70~JqQbjb84672#s3lcKVI@?` zPiqEPO;D@~N~BM8K!cbEI-;F?zoRO0tEN~rl$4WYTZ>(xd6Wu$s2=85XLp%?TA?#PwVuRhA( zN%a~ae!9}o5JeZ(_B_x~)(AY2PZgCmLf+q`#>j z0u`k9<|lLm!q{&s6xu*7yij%4FI%IRjH_)>Y*EDw=m2+JTa>}Q(GI<0_R=10pCffZ zw^^6$h@SIAbwVC`TnwGjF6NcqXiOfd3;Ie%(G`80C3Qm)C#3GE538U(&~C225Bg{( z`J&M+wB?>?KW_y5&~WA*z0fe!8?8T}>(&QVXLisRjVr5t^g~9Yr2c3P&&L4Nti3c4 zg(OOY&`L7A!N|*4F@F@q%zH>~=^tq*a(}Ds4MX2JLjkCLTeTgI4)DBduQKx9t7 zI}(|?DK-kFbWvL&?P?rU(HMTaIY);}G6j#s@I zsN8I6COXQvFbg^G1k6Uy7;)yH^jG>E{~=HAzqu%td}AI;Un;ckkpK`-(vwidOd?_7tB+o^Ot>RL^)4alEwNNhwuGSp%ddd+>X87=1x>lW1c zol3W&ri{+pkVR|N+m0FqE4Bk=%}~9as4njiB2in`)pnt0tR?J5BMYhC9`rU`rF)T) zw_^K{=?G~*3f(P5p$O(F2hcJ4;)7`P8kHVG{G6NNFxt*FI)c`cV;)7T3oCXEnQ(@p z(GxP?T2M2FbNCG?Vh{4$E;sl9?0e37oA-;A)=&_55wt|MAiHy)j4W}SdK)sPa=Pwt2$G@T6o1F~VR_7Rmp$*3Q>-Y4|+ zoMNBR46>yZ^o7;5RP>UO^9wRBCw)af`7MlZ$d%0PI|?Vi`hl!@LVu!OE2T8l?uYaX zZT8bXexuf$=X6xDf|P+83{|~M^wC<%%8fC<{DUk~rN8JnN1Bad=p%AaKWFJ5nn%uR zbW*xpPRfJkky#p}CFFW0XccF}6qQ=6m>IfvM>0n}8QJrq&yy9)hjzVJEI&$kDiuH_ zT1pnE*h|S0?P0~v3hnEpSV3e$4_pYfUN2dr5sRh5=qOKj5p-yP+=RD(+|ue|=aVz4)cAG(a8uNDa}%K-Kd=orrlN-;#jt8=tRfCV#hBv^Mlai|ojpGKg}0g5d`#aQE6jE-?O zmLSL4(o%FVU8T#ANfX7EqxIwowU%CG~4 zkTdK=ReI|PB2m*JD&2)HvE|*!shN&t56WiL*o#)thwVd4ebsh9+RmsOgA_$f=-g# zrlJf}wf%wy@*d(Vn!$Mf4W-Xk(Sd^Q{Ow5ej{&?nAXc~nxT&R~mP@%^NP+vRMb3{#uRYlF|EvljF z5t0*{9Vb;skF6zVRN$#p1AXJEt%=%^G1fx8=v8W?k~uokIw*)$b{7;mS20(#Ww=xq zbsDY~^^nyW$qn(R_y%|Mk}cOq{xuY9fNF8{4G}*zY4AYyJdK{nozbrm@@b{g#%NDP zsR{a1T55{sGHx|PM%)|CQ8D_-7ATw%u_YRQOlpOSw9@DBLRNgMqcy7ETxx?h(xV&D z+*GM8D!fUh?NAo8o%ZN~x6}bed{t>jbOgf6sG+smB|nt!medQ)Bs1!bwz8Jd2buR# ztS{QLT^!I^i1bxX!jz$H@$b!(K1u6|jDbJ-4bZm#lB27RM+&L3b=`h8@P$5h0Z4!FQitA()&nKUP zE|F18MFz&pX{cpul}<;kHcB&)mz6XVIWp$WLi5jSAG6U+dj2_R7Mb9G=nv;*E*eGu zHxK!9cg{z{xHlFck9FG0LR9vFT7;trHz@)++)#@}XgY797Ndr~DqVsO(K{|h9r;Vr zWvItd#g^yBF00-O9{jS({G=+8k9cYD{TI@sx+9(!@ zK9y6wUC5layAeNmYuJOf^4a#H;@p$_kX4jg>_;}~Dvd(R(E&91qe>5=b==v9P%Fli z!^qh}I)V(WHyuTj`bo!7(oiWHHQ>8($59@C#ZI6{m9)K+$eD9+3i(#4aiI0Afvs~TQry+{T+J8xqpw6=SlIX6Z4(~bUR-45>fwMQW7%U zl|G;X?yC0@-C}#m$c;1f3B{2qd`9_s8dFfQK8mHHMVz58$Uu+u6_s41*f$i-NcSC0 zD5w@cP!|`)exm!GR4)ykVIJ@cnOI7{(Z>pEk&aTBhi0INrcx&Q$EcfyZgO}2L2fS6 zUsNzorP*i?J#Y@H{aLYp$d*3LNC`&3lQU8tl+DVlF|s8~GeK6J)z%c1XEoFe^?#;P zbJUf0i+NF_kt)rHtUjtVKQd$VD}WY!mn=}h^STc#ktKPt6{^J?q9D3PM#~RD2V5m< zu|{wEDpnYM3{<`UIlAw-p1wGa{qK7mC%0rh|1^({gnms4OYD>Xd!)URkXR2 zWQi`3D_fxz0cu+fE$=B+M~zv}u||c)s9p_pt%gc%&`7RUO>~M8rxv;pqL?kRC6jSPkC?qTL=UTL z%TB0vQK^xnZ^SL+j&4jea;(}kLCO6jXS8Od)D)#`R=sAZfwN-G(cHF*wLnq56mvoL zqqV=5$d>V$mjV7>m!#Hc&Na0l0rn4|FLXsy*j`&yx1M6{P%~PzN1yrZZfMzF$sKKE zl=nc%5!zk{w4SHI6J>KgywGuS+K%YW0@dq;Qin>N(V2ddH>$i`Tke8x@eFiD{=cMd zD27!${`9c_A_K*GARlG|J(1B|#d@JS^Q7J=nROQ*6nk2+KB(wHsV`bgX+N}y=gb$i zW%kk^C4?z90F~nt4Ma^jFN087ao>)Qp#0WqF%*qTQfwHydPf?LULRNK2-GWG zF+XH{Me;{e$n^tISQphBiMDb!Mxl`Y(&)T;WC&wWGUMr3ba;beG8%n5q3y+> z0FHDWs!VPai%i1RVm-RMNs2@Bm|1K<9r@%N5vj1pCUlQE)n;T#*183~Z6<9+>Cbh1 z+t3((PqrOZ;f?YRl%GCsC%QUEibobazq`;yMzh_>?t-)j4P;c_iz+ZS?L!GXtNT&3 zgGvvermiYIhz@O2=^^B{L8XV$(lgQ#G~}Xm6!q>a9Ydq&DUYLPJijNiZt#(rEEIP+*_Z%|Gmd>MjzAC+d){!eDprhQ+7m@#0=@RN}tQMEi zG1hvoAP4$`t7tpfz%^9u#v9E9rTF1 z=`Py)R7yf;Ppb4@o;c(8Q8=@gWYmd$JV5b7rH9CX=jaid$`yQ!f|zYQLB)zoPf@tH zl!E%+lu}XEEm9h?oGv{>e;MJPqt5pgdx1VM(|d_rcnkCjy<%nMHJZpQ@eOM3DZNFh zU)1&;N?<)N9sT;QPxL-d9A5@%&$m-D(R9{RJ|NHbYVi@xWTx^7HA|L0qdAT$%|e+= z75jpGT%@n423PAF+R1$EJ1S2OnvFbC6#IcTnyX$8dSoj7MCK`~_X~aIZu*U!_&#$k z>JX>cAC&N3_5Pv;6V&z}qWkhNI4RZOtz15InSL!l`Z!Q63ZU_eq=IMzKLgo%)L}v9JOYiV2Toct6m9| zMsHCP^$Jt06gvM+DvgHbN@Y-)m8w@3Ia(`L4y~m{dDNEP#|*V#zEc79?0qWIFPR|^@|k!%q^EAp^ICpzj3)kY?Nq&lc`BekuIx;0R}dMLY( zR3CNc9>HJKMjHw%=8c>fIlG{$-PNKis%NKIH&lpGw>x^q?7jzzY^HiWQHy<2FO)Pw>W!{5 zzw<#pTeP=6=sokhzNlSA9eqC(a7rzFQF+$$`Xg62#Ri~5v>1ru*C;j!jo}-1gVCyE ziVZ{Z(%SijS83&^6Y<{82;=DF8iwB#lHP=_5v=t*P4H zXf&j(Vq?(!LW+$=Hw!2>4vi;U8jpH2tDAtrS-A*AIRVl{RBfF0!Ovd&gULlFAx}n) z$taB;Bp9uuhns>{qp2v7F(m{&PuD&|k>Px48mhn$fToC(oks$D*r@UiY_yoT!y@vgDpqZncc5Ic3q{F$RI*mh1T#X zSEC@t!8NEY-=bQJ*3Z=u{D;P#lcLdUa>5wYj~sIy+Q3{r7Av&VQ^%o?&D3H8 zDt}1Yh!%9y_BNr(JX@R5alX&D1wDDMdRviOqRz`UGl$+FC|yT` zW~lTAs?}Vvo5=63wsH&Ash=c3-B;;b6i$Eo4o$7A?WLodWP%17{bA#eJDw)6DlplX9u?@~8~+S~GN(d%OZF#>i9=^=0kG9L=JauY}&0Qmirx zG*!$3g*TI`pz}MVswfg!BIDs|VTGc4D^?9P=2uSD(TLaDn>BjIeOd$c3sB4k<LQ!jDy@gQg-i9(GK_jm^t`f4TOx1XVzfdoz2Q-g+(i7d{Ir2h@ucVGBth7oyA=6C7I-}KlByZFq zFaJXpE{b(Uy8@+d$cUrwj)t$2dgRsP3id>=+9}oxotdH*y^$wRfDh`){nrPbH-{HjaC z(bG_A1j=owYw3rgRx0L?o{f=6L;W*3&m)l;BhDx^jy=k4%}_Oh9QH6bnQbI2#ku)%sEpnoagK32n4ji^-@NJ%2Fz&HXn8y=BCiik#@V zLeRUnDh)-GCn`1##q(YK>1ddTGy|23Q@xoebdWR)MVLupD1Nls&PIt`-*6NiEzLnq zrb~0tqpI58JQVv^Eh3OfacMp((N7| z|Dhc=ibbOt+}SaxDEH7hl)`fvizd^ntVj3hcjHi*n$iYj^j6x4GTZBzH=#pI72AxC z(CckM6X_$iqN$wmZKyE6Pv4IA=BmXGw2SrPohXB2iARZjq+O_crrPdCq0HI$phwi( zik`rdRH2MY>6ZLc7!ePlMWa=E7$vj9d<4ai9~?!?k7;km(7fM@ z9Y>F1q!Y-xmr75f-mLqaLJk8}dKv|B_0OOpU~5OPxZ+^p}TEV?=uSLDrBMm=rO;b#`#qG6$LF*+i$3SE9pD>XsvqLsDgoFKhP*I zDF=;yE&W6b=~;iFx31dWZ}co)v0UUyUi=5m=S==ZGw3(|A!kp?KtrnkCXOl}nn_=h z9~p5^7C`xFTM+fwDiuPd23X;tYS6LmPFOFLB$TMv?f~7QL2TS&y{S^*$l}JrBqkj z+GuG|xgk^n}@LeN@0i_oO}A<*3pI=<5Z^0rg~rbwmy56C0vb-i|n- zbr03H5h^@E^%|o^FQq0Z@}lI7a{1LtQ}l)&q#1gem;a$&E!Ta>m=C81jhrXya^^x}oW0o9^fz>u?^Z=@PZ* zfKD>s@mr8~OC zRp^11@QHe&BB@d@w7Z+y_C^`>Dn2Nh-mDM0NLJq$C7^!jBS+tFy*mi?=li&W(Xe8Q4M7E{Hx#X#tG2_?uVvD3G-ZKGN1*XrBtLY=K*#5gdZGX{ zag;O?ovf>Rqfqn!#YUs%JQZV5iB{V3Sd{ihv2n=5LmH1l-b)kEQ1aqHWR@XKMES=_ zLFm^kX%cGBC!dU-4%FU)(G{-X6jX>Taw;lJRuFas{=BLQaf0OVGK#DqV`QskaQd@mwxP8^cs@ z1u`70*h-W-Ra%9-xW21VqchSPbe(){Em~4V`VVz_BSoWeZKW9Whc~k8P)**8$0F~6 z+S__`iWS#5^nsCm11ik8un}1^u5LorSaaKqMnpKV z!6!e2x^u@K&Z{?HI)cuhmyV)*1EpgqqpWls-C(8i1Uk&R<4H7Zy-H7^dfdCG5q~Do z;|!We&vh1U;7&Y;rdg`=JX#VfT|imARGNUQ)Y6tOqVJ=mOQ<>h&}CF{qFP)*mARX) zqToY{T|=fkDc4bN)~;`$KRkmskxPBWZlU_*iHT?k`TcElcdhE(L5+E)@1p(ziY1|* z$E16x!DHz@dKRZ^nT*PEk3T?LS)qD}R`NftK0+5SX?u^+S8}N*=mmd=_$i7pSKAci z%YIW)&)!lRI@Lt=o}p!J)b=?#zC$fupmf%TU!pI(qkn}4#Y?YIJ9>*Z$cyLWEh_J< zt-M3$`6fa-dXS{j_vjgG+!?4B{b?pL*skq;Ks&E1_7N3h4E=;kk5ue4GNzBnLW{3x z%U{s(*(&{t+H>c8Lp#bT_8pBJuUIx}Xsg%{bndT|gPPV;=}*+fQ?Xyj$4~l=9;8aS z$hf%l2RX9F{TIb^rT?KJn^kI{uE2lIeJLLra7oIKdKFW>0%*|%eaeF925SI?P+j`E z!l=bZsR)Yvr+S7cjXTx|B{Px~MfVu7jS*kz^eBdGZPda9ZJ`G#j$+8$O;LU~sRX*) zSS?DTEXLnbXgc>sX=IsCDubqyDU?M~*L0rCAy2+PR3264%9tT1#?96-nQSJ6>4ZsY>)PJ+vhX=S{H{`ZiLrYUm59o~IDC zwnjnRJ2lW*uAvS3#&}v2@dXEuS}2;F!WQ}erxtdoOkM_v9QglF>Yxq3RIe^NN#HmFru z#avODLfUd$)R1w!9Xe>D()MT#e+pl`=s44xA2P(o`t^@jMEO{cYvD%6ky5C>N z(h&{h?NcWdbzEENjCT8}o;O;sPq8kj4%eeAdP%)*D3<)8J4&ywee^*2x~jA%O5&(` zp{Kv4-pH2KDj(E^XQ~f+GhFJ6{&9T$&`Y-GivoC7`lEPrX#i@;C^`_$q3<7rHWpQj z!6>Y%Vna}s?urdXt;gt74nqf+GY>~im~D(e8L^TdD&9h+{>T&spcux#k*Mu^eU4Gc zkUM8Ix<5qq#-MfN3S&`5b(M}ort~J`Q5UZC1T@u4u|Twpb(e`KmSYJ*RU%Y62{mD* zdNR6GPo=?V7WILD~G0ZY>%?hV>tsZL88~RF&~L2DNCW(sgKiTb0J5L$p|r+OjSl zhaQ?r8&Eo9;znc^C2c|xgH*a1`PP)SAV;pkR%FT;yA7GQm$oD8K`PyWM$zZ&L=7KG z@u)W6(b$EatWmw)=m9Gxd(cSUf9*wsZz#48b#Ty@_oE73r32^)XXqd*7a$!%&*P=T zD237I2(o%D9YqF==*Q3*&c<=Hv!qH-pg~=vlj!wQ9l4jpa(WeSOad|pR_R4_=Crna3Ay@8mr?W-m0m$}5)`|N!g>F74K3KN z((9--eZ&oP@rhzLQT1fiyM@}310V3AG_N|BM1dRWAz}GhTi{S%($-ilTXDz9BRE z?C&U-UMd?sA#eVHj=fW94hp3|_=)WKl)uoN&D!2?l#g*C7p?28dVf$1D`J21>h)9U zKUCRHr3PC5@qb5;nGe~Lx#veU>0=9^QZ>}JAex@3SRv$Uq*!6Jpp#StMJKA%5E+um z8lg}|tD?yJykf?v7e`+VWs|FzAe$LdaWuKFN=?zvH;R=&VG|T9iTcqOmqNwZUTKs< zo>K-*FRT`2(O-Jta%eM8cX{OVS*2#E*l)!upvm2&ifHOB$sA>vXnU2AH)CUE6n9x| zEl_3?)vJOQ6jW(d6wi8|CHhXLWrYUrP>X7461`}3RARkKt&zuDsRk+&E7>4ddXSoE z1-V5n)Rt$}7LDQP?a*rS>)NRQMYX7d9^aJeqJPb$dT0;NZ+%p&k7D-d{YJ$apmg4# zJ0J^hl{%u+WK|7O-{FcmAy@9iM(9ve#TuiYkEJH)7;|f96mnbJYl_Z%lA589JTuMF zLY`#)yqW*q<|=hT%Xs765J;GUi$6fXsX)PsAYS;f03qeYuY43?oD*hO)OLFfeMU@%(AXgUN%8mPrk z)SdTa!_c&2iVa7uTXhabpe(McAG*gZ!5_WnuOS2=8@{PE64m7C8HL^is>Nv3%}Xu# z8H0ZvbCr%o)t^h_P>I&6Hy+t{lO`aKUMdYl2lDbi^k}nULFnd5ZEq4`Y|D-98I7udDrrp+UTV zn2j=`6bna-xtr#oa*RxK(TNag9_mn1^&-%>VQM=c%{Z>o1*mqi6p5}daxO$c^sI}} z?2gi6G;E9%g<|crl_hAmue20>2+=;4p={TC&NIHRXQdD{pz3iaaDU|P?_Hi2Zk?nKs;~F|%Q@V}}IjS2d^Ru>h z6YVJ=-9puwDJ3Fz{=&{}w5^?DcaY0o=`KogRf{BK!))Rnig%apqsd9CmyGt%t2{t< zdA|Whcgc(%p?n>r$LJqV_Y)M&6Z#a*B-2Vkw>L_uD2iVVq@f9{q(4JfxI3StCA(Gc z1KaS-+O0KKY47BaLl!>f= z=mL^Sk2hxDQR_vDWuulK z6#IdevVxU^j*vb4LRBw%9B~bA%Qc2{nN?R_4=FyjwMze=1RtCMBu2@-A zeza5$Rb!+pkBsP5%utsrYEc3GdL&gu8y-mJXbF8-C1l6wQW-sAe6v88dGlNa?Pevt zDoSVlz!G(FldRBH?ucs0gc(b9RFfy!8nrnk)j+z}LtAnrcT}dKw(Nl{ zA4?sOVPTbeq8Z%nUZ^4~Z5`2;Co1iPvR%}oGkSePF>kbytKS9HVC?RSY&NJ~H)O(W zr#pJhN?Q+fZm!f5y&(7Lg+32atT*b&XyAiZ@*9diC?Z|zi>`51`=PFj74t>Ed3ySz zZ{4H;$myaq5dBB5G6*H{1Pn%hnVSwlXSwD>kqxuJVaSrZb2!S4R*Mm+d649Xo-iNu zN9h$63qWCG)M6y+^Hi}>sCb+-8g0BSjX_B#bY8}yRZfbHLn&m}<58cYicLVjic5j0 z`wnR$>Pu-5szrV<2^DADnv89D*F0Nuj9fGu4}hx}DM| znvQnx7JLTEAV;5xHqe*MLhC0>VJM-8G#gE$zY0e|Jl%5;-JHiG^_`pXz~0=Zw1PNFf{+R7<3 zjFI>>iYH$?gKE9k)jx}>@GYBjXft#B^Jp)9_679ul$3xH_zP_p(Yc=5$0c-mgl7DIDJoiGFR+mTw_P?ubOxfU9*IxhztPJLn`= z`YtM^6v8739b;B>58b3EypP85G$y072NipO`f{}%qGtD`N9Z`$<1t!QS+OT5g6Hii zYJXEoK`ptesc7 zOL~he7zf{>7Cvf`j<(iP>^*8rpOb+~bH8Mw3B#oi=niWDAJLg))%%1-g-f5&jTSoQ zEHsHV=`UywImlOZm^F`YXgJ669c^hLWuwU!(hn43t$I1=7VorwqES4TzfkOX#eO3z zFSW=;GZ+{CAa_QMzvwi5(?9fnw`6c$I>_h9hb}D8k>*E%4OLnI4Q6emAS#xkSRqu1 zoWC#{$>>}J@$)ecL$vj}j>QNa<{A}6?*mk7j68VuS-#W%#;ceKN^PlFaddC{`KSEwxyDA-i7hN!)jw&H}=+o`k>`o*2y z82ushZGzTvcRHgljTLK(<~P$;nxT>#RN5SMZ!5JxN4VQvP%~4-TB0Yc(zQZ~-}HG~ zqf(r;Hps2DN?nob45=-OWiHeX-DI_=J*w-hQa9w!{LLM;q=g4^B46u({2oZ2sP!V% z^FkZXNF7m6`ovD?#Q>=@8o_D+3)uci8`ZW8+DUKG6_p`}>xQ!UW?FajopqWXd17t2 zC%T`jee^=J`L0uM)Tget=Yv`@r|X02?3MbWAV#5nXbI1yFKR^}(I0)}Ngjaq%#;SA zmcyh$D4us1gHh#n(h#)nw6-@CC0I(sP+c;L;b;--jw8^)hHBx5783JE^)jRY)STlR ziAu8uFbY`@(eaH&m6`jEL5JzH$D+G;6&r^l*Gc11R&kY1Ku(Rcw?Gugoj4JNwUB~P zIHS-cw1w?WM&=vIr{NJu@&g* za&37f`c7ZG3f-74twu5Qglo{r1=3m+%o~{h(7vaNMWaK^m}Agia*K870DWvMs$Na| zU61N?RV)rwVP3HTRUEF^M%19VVw=!%-bQXls|Txe3mU?VYAf=)rqXT5o~L3va$~-~ z15NF(t?WcI8Gqx^^KPoQ3%Os?Io*v4@_uFys?3|Xy{PI?#rB~k++q9C&?Ig709r(T zdJq{??-26suGnD|$IS2u%3naGNApxrrN>Yg>K#Y*$OKQIIoydS(FuO*eF_Ee#`rXv zHA?l)poI;jv*^o3ZRH$FBY!!My6#Zv1yqs4#Q78)#&zN^hdj48?AtaVgqcB073krMJ<&x@vm|tu<5ZE;`9u zwGn$EX>@D)l zk=`Mv`BFM6ohiLX|L#Z`Xac|S$V4xAQa&ITR$V?K^ZL>!6gW<$pHa{;wa7wFCv|*Z zP>*wpeMMpXuJ#*h#@+NiFSc53vr!c?nIEVv?W5jxynt&5`7TpMFFyoO@M&~?s-30lcKt2mlQUSNvsN2y*3 z6wluVD~a0rDOL&%Cub~;?q+H$WstwOVr9{5o~d%kp5rf%D)Il@n4tmfwT}wuI8R(f z6h25YM+Uo9S_wrQR*TB$!z9Hl(0aC41(}^ztSWLN`?f?sm}6L>ezsCIoYdUj?Y^Y^~tY#wa}>kk}cX}CGiKY{C^D8QPoD%ywsu&I=ES-b&&<% zk*$Zi@toC1efCTCXxMhC0Sb#zJqHxa)pA62e@G2cE3$7VltTaA2-(rIHAcgBt8EjM z>aSyQMuq7|o1$-dD}ZR|M{Tb;deA^>fmSnKxuC&}tSwRPd{Qgagpsv1dfi+t+Mrsa zRqBeo81>qs`ee}U(9v4jZ+kT7pX7%4nuG@vaep6AZO;RRb8mM*Ww?ht(Xx?}7urWZ z+7azdP}@%EG%HD+(e^)*H`>Fobjd5_ZCh7l%z5dC)*9;wx})VBRS#4@U2S`!Ie9C9 zDAH9edgsNARL=*MIHY=g(6twe^+oyeE7lKPBuDW@?*^;1KT76V9)OC6DK-#oe=Q9{ z1InrGVAR`1u^}kypkhN&M`q~5kkb)qI2y59^+uqg^yz-cbdyT`(L?&j02EFxGZLA< zkVYZr4Qe|Y9cE522Gt#>*jRM^i(=#Q>ah+x9+`EPCZLl1wb?-AKSK2;qBnJP1VJdA zHH=AU5Lb0FD$5)<7>y%KpMv_6^GrqNtk;I16UI^~N?}Z#hQe5>o{oBRRcD~xYj$kp`%nU9H?W?ZX5_G$x&ec-nM~=Ji)hdfko zCpyP>Gvkp=9R4N<*g$c7Q;IQlzFu@k7 zFblhm;_S4Q8_0t7fSV|S*e&#e5jzq68?F|&QN;<0-9a9WwY|G>Tc+esiUJXepz{ zee{^oJ{g_brWOy-uVE^Eh*}v)kI+3n?_+d}dD|0IyNmP`1@SgI1@(TUSSs@LRxAx= zGK+nNhL_g%o})#~cV3_dWCbtL4({<+D1=q5*U09!^aeR|&EKMyL$sB5sO}-PO-GI? zDt(V)_UI~PppgR=%S4B{uRi3-L@hp|tp^nQgfd;E&!{d>auyoPGx!C)a!`w}D2^xZ z8_FcN_>P*g!jX-paliaPU;R`s2OW7Y{Y2h=+R869n!msE8(m`^Cl}Qtllg;u8HN6$ z9klp|UU7B}G~D?&wv+OqVslh4KbpyVg#xG#<5590u$f8=p&Xuy!pMsIuL$ZsS29E$ zIQK?qu$^K>QRnB9F^c1^D~6uaH<_TD{Kl*}DoZ9~iUKD}C6EDEp(ILQD3wAFS*b3K zf_To$pb+kovS_NIO3R@DR!7Ps7D_$LkPA<81?0f!R}qya2Qf$PI~1#goN~04%BTq0 zw*_+BqF5EQjdh5sXhRvv5+#xgSRv;`)vJc;q3Wo2nCe-hZuE{d&;Z)npzrjAHPK17 zTnkk^DcPb8Q?(U4RIQfk)ke9jNYp`2WP)|kyK{=wLo@ijQGGO<)njti>6UD6Vj=qt5C#;vrs)+n1hu}xk*GB;N=ZlSi<7OgL$(ssxLwMV|J zR=J@@oM(6R@U7&5UI$AZkmnQ06ZHsC3orE9T(OR5HP^QjDo+;F8O6O*sW+PTQl(wc zQbxM2sF1ZvyP+zq`*lb0`~tTJO630(?1{|MRIeABdP?ezwvf^KpvugE`=Ii(73+)a z$l>~-ou9N7Uv$5)V*OE0IUT_OWX1S95RD^SAB2Kes@`DqFpK#ea4e&c4Nuf)6v1dP26gPM(y{3DOKBX6 zCl?)$KI~C!0y3aq3q)(uR5}r*(sKo&`g|L95;{IovB@ZwQ8yT!W9*)SJXkBAidHka zgrIx3)ixAGww9)$q4U&YI%>gaFasT9WSWUqvSK_7O;{s^pix#+y7G!Ip*CqSS%XyRY{)_WE`c&ykt{WUbT_mHpg z`onvGCn$cLj_)Z-q~AzE39l7PMVIocUK(1=lkyCW%FsTZqagaL7pOj0^(8u2O0idH z0nh$x^pAY)4Jt51v9~ChzVjW*;muGwYR_A~_sE*;CIeY6l`_$XROtgM_e1)K3hEz^ zPv{Qw+Rtc7KgF_8Ff*?&==FQ;<10FXzM+=)RPQ?~Kwp=QE-(`RKwmi-h9kq>?LA9R`6UzBl5Tlt5=$VCm*75KYl>PYjUCOp&mQA^h53ZO3S zRj(i_%H3HAU1jC5Fv{i$ErQ$*DrSfdRFRBOI%lXTs`pDVV-z+{Du(7+Nhat8SF1Rh zN|s@YZrUhTA}_{DQAxCsb5IIR3Xn>pI%8E@1{HLW%A(fvz~xZ<1gSiFY$=(ci)3FF zkZotFB8n-bQgal=47?ILd`HJu89f=Hm<8%jzEK73r{ArL_>ZqWEKxk;krnz_NL#Lk zrt?%(M`2uPYc!k{)EX#vwOZJqFT9hei3+V#tQLxmSIib|nIPGrB<`l#=osU49b~|7 zY3ibRjL!9tx3^;T(J*9>qDrf@0cuUm0SyS%)pta$j2aD*v$5*&#WMfPUaHp!^(0em zj83uA(FC0%XLUy3SdVCmzK|<7LyhmMUURgHE7JlU4b}Es&{|iOwnWi<53?0Av{0-y znx7)ILA^p$>WZF{Ewx2&$<5lKu~QUlkJ^@$-11^veRmW`mg|8^+UiqwK)0%?)DwN? zDtMvy`xWbmmNVPwggR`KIwK!e2fb0jJ&JWf4!hK%D=NaeSvRzWv(Y_I%yD`k0~e_$ z+QyOgLdoM4>x~9hSIh_HKG9bCAj>w2^+j)bO8t-@cbzXv-zM?XAOF34du9Nt#(L~P zWVTVIgU~gu+hFAQNg9G`bN>xR`;4VwXckY;a8#XVVFa@Fm;8|XLv7C=tzhjd09o

      H1vc1YC2lASFsr= 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%0D0#^ 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 0, train_dataset))) + valid_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, valid_dataset))) + test_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) + self._helper_test_func(len(train_data), 2049990, train_data[20:25], + [5024, 89, 21, 3, 1838]) + self._helper_test_func(len(test_data), 241859, test_data[30:35], + [914, 4, 36, 11, 569]) + self._helper_test_func(len(valid_data), 214417, valid_data[40:45], + [925, 8, 2, 150, 8575]) vocab = train_dataset.get_vocab() tokens_ids = [vocab[token] for token in 'the player characters rest'.split()] self.assertEqual(tokens_ids, [2, 286, 503, 700]) + # Add test for the subset of the standard datasets + train_iter, valid_iter, test_iter = torchtext.experimental.datasets.raw.WikiText2(data_select=('train', 'valid', 'test')) + self._helper_test_func(len(train_iter), 36718, next(iter(train_iter)), ' \n') + self._helper_test_func(len(valid_iter), 3760, next(iter(valid_iter)), ' \n') + self._helper_test_func(len(test_iter), 4358, next(iter(test_iter)), ' \n') + del train_iter, valid_iter, test_iter + train_dataset, test_dataset = WikiText2(data_select=('train', 'test')) + train_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) + test_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) + self._helper_test_func(len(train_data), 2049990, train_data[20:25], + [5024, 89, 21, 3, 1838]) + self._helper_test_func(len(test_data), 241859, test_data[30:35], + [914, 4, 36, 11, 569]) + conditional_remove(cachedir) conditional_remove(cachefile) @@ -80,71 +89,120 @@ def test_penntreebank_legacy(self): def test_penntreebank(self): from torchtext.experimental.datasets import PennTreebank # smoke test to ensure penn treebank works properly - train_dataset, test_dataset, valid_dataset = PennTreebank() - self.assertEqual(len(train_dataset), 924412) - self.assertEqual(len(test_dataset), 82114) - self.assertEqual(len(valid_dataset), 73339) + train_dataset, valid_dataset, test_dataset = PennTreebank() + train_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) + valid_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, valid_dataset))) + test_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) + self._helper_test_func(len(train_data), 924412, train_data[20:25], + [9919, 9920, 9921, 9922, 9188]) + self._helper_test_func(len(test_data), 82114, test_data[30:35], + [397, 93, 4, 16, 7]) + self._helper_test_func(len(valid_data), 73339, valid_data[40:45], + [0, 0, 78, 426, 196]) vocab = train_dataset.get_vocab() tokens_ids = [vocab[token] for token in 'the player characters rest'.split()] self.assertEqual(tokens_ids, [2, 2550, 3344, 1125]) + # Add test for the subset of the standard datasets + train_dataset, test_dataset = PennTreebank(data_select=('train', 'test')) + train_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) + test_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) + self._helper_test_func(len(train_data), 924412, train_data[20:25], + [9919, 9920, 9921, 9922, 9188]) + self._helper_test_func(len(test_data), 82114, test_data[30:35], + [397, 93, 4, 16, 7]) + train_iter, test_iter = torchtext.experimental.datasets.raw.PennTreebank(data_select=('train', 'test')) + self._helper_test_func(len(train_iter), 42068, next(iter(train_iter))[:15], ' aer banknote b') + self._helper_test_func(len(test_iter), 3761, next(iter(test_iter))[:25], " no it was n't black mond") + del train_iter, test_iter + def test_text_classification(self): + from torchtext.experimental.datasets import AG_NEWS # smoke test to ensure ag_news dataset works properly - datadir = os.path.join(self.project_root, ".data") if not os.path.exists(datadir): os.makedirs(datadir) - ag_news_train, ag_news_test = AG_NEWS(root=datadir, ngrams=3) - self.assertEqual(len(ag_news_train), 120000) - self.assertEqual(len(ag_news_test), 7600) - self.assertEqual(ag_news_train[-1][1][:10], - torch.tensor([3525, 319, 4053, 34, 5407, 3607, 70, 6798, 10599, 4053]).long()) - self.assertEqual(ag_news_test[-1][1][:10], - torch.tensor([2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]).long()) + train_dataset, test_dataset = AG_NEWS(root=datadir, ngrams=3) + self._helper_test_func(len(train_dataset), 120000, train_dataset[-1][1][:10], + [3525, 319, 4053, 34, 5407, 3607, 70, 6798, 10599, 4053]) + self._helper_test_func(len(test_dataset), 7600, test_dataset[-1][1][:10], + [2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]) + + # Add test for the subset of the standard datasets + train_dataset, = AG_NEWS(data_select=('train')) + self._helper_test_func(len(train_dataset), 120000, train_dataset[-1][1][:10], + [2155, 223, 2405, 30, 3010, 2204, 54, 3603, 4930, 2405]) + train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() + self._helper_test_func(len(train_iter), 120000, next(iter(train_iter))[1][:25], 'Wall St. Bears Claw Back ') + self._helper_test_func(len(test_iter), 7600, next(iter(test_iter))[1][:25], 'Fears for T N pension aft') + del train_iter, test_iter def test_imdb(self): from torchtext.experimental.datasets import IMDB from torchtext.vocab import Vocab # smoke test to ensure imdb works properly train_dataset, test_dataset = IMDB() - self.assertEqual(len(train_dataset), 25000) - self.assertEqual(len(test_dataset), 25000) - self.assertEqual(train_dataset[0][1][:10], - torch.tensor([13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]).long()) - self.assertEqual(train_dataset[-1][1][:10], - torch.tensor([2, 71, 4555, 194, 3328, 15144, 42, 227, 148, 8]).long()) - self.assertEqual(test_dataset[0][1][:10], - torch.tensor([13, 125, 1051, 5, 246, 1652, 8, 277, 66, 20]).long()) - self.assertEqual(test_dataset[-1][1][:10], - torch.tensor([13, 1035, 14, 21, 28, 2, 1051, 1275, 1008, 3]).long()) + self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], + [13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]) + self._helper_test_func(len(test_dataset), 25000, test_dataset[0][1][:10], + [13, 125, 1051, 5, 246, 1652, 8, 277, 66, 20]) # Test API with a vocab input object old_vocab = train_dataset.get_vocab() new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) new_train_data, new_test_data = IMDB(vocab=new_vocab) + # Add test for the subset of the standard datasets + train_dataset, = IMDB(data_select=('train')) + self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], + [13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]) + train_iter, test_iter = torchtext.experimental.datasets.raw.IMDB() + self._helper_test_func(len(train_iter), 25000, next(iter(train_iter))[1][:25], 'I rented I AM CURIOUS-YEL') + self._helper_test_func(len(test_iter), 25000, next(iter(test_iter))[1][:25], 'I love sci-fi and am will') + del train_iter, test_iter + def test_multi30k(self): from torchtext.experimental.datasets import Multi30k # smoke test to ensure multi30k works properly train_dataset, valid_dataset, test_dataset = Multi30k() - self.assertEqual(len(train_dataset), 29000) - self.assertEqual(len(valid_dataset), 1014) - self.assertEqual(len(test_dataset), 1000) + self._helper_test_func(len(train_dataset), 29000, train_dataset[20], + ([4, 444, 2531, 47, 17480, 7423, 8, 158, 10, 12, 5849, 3, 2], + [5, 61, 530, 137, 1494, 10, 9, 280, 6, 2, 3749, 4, 3])) + self._helper_test_func(len(valid_dataset), 1014, valid_dataset[30], + ([4, 179, 26, 85, 1005, 57, 19, 154, 3, 2], + [5, 24, 32, 81, 47, 1348, 6, 2, 119, 4, 3])) + self._helper_test_func(len(test_dataset), 1000, test_dataset[40], + ([4, 26, 6, 12, 3915, 1538, 21, 64, 3, 2], + [5, 32, 20, 2, 747, 345, 1915, 6, 46, 4, 3])) de_vocab, en_vocab = train_dataset.get_vocab() de_tokens_ids = [ de_vocab[token] for token in 'Zwei Männer verpacken Donuts in Kunststofffolie'.split() ] - self.assertEqual(de_tokens_ids, [19, 29, 18703, 4448, 5, 6240]) + self.assertEqual(de_tokens_ids, [20, 30, 18705, 4448, 6, 6241]) en_tokens_ids = [ en_vocab[token] for token in 'Two young White males are outside near many bushes'.split() ] self.assertEqual(en_tokens_ids, - [17, 23, 1167, 806, 15, 55, 82, 334, 1337]) + [18, 24, 1168, 807, 16, 56, 83, 335, 1338]) + + # Add test for the subset of the standard datasets + train_iter, valid_iter = torchtext.experimental.datasets.raw.Multi30k(data_select=('train', 'valid')) + self._helper_test_func(len(train_iter), 29000, ' '.join(next(iter(train_iter))), + ' '.join(['Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n', + 'Two young, White males are outside near many bushes.\n'])) + self._helper_test_func(len(valid_iter), 1014, ' '.join(next(iter(valid_iter))), + ' '.join(['Eine Gruppe von Männern lädt Baumwolle auf einen Lastwagen\n', + 'A group of men are loading cotton onto a truck\n'])) + del train_iter, valid_iter + train_dataset, = Multi30k(data_select=('train')) + self._helper_test_func(len(train_dataset), 29000, train_dataset[20], + ([4, 444, 2531, 47, 17480, 7423, 8, 158, 10, 12, 5849, 3, 2], + [5, 61, 530, 137, 1494, 10, 9, 280, 6, 2, 3749, 4, 3])) datafile = os.path.join(self.project_root, ".data", "train*") conditional_remove(datafile) @@ -161,47 +219,33 @@ def test_udpos_sequence_tagging(self): # smoke test to ensure imdb works properly train_dataset, valid_dataset, test_dataset = UDPOS() - self.assertEqual(len(train_dataset), 12543) - self.assertEqual(len(valid_dataset), 2002) - self.assertEqual(len(test_dataset), 2077) - self.assertEqual(train_dataset[0][0][:10], - torch.tensor([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585]).long()) - self.assertEqual(train_dataset[0][1][:10], - torch.tensor([8, 3, 8, 3, 9, 2, 4, 8, 8, 8]).long()) - self.assertEqual(train_dataset[0][2][:10], - torch.tensor([5, 34, 5, 27, 7, 11, 14, 5, 5, 5]).long()) - self.assertEqual(train_dataset[-1][0][:10], - torch.tensor([9, 32, 169, 436, 59, 192, 30, 6, 117, 17]).long()) - self.assertEqual(train_dataset[-1][1][:10], - torch.tensor([5, 10, 11, 4, 11, 11, 3, 12, 11, 4]).long()) - self.assertEqual(train_dataset[-1][2][:10], - torch.tensor([6, 20, 8, 10, 8, 8, 24, 13, 8, 15]).long()) - - self.assertEqual(valid_dataset[0][0][:10], - torch.tensor([746, 3, 10633, 656, 25, 1334, 45]).long()) - self.assertEqual(valid_dataset[0][1][:10], - torch.tensor([6, 7, 8, 4, 7, 2, 3]).long()) - self.assertEqual(valid_dataset[0][2][:10], - torch.tensor([3, 4, 5, 16, 4, 2, 27]).long()) - self.assertEqual(valid_dataset[-1][0][:10], - torch.tensor([354, 4, 31, 17, 141, 421, 148, 6, 7, 78]).long()) - self.assertEqual(valid_dataset[-1][1][:10], - torch.tensor([11, 3, 5, 4, 9, 2, 2, 12, 7, 11]).long()) - self.assertEqual(valid_dataset[-1][2][:10], - torch.tensor([8, 12, 6, 15, 7, 2, 2, 13, 4, 8]).long()) - - self.assertEqual(test_dataset[0][0][:10], - torch.tensor([210, 54, 3115, 0, 12229, 0, 33]).long()) - self.assertEqual(test_dataset[0][1][:10], - torch.tensor([5, 15, 8, 4, 6, 8, 3]).long()) - self.assertEqual(test_dataset[0][2][:10], - torch.tensor([30, 3, 5, 14, 3, 5, 9]).long()) - self.assertEqual(test_dataset[-1][0][:10], - torch.tensor([116, 0, 6, 11, 412, 10, 0, 4, 0, 6]).long()) - self.assertEqual(test_dataset[-1][1][:10], - torch.tensor([5, 4, 12, 10, 9, 15, 4, 3, 4, 12]).long()) - self.assertEqual(test_dataset[-1][2][:10], - torch.tensor([6, 16, 13, 16, 7, 3, 19, 12, 19, 13]).long()) + self._helper_test_func(len(train_dataset), 12543, (train_dataset[0][0][:10], train_dataset[0][1][:10], + train_dataset[0][2][:10], train_dataset[-1][0][:10], + train_dataset[-1][1][:10], train_dataset[-1][2][:10]), + ([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585], + [8, 3, 8, 3, 9, 2, 4, 8, 8, 8], + [5, 34, 5, 27, 7, 11, 14, 5, 5, 5], + [9, 32, 169, 436, 59, 192, 30, 6, 117, 17], + [5, 10, 11, 4, 11, 11, 3, 12, 11, 4], + [6, 20, 8, 10, 8, 8, 24, 13, 8, 15])) + self._helper_test_func(len(valid_dataset), 2002, (valid_dataset[0][0][:10], valid_dataset[0][1][:10], + valid_dataset[0][2][:10], valid_dataset[-1][0][:10], + valid_dataset[-1][1][:10], valid_dataset[-1][2][:10]), + ([746, 3, 10633, 656, 25, 1334, 45], + [6, 7, 8, 4, 7, 2, 3], + [3, 4, 5, 16, 4, 2, 27], + [354, 4, 31, 17, 141, 421, 148, 6, 7, 78], + [11, 3, 5, 4, 9, 2, 2, 12, 7, 11], + [8, 12, 6, 15, 7, 2, 2, 13, 4, 8])) + self._helper_test_func(len(test_dataset), 2077, (test_dataset[0][0][:10], test_dataset[0][1][:10], + test_dataset[0][2][:10], test_dataset[-1][0][:10], + test_dataset[-1][1][:10], test_dataset[-1][2][:10]), + ([210, 54, 3115, 0, 12229, 0, 33], + [5, 15, 8, 4, 6, 8, 3], + [30, 3, 5, 14, 3, 5, 9], + [116, 0, 6, 11, 412, 10, 0, 4, 0, 6], + [5, 4, 12, 10, 9, 15, 4, 3, 4, 12], + [6, 16, 13, 16, 7, 3, 19, 12, 19, 13])) # Assert vocabs self.assertEqual(len(train_dataset.get_vocabs()), 3) @@ -214,38 +258,41 @@ def test_udpos_sequence_tagging(self): tokens_ids = [word_vocab[token] for token in 'Two of them were being run'.split()] self.assertEqual(tokens_ids, [1206, 8, 69, 60, 157, 452]) + # Add test for the subset of the standard datasets + train_dataset, = UDPOS(data_select=('train')) + self._helper_test_func(len(train_dataset), 12543, (train_dataset[0][0][:10], train_dataset[-1][2][:10]), + ([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585], + [6, 20, 8, 10, 8, 8, 24, 13, 8, 15])) + train_iter, valid_iter = torchtext.experimental.datasets.raw.UDPOS(data_select=('train', 'valid')) + self._helper_test_func(len(train_iter), 12543, ' '.join(next(iter(train_iter))[0][:5]), + ' '.join(['Al', '-', 'Zaman', ':', 'American'])) + self._helper_test_func(len(valid_iter), 2002, ' '.join(next(iter(valid_iter))[0][:5]), + ' '.join(['From', 'the', 'AP', 'comes', 'this'])) + del train_iter, valid_iter + def test_conll_sequence_tagging(self): from torchtext.experimental.datasets import CoNLL2000Chunking # smoke test to ensure imdb works properly train_dataset, test_dataset = CoNLL2000Chunking() - self.assertEqual(len(train_dataset), 8936) - self.assertEqual(len(test_dataset), 2012) - self.assertEqual(train_dataset[0][0][:10], - torch.tensor([11556, 9, 3, 1775, 17, 1164, 177, 6, 212, 317]).long()) - self.assertEqual(train_dataset[0][1][:10], - torch.tensor([2, 3, 5, 2, 17, 12, 16, 15, 13, 5]).long()) - self.assertEqual(train_dataset[0][2][:10], - torch.tensor([3, 6, 3, 2, 5, 7, 7, 7, 7, 3]).long()) - self.assertEqual(train_dataset[-1][0][:10], - torch.tensor([85, 17, 59, 6473, 288, 115, 72, 5, 2294, 2502]).long()) - self.assertEqual(train_dataset[-1][1][:10], - torch.tensor([18, 17, 12, 19, 10, 6, 3, 3, 4, 4]).long()) - self.assertEqual(train_dataset[-1][2][:10], - torch.tensor([3, 5, 7, 7, 3, 2, 6, 6, 3, 2]).long()) - - self.assertEqual(test_dataset[0][0][:10], - torch.tensor([0, 294, 73, 10, 13582, 194, 18, 24, 2414, 7]).long()) - self.assertEqual(test_dataset[0][1][:10], - torch.tensor([4, 4, 4, 23, 4, 2, 11, 18, 11, 5]).long()) - self.assertEqual(test_dataset[0][2][:10], - torch.tensor([3, 2, 2, 3, 2, 2, 5, 3, 5, 3]).long()) - self.assertEqual(test_dataset[-1][0][:10], - torch.tensor([51, 456, 560, 2, 11, 465, 2, 1413, 36, 60]).long()) - self.assertEqual(test_dataset[-1][1][:10], - torch.tensor([3, 4, 4, 8, 3, 2, 8, 4, 17, 16]).long()) - self.assertEqual(test_dataset[-1][2][:10], - torch.tensor([6, 3, 2, 4, 6, 3, 4, 3, 5, 7]).long()) + self._helper_test_func(len(train_dataset), 8936, (train_dataset[0][0][:10], train_dataset[0][1][:10], + train_dataset[0][2][:10], train_dataset[-1][0][:10], + train_dataset[-1][1][:10], train_dataset[-1][2][:10]), + ([11556, 9, 3, 1775, 17, 1164, 177, 6, 212, 317], + [2, 3, 5, 2, 17, 12, 16, 15, 13, 5], + [3, 6, 3, 2, 5, 7, 7, 7, 7, 3], + [85, 17, 59, 6473, 288, 115, 72, 5, 2294, 2502], + [18, 17, 12, 19, 10, 6, 3, 3, 4, 4], + [3, 5, 7, 7, 3, 2, 6, 6, 3, 2])) + self._helper_test_func(len(test_dataset), 2012, (test_dataset[0][0][:10], test_dataset[0][1][:10], + test_dataset[0][2][:10], test_dataset[-1][0][:10], + test_dataset[-1][1][:10], test_dataset[-1][2][:10]), + ([0, 294, 73, 10, 13582, 194, 18, 24, 2414, 7], + [4, 4, 4, 23, 4, 2, 11, 18, 11, 5], + [3, 2, 2, 3, 2, 2, 5, 3, 5, 3], + [51, 456, 560, 2, 11, 465, 2, 1413, 36, 60], + [3, 4, 4, 8, 3, 2, 8, 4, 17, 16], + [6, 3, 2, 4, 6, 3, 4, 3, 5, 7])) # Assert vocabs self.assertEqual(len(train_dataset.get_vocabs()), 3) @@ -258,42 +305,78 @@ def test_conll_sequence_tagging(self): tokens_ids = [word_vocab[token] for token in 'Two of them were being run'.split()] self.assertEqual(tokens_ids, [970, 5, 135, 43, 214, 690]) + # Add test for the subset of the standard datasets + train_dataset, = CoNLL2000Chunking(data_select=('train')) + self._helper_test_func(len(train_dataset), 8936, (train_dataset[0][0][:10], train_dataset[0][1][:10], + train_dataset[0][2][:10], train_dataset[-1][0][:10], + train_dataset[-1][1][:10], train_dataset[-1][2][:10]), + ([11556, 9, 3, 1775, 17, 1164, 177, 6, 212, 317], + [2, 3, 5, 2, 17, 12, 16, 15, 13, 5], + [3, 6, 3, 2, 5, 7, 7, 7, 7, 3], + [85, 17, 59, 6473, 288, 115, 72, 5, 2294, 2502], + [18, 17, 12, 19, 10, 6, 3, 3, 4, 4], + [3, 5, 7, 7, 3, 2, 6, 6, 3, 2])) + train_iter, test_iter = torchtext.experimental.datasets.raw.CoNLL2000Chunking() + self._helper_test_func(len(train_iter), 8936, ' '.join(next(iter(train_iter))[0][:5]), + ' '.join(['Confidence', 'in', 'the', 'pound', 'is'])) + self._helper_test_func(len(test_iter), 2012, ' '.join(next(iter(test_iter))[0][:5]), + ' '.join(['Rockwell', 'International', 'Corp.', "'s", 'Tulsa'])) + del train_iter, test_iter + def test_squad1(self): from torchtext.experimental.datasets import SQuAD1 from torchtext.vocab import Vocab # smoke test to ensure imdb works properly train_dataset, dev_dataset = SQuAD1() - self.assertEqual(len(train_dataset), 87599) - self.assertEqual(len(dev_dataset), 10570) context, question, answers, ans_pos = train_dataset[100] - self.assertEqual(question, - torch.tensor([7, 24, 86, 52, 2, 373, 887, 18, 12797, 11090, 1356, 2, 1788, 3273, 16]).long()) - self.assertEqual(ans_pos[0], torch.tensor([72, 72]).long()) + self._helper_test_func(len(train_dataset), 87599, (question[:5], ans_pos[0]), + ([7, 24, 86, 52, 2], [72, 72])) context, question, answers, ans_pos = dev_dataset[100] - self.assertEqual(question, torch.tensor([42, 27, 669, 7438, 17, 2, 1950, 3273, 17252, 389, 16]).long()) - self.assertEqual(ans_pos[0], torch.tensor([45, 48]).long()) + self._helper_test_func(len(dev_dataset), 10570, (question, ans_pos[0]), + ([42, 27, 669, 7438, 17, 2, 1950, 3273, 17252, 389, 16], [45, 48])) # Test API with a vocab input object old_vocab = train_dataset.get_vocab() new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) new_train_data, new_test_data = SQuAD1(vocab=new_vocab) + # Add test for the subset of the standard datasets + train_dataset, = SQuAD1(data_select=('train')) + context, question, answers, ans_pos = train_dataset[100] + self._helper_test_func(len(train_dataset), 87599, (question[:5], ans_pos[0]), + ([7, 24, 86, 52, 2], [72, 72])) + train_iter, dev_iter = torchtext.experimental.datasets.raw.SQuAD1() + self._helper_test_func(len(train_iter), 87599, next(iter(train_iter))[0][:50], + 'Architecturally, the school has a Catholic charact') + self._helper_test_func(len(dev_iter), 10570, next(iter(dev_iter))[0][:50], + 'Super Bowl 50 was an American football game to det') + del train_iter, dev_iter + def test_squad2(self): from torchtext.experimental.datasets import SQuAD2 from torchtext.vocab import Vocab # smoke test to ensure imdb works properly train_dataset, dev_dataset = SQuAD2() - self.assertEqual(len(train_dataset), 130319) - self.assertEqual(len(dev_dataset), 11873) context, question, answers, ans_pos = train_dataset[200] - self.assertEqual(question, - torch.tensor([84, 50, 1421, 12, 5439, 4569, 17, 30, 2, 15202, 4754, 1421, 16]).long()) - self.assertEqual(ans_pos[0], torch.tensor([9, 9]).long()) + self._helper_test_func(len(train_dataset), 130319, (question[:5], ans_pos[0]), + ([84, 50, 1421, 12, 5439], [9, 9])) context, question, answers, ans_pos = dev_dataset[200] - self.assertEqual(question, torch.tensor([41, 29, 2, 66, 17016, 30, 0, 1955, 16]).long()) - self.assertEqual(ans_pos[0], torch.tensor([40, 46]).long()) + self._helper_test_func(len(dev_dataset), 11873, (question, ans_pos[0]), + ([41, 29, 2, 66, 17016, 30, 0, 1955, 16], [40, 46])) # Test API with a vocab input object old_vocab = train_dataset.get_vocab() new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) new_train_data, new_test_data = SQuAD2(vocab=new_vocab) + + # Add test for the subset of the standard datasets + train_dataset, = SQuAD2(data_select=('train')) + context, question, answers, ans_pos = train_dataset[200] + self._helper_test_func(len(train_dataset), 130319, (question[:5], ans_pos[0]), + ([84, 50, 1421, 12, 5439], [9, 9])) + train_iter, dev_iter = torchtext.experimental.datasets.raw.SQuAD2() + self._helper_test_func(len(train_iter), 130319, next(iter(train_iter))[0][:50], + 'Beyoncé Giselle Knowles-Carter (/biːˈjɒnseɪ/ bee-Y') + self._helper_test_func(len(dev_iter), 11873, next(iter(dev_iter))[0][:50], + 'The Normans (Norman: Nourmands; French: Normands; ') + del train_iter, dev_iter diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 80648d0983..66fda21154 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -5,7 +5,6 @@ import uuid import unittest -import sentencepiece as spm import torch import torchtext.data as data from torchtext.data.functional import ( @@ -46,11 +45,8 @@ def test_generate_sp_model(self): model_prefix = os.path.join(dir_name, f'spm_user_{uuid.uuid4()}') model_file = f'{model_prefix}.model' generate_sp_model(data_path, vocab_size=23456, model_prefix=model_prefix) - - sp_user = spm.SentencePieceProcessor() - sp_user.Load(model_file) - - self.assertEqual(len(sp_user), 23456) + sp_model = load_sp_model(model_file) + self.assertEqual(sp_model.GetPieceSize(), 23456) def test_sentencepiece_numericalizer(self): test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index cae865f628..946c436e95 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -5,7 +5,7 @@ import unittest from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vectors import ( - vectors, + build_vectors, ) @@ -20,7 +20,7 @@ def test_empty_vectors(self): vecs = torch.empty(0, dtype=torch.float) unk_tensor = torch.tensor([0], dtype=torch.float) - vectors_obj = vectors(tokens, vecs, unk_tensor) + vectors_obj = build_vectors(tokens, vecs, unk_tensor) self.assertEqual(vectors_obj['not_in_it'], unk_tensor) def test_empty_unk(self): @@ -29,7 +29,7 @@ def test_empty_unk(self): tokens = ['a'] vecs = tensorA.unsqueeze(0) - vectors_obj = vectors(tokens, vecs) + vectors_obj = build_vectors(tokens, vecs) self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) @@ -40,7 +40,7 @@ def test_vectors_basic(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) - vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) + vectors_obj = build_vectors(tokens, vecs, unk_tensor=unk_tensor) self.assertEqual(vectors_obj['a'], tensorA) self.assertEqual(vectors_obj['b'], tensorB) @@ -53,7 +53,7 @@ def test_vectors_jit(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) - vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) + vectors_obj = build_vectors(tokens, vecs, unk_tensor=unk_tensor) jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) assert not vectors_obj.is_jitable @@ -70,7 +70,7 @@ def test_vectors_forward(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) - vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) + vectors_obj = build_vectors(tokens, vecs, unk_tensor=unk_tensor) jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) tokens_to_lookup = ['a', 'b', 'c'] @@ -88,7 +88,7 @@ def test_vectors_lookup_vectors(self): unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) - vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) + vectors_obj = build_vectors(tokens, vecs, unk_tensor=unk_tensor) tokens_to_lookup = ['a', 'b', 'c'] expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) @@ -102,7 +102,7 @@ def test_vectors_add_item(self): tokens = ['a'] vecs = tensorA.unsqueeze(0) - vectors_obj = vectors(tokens, vecs, unk_tensor=unk_tensor) + vectors_obj = build_vectors(tokens, vecs, unk_tensor=unk_tensor) tensorB = torch.tensor([0, 1], dtype=torch.float) vectors_obj['b'] = tensorB @@ -118,7 +118,7 @@ def test_vectors_load_and_save(self): tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) - vectors_obj = vectors(tokens, vecs) + vectors_obj = build_vectors(tokens, vecs) tensorC = torch.tensor([1, 1], dtype=torch.float) vectors_obj['b'] = tensorC @@ -145,4 +145,4 @@ def test_errors_vectors_cpp(self): # Test proper error raised when tokens have duplicates # TODO: use self.assertRaisesRegex() to check # the key of the duplicate token in the error message - vectors(tokens, vecs) + build_vectors(tokens, vecs) diff --git a/test/experimental/test_transforms_with_asset.py b/test/experimental/test_with_asset.py similarity index 68% rename from test/experimental/test_transforms_with_asset.py rename to test/experimental/test_with_asset.py index 610ff6beaf..146eec53ce 100644 --- a/test/experimental/test_transforms_with_asset.py +++ b/test/experimental/test_with_asset.py @@ -1,6 +1,7 @@ import torch +import torchtext from test.common.torchtext_test_case import TorchtextTestCase -from ..common.assets import get_asset_path +from ..common.assets import get_asset_path, conditional_remove from torchtext.experimental.transforms import ( sentencepiece_tokenizer, basic_english_normalize, @@ -9,28 +10,76 @@ sentencepiece_processor, TextSequentialTransforms, ) +from torch.utils.data import DataLoader from torchtext.experimental.vocab import ( - vocab_from_file, - vocab_from_raw_text_file, + load_vocab_from_file, + build_vocab_from_text_file, ) import shutil import tempfile import os +import unittest +import platform from torchtext.experimental.vectors import ( GloVe, - vectors, + build_vectors, FastText, - vectors_from_file_object, + load_vectors_from_file_path, ) from torchtext.utils import download_from_url +class TestWithAsset(TorchtextTestCase): + def _helper_test_func(self, length, target_length, results, target_results): + self.assertEqual(length, target_length) + if isinstance(target_results, list): + target_results = torch.tensor(target_results, dtype=torch.int64) + if isinstance(target_results, tuple): + target_results = tuple(torch.tensor(item, dtype=torch.int64) for item in target_results) + self.assertEqual(results, target_results) + + def test_wikitext103(self): + from torchtext.experimental.datasets import WikiText103 + cachedir = os.path.join(self.project_root, ".data", "wikitext-103") + conditional_remove(cachedir) + cachefile = os.path.join(self.project_root, ".data", "wikitext-103-v1.zip") + conditional_remove(cachefile) + + asset_name = 'wikitext103_vocab.pt' + asset_path = get_asset_path(asset_name) + with open(asset_path, 'rb') as f: + builtin_vocab = torch.load(f) + train_dataset, valid_dataset, test_dataset = WikiText103(vocab=builtin_vocab) + self._helper_test_func(len(train_dataset), 1801350, train_dataset[10][:5], + [2, 69, 12, 14, 265]) + self._helper_test_func(len(test_dataset), 4358, test_dataset[28][:5], + [10, 10, 10, 1329, 10]) + self._helper_test_func(len(valid_dataset), 3760, valid_dataset[11][:5], + [2, 25864, 5, 361, 4]) + + vocab = train_dataset.get_vocab() + tokens_ids = [vocab[token] for token in 'the player characters rest'.split()] + self.assertEqual(tokens_ids, [2, 320, 437, 687]) + + # Add test for the subset of the standard datasets + train_dataset, test_dataset = torchtext.experimental.datasets.raw.WikiText103(data_select=('train', 'test')) + self._helper_test_func(len(train_dataset), 1801350, next(iter(train_dataset)), ' \n') + self._helper_test_func(len(test_dataset), 4358, next(iter(test_dataset)), ' \n') + train_dataset, test_dataset = WikiText103(vocab=builtin_vocab, data_select=('train', 'test')) + self._helper_test_func(len(train_dataset), 1801350, train_dataset[10][:5], + [2, 69, 12, 14, 265]) + self._helper_test_func(len(test_dataset), 4358, test_dataset[28][:5], + [10, 10, 10, 1329, 10]) + conditional_remove(cachedir) + conditional_remove(cachefile) + + class TestTransformsWithAsset(TorchtextTestCase): def test_vocab_transform(self): asset_name = 'vocab_test2.txt' asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: - vocab_transform = VocabTransform(vocab_from_file(f)) + vocab_transform = VocabTransform(load_vocab_from_file(f)) self.assertEqual(vocab_transform(['of', 'that', 'new']), [7, 18, 24]) jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) @@ -44,7 +93,7 @@ def test_errors_vectors_python(self): with self.assertRaises(ValueError): # Test proper error raised when passing in empty tokens and vectors and # not passing in a user defined unk_tensor - vectors(tokens, vecs) + build_vectors(tokens, vecs) tensorA = torch.tensor([1, 0, 0], dtype=torch.int8) tokens = ['a'] @@ -52,7 +101,7 @@ def test_errors_vectors_python(self): with self.assertRaises(TypeError): # Test proper error raised when vector is not of type torch.float - vectors(tokens, vecs) + build_vectors(tokens, vecs) with tempfile.TemporaryDirectory() as dir_name: # Test proper error raised when incorrect filename or dim passed into GloVe @@ -131,7 +180,7 @@ def test_vocab_from_file(self): asset_name = 'vocab_test.txt' asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: - v = vocab_from_file(f, unk_token='') + v = load_vocab_from_file(f, unk_token='') expected_itos = ['', 'b', 'a', 'c'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) @@ -143,7 +192,7 @@ def test_vocab_from_raw_text_file(self): with open(asset_path, 'r') as f: tokenizer = basic_english_normalize() jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) - v = vocab_from_raw_text_file(f, jit_tokenizer, unk_token='') + v = build_vocab_from_text_file(f, jit_tokenizer, unk_token='') expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', 'pension', 'representing', 'say', 'stricken', 't', 'they', 'turner', @@ -169,11 +218,31 @@ def test_builtin_pretrained_sentencepiece_processor(self): ref_results = [13, 1465, 12824, 304, 24935, 5771, 3776] self.assertEqual(spm_transform(test_sample), ref_results) + # we separate out these errors because Windows runs into seg faults when propagating + # exceptions from C++ using pybind11 + @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") + def test_sentencepiece_with_dataloader(self): + example_strings = ['the pretrained spm model names'] * 64 + ref_results = torch.tensor([[13, 1465, 12824, 304, 24935, 5771, 3776]] * 16, dtype=torch.long) + + # Windows doesn't support the nested function pickle + # Move the batch function out of the test_sentencepiece_with_dataloader test + sp_model_path = download_from_url(PRETRAINED_SP_MODEL['text_bpe_25000']) + spm_processor = sentencepiece_processor(sp_model_path) + + def batch_func(data): + return torch.tensor([spm_processor(text) for text in data], dtype=torch.long) + + dataloader = DataLoader(example_strings, batch_size=16, num_workers=2, + collate_fn=batch_func) + for item in dataloader: + self.assertEqual(item, ref_results) + def test_text_sequential_transform(self): asset_name = 'vocab_test2.txt' asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: - pipeline = TextSequentialTransforms(basic_english_normalize(), vocab_from_file(f)) + pipeline = TextSequentialTransforms(basic_english_normalize(), load_vocab_from_file(f)) jit_pipeline = torch.jit.script(pipeline.to_ivalue()) self.assertEqual(pipeline('of that new'), [7, 18, 24]) self.assertEqual(jit_pipeline('of that new'), [7, 18, 24]) @@ -181,8 +250,7 @@ def test_text_sequential_transform(self): def test_vectors_from_file(self): asset_name = 'vectors_test.csv' asset_path = get_asset_path(asset_name) - f = open(asset_path, 'r') - vectors_obj = vectors_from_file_object(f) + vectors_obj = load_vectors_from_file_path(asset_path) expected_tensorA = torch.tensor([1, 0, 0], dtype=torch.float) expected_tensorB = torch.tensor([0, 1, 0], dtype=torch.float) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 920167af5a..6cc192c9b4 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -68,7 +68,7 @@ PYBIND11_MODULE(_torchtext, m) { m.def("_load_token_and_vectors_from_file", &_load_token_and_vectors_from_file); m.def("_load_vocab_from_file", &_load_vocab_from_file); - m.def("_load_vocab_from_raw_text_file", _load_vocab_from_raw_text_file); + m.def("_build_vocab_from_text_file", _build_vocab_from_text_file); } // Registers our custom classes with torch. diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 1b462a8967..a9a5f0c844 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -330,10 +330,10 @@ Vocab _load_vocab_from_file(const std::string &file_path, return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); } -Vocab _load_vocab_from_raw_text_file(const std::string &file_path, - const std::string &unk_token, - const int64_t min_freq, - const int64_t num_cpus, py::object fn) { +Vocab _build_vocab_from_text_file(const std::string &file_path, + const std::string &unk_token, + const int64_t min_freq, + const int64_t num_cpus, py::object fn) { std::cerr << "[INFO] Reading file " << file_path << std::endl; torch::jit::script::Module module(*torch::jit::as_module(fn)); diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h index 005f833c02..594f44f2fb 100644 --- a/torchtext/csrc/vocab.h +++ b/torchtext/csrc/vocab.h @@ -41,10 +41,10 @@ VocabStates _set_vocab_states(const c10::intrusive_ptr &self); Vocab _load_vocab_from_file(const std::string &file_path, const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus); -Vocab _load_vocab_from_raw_text_file(const std::string &file_path, - const std::string &unk_token, - const int64_t min_freq, - const int64_t num_cpus, - py::object tokenizer); +Vocab _build_vocab_from_text_file(const std::string &file_path, + const std::string &unk_token, + const int64_t min_freq, + const int64_t num_cpus, + py::object tokenizer); } // namespace torchtext diff --git a/torchtext/data/batch.py b/torchtext/data/batch.py index f345a82e19..5a74ce60de 100644 --- a/torchtext/data/batch.py +++ b/torchtext/data/batch.py @@ -20,7 +20,7 @@ class Batch(object): def __init__(self, data=None, dataset=None, device=None): """Create a Batch from a list of examples.""" - warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) + warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) if data is not None: self.batch_size = len(data) self.dataset = dataset diff --git a/torchtext/data/example.py b/torchtext/data/example.py index a5d29ef42a..8d95a389d0 100644 --- a/torchtext/data/example.py +++ b/torchtext/data/example.py @@ -10,7 +10,7 @@ class Example(object): """ @classmethod def fromJSON(cls, data, fields): - warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) + warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) ex = cls() obj = json.loads(data) @@ -49,7 +49,7 @@ def reducer(obj, key): @classmethod def fromdict(cls, data, fields): - warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) + warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) ex = cls() for key, vals in fields.items(): if key not in data: @@ -65,7 +65,7 @@ def fromdict(cls, data, fields): @classmethod def fromCSV(cls, data, fields, field_to_index=None): - warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) + warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) if field_to_index is None: return cls.fromlist(data, fields) else: @@ -75,7 +75,7 @@ def fromCSV(cls, data, fields, field_to_index=None): @classmethod def fromlist(cls, data, fields): - warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) + warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) ex = cls() for (name, field), val in zip(fields, data): if field is not None: @@ -91,7 +91,7 @@ def fromlist(cls, data, fields): @classmethod def fromtree(cls, data, fields, subtrees=False): - warnings.warn('Example class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.', UserWarning) + warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) try: from nltk.tree import Tree except ImportError: diff --git a/torchtext/data/field.py b/torchtext/data/field.py index 6054f1a510..e117b2edb7 100644 --- a/torchtext/data/field.py +++ b/torchtext/data/field.py @@ -33,7 +33,7 @@ class RawField(object): """ def __init__(self, preprocessing=None, postprocessing=None, is_target=False): - warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) + warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) self.preprocessing = preprocessing self.postprocessing = postprocessing self.is_target = is_target @@ -147,7 +147,7 @@ def __init__(self, sequential=True, use_vocab=True, init_token=None, batch_first=False, pad_token="", unk_token="", pad_first=False, truncate_first=False, stop_words=None, is_target=False): - warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) + warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) self.sequential = sequential self.use_vocab = use_vocab self.init_token = init_token @@ -367,7 +367,7 @@ def numericalize(self, arr, device=None): class ReversibleField(Field): def __init__(self, **kwargs): - warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) + warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) if kwargs.get('tokenize') is list: self.use_revtok = False else: @@ -414,7 +414,7 @@ class SubwordField(ReversibleField): vocab_cls = SubwordVocab def __init__(self, **kwargs): - warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) + warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) kwargs['tokenize'] = 'subword' if 'unk_token' not in kwargs: kwargs['unk_token'] = '�' @@ -495,7 +495,7 @@ def __init__(self, nesting_field, use_vocab=True, init_token=None, eos_token=Non postprocessing=None, tokenize=None, tokenizer_language='en', include_lengths=False, pad_token='', pad_first=False, truncate_first=False): - warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) + warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) if isinstance(nesting_field, NestedField): raise ValueError('nesting field must not be another NestedField') if nesting_field.include_lengths: diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py index bc4d410464..4c1119cb8c 100644 --- a/torchtext/data/iterator.py +++ b/torchtext/data/iterator.py @@ -45,7 +45,7 @@ def __init__(self, dataset, batch_size, sort_key=None, device=None, batch_size_fn=None, train=True, repeat=False, shuffle=None, sort=None, sort_within_batch=None): - warnings.warn('{} class will be retired in the 0.8.0 release and moved to torchtext.legacy. Please see 0.7.0 release notes for further information.'.format(self.__class__.__name__), UserWarning) + warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) self.batch_size, self.train, self.dataset = batch_size, train, dataset self.batch_size_fn = batch_size_fn self.iterations = 0 diff --git a/torchtext/datasets/sequence_tagging.py b/torchtext/datasets/sequence_tagging.py index 1450369efc..849d8be15d 100644 --- a/torchtext/datasets/sequence_tagging.py +++ b/torchtext/datasets/sequence_tagging.py @@ -78,8 +78,7 @@ class CoNLL2000Chunking(SequenceTaggingDataset): def splits(cls, fields, root=".data", train="train.txt", test="test.txt", validation_frac=0.1, **kwargs): """Downloads and loads the CoNLL 2000 Chunking dataset. - NOTE: There is only a train and test dataset so we use - 10% of the train set as validation + NOTE: There is only a train and test dataset so we use 10% of the train set as validation """ train, test = super(CoNLL2000Chunking, cls).splits( diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index 44169f77a5..bf2eca3416 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -1,10 +1,12 @@ -from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank, WMTNewsCrawl # NOQA +from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank, WMTNewsCrawl # NOQA: F401 from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ YelpReviewFull, YahooAnswers, \ AmazonReviewPolarity, AmazonReviewFull, IMDB -from .sequence_tagging import UDPOS, CoNLL2000Chunking -from .translation import Multi30k, IWSLT, WMT14 -from .question_answer import SQuAD1, SQuAD2 +from .text_classification import TextClassificationDataset # NOQA: F401 +from .sequence_tagging import SequenceTaggingDataset, UDPOS, CoNLL2000Chunking # NOQA: F401 +from .translation import TranslationDataset, Multi30k, IWSLT, WMT14 # NOQA: F401 +from .question_answer import QuestionAnswerDataset, SQuAD1, SQuAD2 # NOQA: F401 + DATASETS = {'WikiText2': WikiText2, 'WikiText103': WikiText103, diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index a6dd44ebae..777f04d93c 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -1,9 +1,12 @@ import torch +import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.datasets.raw import language_modeling as raw from torchtext.experimental.datasets.raw.common import check_default_set +logger_ = logging.getLogger(__name__) + def build_vocab(data, transforms): def apply_transforms(data): @@ -24,7 +27,7 @@ class LanguageModelingDataset(torch.utils.data.Dataset): """ - def __init__(self, data, vocab, transforms, single_line): + def __init__(self, data, vocab, transform): """Initiate language modeling dataset. Arguments: @@ -32,23 +35,17 @@ def __init__(self, data, vocab, transforms, single_line): numericalizing the string tokens. torch.tensor([token_id_1, token_id_2, token_id_3, token_id1]).long() vocab: Vocabulary object used for dataset. - transforms: Text string transforms. + transform: Text string transform. """ super(LanguageModelingDataset, self).__init__() self.vocab = vocab - self.transforms = transforms - self.single_line = single_line + self.transform = transform self.data = data - if single_line: - self.data = torch.cat(tuple(filter(lambda t: t.numel() > 0, self.data))) def __getitem__(self, i): - if self.single_line: - return self.data[i] - else: - return self.transforms(self.data[i]) + return self.data[i] def __len__(self): return len(self.data) @@ -61,14 +58,12 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, tokenizer, root, vocab, data_select, single_line, year, language): +def _setup_datasets(dataset_name, tokenizer, root, vocab, data_select, year, language): if tokenizer is None: tokenizer = get_tokenizer('basic_english') data_select = check_default_set(data_select, ('train', 'test', 'valid')) - if not single_line and dataset_name != 'WikiText103': - raise TypeError('single_line must be True except for WikiText103') if vocab is None: if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") @@ -76,24 +71,24 @@ def _setup_datasets(dataset_name, tokenizer, root, vocab, data_select, single_li raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',), year=year, language=language) else: raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) + logger_.info('Building Vocab based on train data') vocab = build_vocab(raw_train, tokenizer) + logger_.info('Vocab has %d entries', len(vocab)) def text_transform(line): return torch.tensor([vocab[token] for token in tokenizer(line)], dtype=torch.long) - raw_data = {} - for name in data_select: - if dataset_name == 'WMTNewsCrawl': - raw_data[name], = raw.DATASETS[dataset_name](root=root, data_select=name, year=year, language=language) - else: - raw_data[name], = raw.DATASETS[dataset_name](root=root, data_select=name) - raw_data[name] = [text_transform(txt) for txt in raw_data[name]] - - return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform, single_line) + if dataset_name == 'WMTNewsCrawl': + raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select, year=year, language=language) + else: + raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select) + raw_data = {name: list(map(text_transform, raw_dataset)) for name, raw_dataset in zip(data_select, raw_datasets)} + logger_.info('Building datasets for {}'.format(data_select)) + return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform) for item in data_select) -def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 'test', 'valid')): +def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 'valid', 'test')): """ Defines WikiText2 datasets. Create language modeling dataset: WikiText2 @@ -107,8 +102,7 @@ def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 't root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets - (Default: ('train', 'test','valid')) + data_select: a string or tupel for the returned datasets. Default: ('train', 'valid','test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -119,16 +113,16 @@ def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 't >>> from torchtext.experimental.datasets import WikiText2 >>> from torchtext.data.utils import get_tokenizer >>> tokenizer = get_tokenizer("spacy") - >>> train_dataset, test_dataset, valid_dataset = WikiText2(tokenizer=tokenizer) + >>> train_dataset, valid_dataset, test_dataset = WikiText2(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() >>> valid_dataset, = WikiText2(tokenizer=tokenizer, vocab=vocab, data_select='valid') """ - return _setup_datasets("WikiText2", tokenizer, root, vocab, data_select, True, None, None) + return _setup_datasets("WikiText2", tokenizer, root, vocab, data_select, None, None) -def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', 'test', 'valid'), single_line=True): +def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', 'valid', 'test')): """ Defines WikiText103 datasets. Create language modeling dataset: WikiText103 @@ -142,33 +136,28 @@ def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets - (Default: ('train', 'test','valid')) + data_select: a string or tupel for the returned datasets. Default: ('train', 'valid', 'test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. - single_line: whether to return all tokens in a single line. - (Default: True) - By default, all lines in raw text file are concatenated into a single line. - Use `single_line = False` if one wants to get data line by line. Examples: >>> from torchtext.experimental.datasets import WikiText103 >>> from torchtext.data.utils import get_tokenizer >>> tokenizer = get_tokenizer("spacy") - >>> train_dataset, test_dataset, valid_dataset = WikiText103(tokenizer=tokenizer) + >>> train_dataset, valid_dataset, test_dataset = WikiText103(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() >>> valid_dataset, = WikiText103(tokenizer=tokenizer, vocab=vocab, data_select='valid') """ - return _setup_datasets("WikiText103", tokenizer, root, vocab, data_select, single_line, None, None) + return _setup_datasets("WikiText103", tokenizer, root, vocab, data_select, None, None) -def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', 'test', 'valid')): +def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', 'valid', 'test')): """ Defines PennTreebank datasets. Create language modeling dataset: PennTreebank @@ -182,8 +171,7 @@ def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets - (Default: ('train', 'test','valid')) + data_select: a string or tupel for the returned datasets. Default: ('train', 'valid', 'test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -194,14 +182,14 @@ def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', >>> from torchtext.experimental.datasets import PennTreebank >>> from torchtext.data.utils import get_tokenizer >>> tokenizer = get_tokenizer("spacy") - >>> train_dataset, test_dataset, valid_dataset = PennTreebank(tokenizer=tokenizer) + >>> train_dataset, valid_dataset, test_dataset = PennTreebank(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() >>> valid_dataset, = PennTreebank(tokenizer=tokenizer, vocab=vocab, data_select='valid') """ - return _setup_datasets("PennTreebank", tokenizer, root, vocab, data_select, True, None, None) + return _setup_datasets("PennTreebank", tokenizer, root, vocab, data_select, None, None) def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, data_select=('train'), year=2010, language='en'): @@ -232,7 +220,7 @@ def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, data_select=('train') Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. """ - return _setup_datasets("WMTNewsCrawl", tokenizer, root, vocab, data_select, True, year, language) + return _setup_datasets("WMTNewsCrawl", tokenizer, root, vocab, data_select, year, language) DATASETS = { diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index a7cc2df9a8..fb3b390dd8 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -1,4 +1,5 @@ import torch +import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.datasets.raw import question_answer as raw @@ -9,12 +10,15 @@ sequential_transforms, ) +logger_ = logging.getLogger(__name__) + class QuestionAnswerDataset(torch.utils.data.Dataset): """Defines an abstract question answer datasets. - Currently, we only support the following datasets: - - SQuAD1 - - SQuAD2 + Currently, we only support the following datasets: + + - SQuAD1 + - SQuAD2 """ def __init__(self, data, vocab, transforms): @@ -24,8 +28,8 @@ def __init__(self, data, vocab, transforms): data: a tuple of (context, question, answers, ans_pos). vocab: Vocabulary object used for dataset. transforms: a dictionary of transforms. - For example {'context': context_transform, 'answers': answers_transform, - 'question': question_transform, 'ans_pos': ans_pos_transform} + For example {'context': context_transform, 'answers': answers_transform, + 'question': question_transform, 'ans_pos': ans_pos_transform} """ super(QuestionAnswerDataset, self).__init__() @@ -63,9 +67,8 @@ def _setup_datasets(dataset_name, root, vocab, tokenizer, data_select): tokenizer = get_tokenizer('basic_english') text_transform = sequential_transforms(tokenizer) data_select = check_default_set(data_select, ('train', 'dev')) - train, dev = raw.DATASETS[dataset_name](root=root) - raw_data = {'train': [item for item in train], - 'dev': [item for item in dev]} + raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select) + raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(data_select, raw_datasets)} if vocab is None: if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") @@ -76,10 +79,13 @@ def apply_transform(data): for item in _answers: tok_ans += text_transform(item) yield text_transform(_context) + text_transform(_question) + tok_ans + logger_.info('Building Vocab based on train data') vocab = build_vocab_from_iterator(apply_transform(raw_data['train']), len(raw_data['train'])) + logger_.info('Vocab has %d entries', len(vocab)) text_transform = sequential_transforms(text_transform, vocab_func(vocab), totensor(dtype=torch.long)) transforms = {'context': text_transform, 'question': text_transform, 'answers': text_transform, 'ans_pos': totensor(dtype=torch.long)} + logger_.info('Building datasets for {}'.format(data_select)) return tuple(QuestionAnswerDataset(raw_data[item], vocab, transforms) for item in data_select) @@ -147,6 +153,7 @@ def SQuAD2(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev' >>> tokenizer = get_tokenizer("spacy") >>> train, dev = SQuAD2(tokenizer=tokenizer) """ + return _setup_datasets('SQuAD2', root, vocab, tokenizer, data_select) diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py index 7f6e606118..0e7b4c26fe 100644 --- a/torchtext/experimental/datasets/raw/language_modeling.py +++ b/torchtext/experimental/datasets/raw/language_modeling.py @@ -28,18 +28,19 @@ def _setup_datasets(dataset_name, root, data_select, year, language): extracted_files = [] select_to_index = {'train': 0, 'test': 1, 'valid': 2} extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], - root=root) for key in data_select] + root=root, hash_value=MD5['PennTreebank'][key], + hash_type='md5') for key in data_select] elif dataset_name == 'WMTNewsCrawl': if not (data_select == ['train'] or set(data_select).issubset(set(('train',)))): raise ValueError("WMTNewsCrawl only creates a training dataset. " "data_select should be 'train' " "or ('train',), got {}.".format(data_select)) - dataset_tar = download_from_url(URLS[dataset_name], root=root) + dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5['WMTNewsCrawl'], hash_type='md5') extracted_files = extract_archive(dataset_tar) file_name = 'news.{}.{}.shuffled'.format(year, language) extracted_files = [f for f in extracted_files if file_name in f] else: - dataset_tar = download_from_url(URLS[dataset_name], root=root) + dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5[dataset_name], hash_type='md5') extracted_files = extract_archive(dataset_tar) _path = {} @@ -53,10 +54,12 @@ def _setup_datasets(dataset_name, root, data_select, year, language): logging.info('Creating {} data'.format(item)) data[item] = iter(io.open(_path[item], encoding="utf8")) - return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], data[item]) for item in data_select) + return tuple(RawTextIterableDataset(dataset_name, + NUM_LINES[dataset_name][item], + data[item]) for item in data_select) -def WikiText2(root='.data', data_select=('train', 'test', 'valid')): +def WikiText2(root='.data', data_select=('train', 'valid', 'test')): """ Defines WikiText2 datasets. Create language modeling dataset: WikiText2 @@ -64,8 +67,7 @@ def WikiText2(root='.data', data_select=('train', 'test', 'valid')): Arguments: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tupel for the returned datasets - (Default: ('train', 'test','valid')) + data_select: a string or tupel for the returned datasets. Default: ('train', 'valid, 'test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -74,7 +76,7 @@ def WikiText2(root='.data', data_select=('train', 'test', 'valid')): Examples: >>> from torchtext.experimental.raw.datasets import WikiText2 - >>> train_dataset, test_dataset, valid_dataset = WikiText2() + >>> train_dataset, valid_dataset, test_dataset = WikiText2() >>> valid_dataset, = WikiText2(data_select='valid') """ @@ -82,7 +84,7 @@ def WikiText2(root='.data', data_select=('train', 'test', 'valid')): return _setup_datasets("WikiText2", root, data_select, None, None) -def WikiText103(root='.data', data_select=('train', 'test', 'valid')): +def WikiText103(root='.data', data_select=('train', 'valid', 'test')): """ Defines WikiText103 datasets. Create language modeling dataset: WikiText103 @@ -90,7 +92,7 @@ def WikiText103(root='.data', data_select=('train', 'test', 'valid')): Arguments: root: Directory where the datasets are saved. Default: ".data" - data_select: the returned datasets (Default: ('train', 'test','valid')) + data_select: the returned datasets. Default: ('train', 'valid','test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test'). If 'train' is not in the tuple, an vocab object should be provided which will @@ -98,14 +100,14 @@ def WikiText103(root='.data', data_select=('train', 'test', 'valid')): Examples: >>> from torchtext.experimental.datasets.raw import WikiText103 - >>> train_dataset, test_dataset, valid_dataset = WikiText103() + >>> train_dataset, valid_dataset, test_dataset = WikiText103() >>> valid_dataset, = WikiText103(data_select='valid') """ return _setup_datasets("WikiText103", root, data_select, None, None) -def PennTreebank(root='.data', data_select=('train', 'test', 'valid')): +def PennTreebank(root='.data', data_select=('train', 'valid', 'test')): """ Defines PennTreebank datasets. Create language modeling dataset: PennTreebank @@ -115,7 +117,7 @@ def PennTreebank(root='.data', data_select=('train', 'test', 'valid')): root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets (Default: ('train', 'test','valid')) - By default, all the three datasets (train, test, valid) are generated. Users + By default, all the three datasets ('train', 'valid', 'test') are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test @@ -123,7 +125,7 @@ def PennTreebank(root='.data', data_select=('train', 'test', 'valid')): Examples: >>> from torchtext.experimental.datasets.raw import PennTreebank - >>> train_dataset, test_dataset, valid_dataset = PennTreebank() + >>> train_dataset, valid_dataset, test_dataset = PennTreebank() >>> valid_dataset, = PennTreebank(data_select='valid') """ @@ -156,8 +158,16 @@ def WMTNewsCrawl(root='.data', data_select=('train'), year=2010, language='en'): 'WMTNewsCrawl': WMTNewsCrawl } NUM_LINES = { - 'WikiText2': 36718, - 'WikiText103': 1801350, - 'PennTreebank': 42068, - 'WMTNewsCrawl': 17676013, + 'WikiText2': {'train': 36718, 'valid': 3760, 'test': 4358}, + 'WikiText103': {'train': 1801350, 'valid': 3760, 'test': 4358}, + 'PennTreebank': {'train': 42068, 'valid': 3370, 'test': 3761}, + 'WMTNewsCrawl': {'train': 17676013} +} +MD5 = { + 'WikiText2': '542ccefacc6c27f945fb54453812b3cd', + 'WikiText103': '9ddaacaf6af0710eda8c456decff7832', + 'PennTreebank': {'train': 'f26c4b92c5fdc7b3f8c7cdcb991d8420', + 'valid': 'aa0affc06ff7c36e977d7cd49e3839bf', + 'test': '8b80168b89c18661a38ef683c0dc3721'}, + 'WMTNewsCrawl': '64150a352f3abe890a87f6c6838524a6' } diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py index 4d80df96e9..71b63df5d5 100644 --- a/torchtext/experimental/datasets/raw/question_answer.py +++ b/torchtext/experimental/datasets/raw/question_answer.py @@ -31,9 +31,9 @@ def _create_data_from_json(data_path): def _setup_datasets(dataset_name, root, data_select): data_select = check_default_set(data_select, ('train', 'dev')) - extracted_files = {key: download_from_url(URLS[dataset_name][key], - root=root) for key in data_select} - return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], + extracted_files = {key: download_from_url(URLS[dataset_name][key], root=root, + hash_value=MD5[dataset_name][key], hash_type='md5') for key in data_select} + return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], _create_data_from_json(extracted_files[item])) for item in data_select) @@ -90,6 +90,10 @@ def SQuAD2(root='.data', data_select=('train', 'dev')): 'SQuAD2': SQuAD2 } NUM_LINES = { - 'SQuAD1': 87599, - 'SQuAD2': 130319 + 'SQuAD1': {'train': 87599, 'dev': 10570}, + 'SQuAD2': {'train': 130319, 'dev': 11873} +} +MD5 = { + 'SQuAD1': {'train': '981b29407e0affa3b1b156f72073b945', 'dev': '3e85deb501d4e538b6bc56f786231552'}, + 'SQuAD2': {'train': '62108c273c268d70893182d5cf8df740', 'dev': '246adae8b7002f8679c027697b0b7cf8'} } diff --git a/torchtext/experimental/datasets/raw/sequence_tagging.py b/torchtext/experimental/datasets/raw/sequence_tagging.py index e45688f07b..b584d147ab 100644 --- a/torchtext/experimental/datasets/raw/sequence_tagging.py +++ b/torchtext/experimental/datasets/raw/sequence_tagging.py @@ -5,10 +5,10 @@ URLS = { "UDPOS": 'https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip', - "CoNLL2000Chunking": [ - 'https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz', - 'https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz' - ] + "CoNLL2000Chunking": { + 'train': 'https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz', + 'test': 'https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz' + } } @@ -42,16 +42,16 @@ def _construct_filepath(paths, file_suffix): def _setup_datasets(dataset_name, separator, root, data_select): data_select = check_default_set(data_select, target_select=('train', 'valid', 'test')) extracted_files = [] - if isinstance(URLS[dataset_name], list): - for f in URLS[dataset_name]: - dataset_tar = download_from_url(f, root=root) + if isinstance(URLS[dataset_name], dict): + for name, item in URLS[dataset_name].items(): + dataset_tar = download_from_url(item, root=root, hash_value=MD5[dataset_name][name], hash_type='md5') extracted_files.extend(extract_archive(dataset_tar)) elif isinstance(URLS[dataset_name], str): - dataset_tar = download_from_url(URLS[dataset_name], root=root) + dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5[dataset_name], hash_type='md5') extracted_files.extend(extract_archive(dataset_tar)) else: raise ValueError( - "URLS for {} has to be in a form or list or string".format( + "URLS for {} has to be in a form of dictionary or string".format( dataset_name)) data_filenames = { @@ -59,7 +59,7 @@ def _setup_datasets(dataset_name, separator, root, data_select): "valid": _construct_filepath(extracted_files, "dev.txt"), "test": _construct_filepath(extracted_files, "test.txt") } - return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], + return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], _create_data_from_iob(data_filenames[item], separator)) if data_filenames[item] is not None else None for item in data_select) @@ -105,8 +105,11 @@ def CoNLL2000Chunking(root=".data", data_select=('train', 'test')): "UDPOS": UDPOS, "CoNLL2000Chunking": CoNLL2000Chunking } - NUM_LINES = { - "UDPOS": 12543, - "CoNLL2000Chunking": 8936 + "UDPOS": {'train': 12543, 'valid': 2002, 'test': 2077}, + "CoNLL2000Chunking": {'train': 8936, 'test': 2012} +} +MD5 = { + "UDPOS": 'bdcac7c52d934656bae1699541424545', + "CoNLL2000Chunking": {'train': '6969c2903a1f19a83569db643e43dcc8', 'test': 'a916e1c2d83eb3004b38fc6fcd628939'} } diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py index 5d114acf27..46ee16b982 100644 --- a/torchtext/experimental/datasets/raw/text_classification.py +++ b/torchtext/experimental/datasets/raw/text_classification.py @@ -36,17 +36,21 @@ def _create_data_from_csv(data_path): def _setup_datasets(dataset_name, root, data_select): data_select = check_default_set(data_select, target_select=('train', 'test')) if dataset_name == 'AG_NEWS': - extracted_files = [download_from_url(URLS[dataset_name][item], root=root) for item in ('train', 'test')] + extracted_files = [download_from_url(URLS[dataset_name][item], root=root, + hash_value=MD5['AG_NEWS'][item], + hash_type='md5') for item in ('train', 'test')] else: - dataset_tar = download_from_url(URLS[dataset_name], root=root) + dataset_tar = download_from_url(URLS[dataset_name], root=root, + hash_value=MD5[dataset_name], hash_type='md5') extracted_files = extract_archive(dataset_tar) + cvs_path = {} for fname in extracted_files: if fname.endswith('train.csv'): cvs_path['train'] = fname if fname.endswith('test.csv'): cvs_path['test'] = fname - return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], + return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], _create_data_from_csv(cvs_path[item])) for item in data_select) @@ -237,9 +241,10 @@ def IMDB(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.IMDB() """ data_select = check_default_set(data_select, target_select=('train', 'test')) - dataset_tar = download_from_url(URLS['IMDB'], root=root) + dataset_tar = download_from_url(URLS['IMDB'], root=root, + hash_value=MD5['IMDB'], hash_type='md5') extracted_files = extract_archive(dataset_tar) - return tuple(RawTextIterableDataset("IMDB", NUM_LINES["IMDB"], + return tuple(RawTextIterableDataset("IMDB", NUM_LINES["IMDB"][item], generate_imdb_data(item, extracted_files)) for item in data_select) @@ -256,13 +261,24 @@ def IMDB(root='.data', data_select=('train', 'test')): 'IMDB': IMDB } NUM_LINES = { - 'AG_NEWS': 120000, - 'SogouNews': 450000, - 'DBpedia': 560000, - 'YelpReviewPolarity': 560000, - 'YelpReviewFull': 650000, - 'YahooAnswers': 1400000, - 'AmazonReviewPolarity': 3600000, - 'AmazonReviewFull': 3000000, - 'IMDB': 25000 + 'AG_NEWS': {'train': 120000, 'test': 7600}, + 'SogouNews': {'train': 450000, 'test': 60000}, + 'DBpedia': {'train': 560000, 'test': 70000}, + 'YelpReviewPolarity': {'train': 560000, 'test': 38000}, + 'YelpReviewFull': {'train': 650000, 'test': 50000}, + 'YahooAnswers': {'train': 1400000, 'test': 60000}, + 'AmazonReviewPolarity': {'train': 3600000, 'test': 400000}, + 'AmazonReviewFull': {'train': 3000000, 'test': 650000}, + 'IMDB': {'train': 25000, 'test': 25000} +} +MD5 = { + 'AG_NEWS': {'train': 'b1a00f826fdfbd249f79597b59e1dc12', 'test': 'd52ea96a97a2d943681189a97654912d'}, + 'SogouNews': '0c1700ba70b73f964dd8de569d3fd03e', + 'DBpedia': 'dca7b1ae12b1091090db52aa7ec5ca64', + 'YelpReviewPolarity': '620c8ae4bd5a150b730f1ba9a7c6a4d3', + 'YelpReviewFull': 'f7ddfafed1033f68ec72b9267863af6c', + 'YahooAnswers': 'f3f9899b997a42beb24157e62e3eea8d', + 'AmazonReviewPolarity': 'fe39f8b653cada45afd5792e0f0e8f9b', + 'AmazonReviewFull': '57d28bd5d930e772930baddf36641c7c', + 'IMDB': '7c2ac02c03563afcf9b574c7e56c153a' } diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py index 4d01b68f11..c36f9abd87 100644 --- a/torchtext/experimental/datasets/raw/translation.py +++ b/torchtext/experimental/datasets/raw/translation.py @@ -3,8 +3,7 @@ import codecs import xml.etree.ElementTree as ET from collections import defaultdict -from torchtext.utils import (download_from_url, extract_archive, - unicode_csv_reader) +from torchtext.utils import (download_from_url, extract_archive) from torchtext.experimental.datasets.raw.common import RawTextIterableDataset from torchtext.experimental.datasets.raw.common import check_default_set @@ -69,9 +68,8 @@ def _read_text_iterator(path): with io.open(path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield " ".join(row) + for row in f: + yield row def _clean_xml_file(f_xml): @@ -129,11 +127,11 @@ def _setup_datasets(dataset_name, extracted_files = [] if isinstance(URLS[dataset_name], list): - for f in URLS[dataset_name]: - dataset_tar = download_from_url(f, root=root) + for idx, f in enumerate(URLS[dataset_name]): + dataset_tar = download_from_url(f, root=root, hash_value=MD5[dataset_name][idx], hash_type='md5') extracted_files.extend(extract_archive(dataset_tar)) elif isinstance(URLS[dataset_name], str): - dataset_tar = download_from_url(URLS[dataset_name], root=root) + dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5[dataset_name], hash_type='md5') extracted_files.extend(extract_archive(dataset_tar)) else: raise ValueError( @@ -174,7 +172,7 @@ def _iter(src_data_iter, tgt_data_iter): yield item datasets.append( - RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name], _iter(src_data_iter, tgt_data_iter))) + RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][key], _iter(src_data_iter, tgt_data_iter))) return tuple(datasets) @@ -251,7 +249,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), root: Directory where the datasets are saved. Default: ".data" Examples: - >>> from torchtext.datasets import Multi30k + >>> from torchtext.experimental.datasets.raw import Multi30k >>> train_dataset, valid_dataset, test_dataset = Multi30k() """ return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, data_select, root) @@ -417,7 +415,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), root: Directory where the datasets are saved. Default: ".data" Examples: - >>> from torchtext.datasets.raw import IWSLT + >>> from torchtext.experimental.datasets.raw import IWSLT >>> train_dataset, valid_dataset, test_dataset = IWSLT() """ src_language = train_filenames[0].split(".")[-1] @@ -503,7 +501,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', root: Directory where the datasets are saved. Default: ".data" Examples: - >>> from torchtext.datasets import WMT14 + >>> from torchtext.experimental.datasets.raw import WMT14 >>> train_dataset, valid_dataset, test_dataset = WMT14() """ return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, data_select, root) @@ -515,7 +513,60 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', 'WMT14': WMT14 } NUM_LINES = { - 'Multi30k': 29000, - 'IWSLT': 173939, - 'WMT14': 4500966, + 'Multi30k': {'train': 29000, 'valid': 1014, 'test': 1000}, + 'IWSLT': {'train': 196884, 'valid': 993, 'test': 1305}, + 'WMT14': {'train': 4500966, 'valid': 3000, 'test': 3003} +} +MD5 = { + 'Multi30k': ['3104872229daa1bef3b401d44dd2220b', + 'efd67d314d98489b716b145475101932', + 'ff2c0fcb4893a13bd73414306bc250ae', + '08dc7cd4a662f31718412de95ca9bfe3', + '6a8d5c87f6ae19e3d35681aa6fd16571', + '005396bac545d880abe6f00bbb7dbbb4', + 'cb09af7d2b501f9112f2d6a59fa1360d', + 'e8cd6ec2bc8a11fc846fa48a46e3d0bb', + 'a7b684e0edbef1d4a23660c8e8e743fd', + '4995d10954a804d3cdfd907b9fd093e8', + 'a152878809942757a55ce087073486b8', + 'd9a5fc268917725a2b0efce3a0cc8607', + '81ff90b99829c0cd4b1b587d394afd39', + '0065d13af80720a55ca8153d126e6627', + '6cb767741dcad3931f966fefbc05203f', + '83cdc082f646b769095615384cf5c0ca', + '6e0e229eb049e3fc99a1ef02fb2d5f91', + '2b69aa9253948ac9f67e94917272dd40', + '93fc564584b7e5ba410c761ea5a1c682', + 'ac0c72653c140dd96707212a1baa4278', + 'eec05227daba4bb8f3f8f25b1cb335f4', + '6dfb42cae4e4fd9a3c40e62ff5398a55', + '9318fa08c0c0b96114eadb10eb2fc633', + 'ece8cec6b87bf00dd12607f3062dae4c', + '088ec0765fa213a0eb937a62adfd4996', + '9a7e7b2dcc33135a32cd621c3b37d2d8', + '5f7c8d0be0ac739856b47d32a9434998', + '7d5ef0f069ee2d74dc2fdc6b46cd47fa', + '713ed720636622a54546d5f14f88b00f', + '62f36422bfab90fb42a560546b704009', + 'cbf5bfc2147706f228d288e1b18bf4af', + '540da4566bb6dd35fdbc720218b742b7', + 'bdfe4222f4692ccaa1e3389460f0890e', + '613eb4a3f0c2b13f0871ced946851b0e', + '0e1ee2b4145795bd180b193424db204b', + 'd848fe0ae8b9447209fb49c5c31cb3d2', + '1cff688d1aadef7fdb22e9ad27d6fd2c', + 'abc13b4042f4fef1cdff6de3b6c53b71', + '3e10289959d0059952511c31df3c7550', + 'b26486ede1d4436d5acf6e38c65bb44d', + 'df57faf5f00d434d2559c021ef55f1aa', + '16165248083beacebfe18866d5f4f0ae', + '9077a5127480cc799116384de501bd70', + '7180780822d4b600eb81c1ccf171c230', + 'c1f697c3b6dfb7305349db34e26b45fc', + '8edb43c90cae66ec762748a968089b99', + 'acb5ea26a577ceccfae6337181c31716', + '873a377a348713d3ab84db1fb57cdede', + '680816e0938fea5cf5331444bc09a4cf'], + 'IWSLT': '6ff9ab8ea16fb352597c2784e0391fa8', + 'WMT14': '874ab6bbfe9c21ec987ed1b9347f95ec' } diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index 7bed1f647b..3c0448e292 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -1,4 +1,5 @@ import torch +import logging from torchtext.experimental.datasets.raw.common import check_default_set from torchtext.experimental.datasets import raw from torchtext.vocab import build_vocab_from_iterator @@ -8,6 +9,8 @@ sequential_transforms, ) +logger_ = logging.getLogger(__name__) + def build_vocab(data): total_columns = len(data[0]) @@ -33,6 +36,7 @@ def _setup_datasets(dataset_name, root, vocabs, data_select): if vocabs is None: if "train" not in data_select: raise TypeError("Must pass a vocab if train is not selected.") + logger_.info('Building Vocab based on train data') vocabs = build_vocab(raw_data["train"]) else: if not isinstance(vocabs, list): @@ -54,18 +58,22 @@ def _setup_datasets(dataset_name, root, vocabs, data_select): totensor(dtype=torch.long)) for idx in range(len(vocabs)) ] + logger_.info('Building datasets for {}'.format(data_select)) return tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in data_select) class SequenceTaggingDataset(torch.utils.data.Dataset): """Defines an abstraction for raw text sequence tagging iterable datasets. + Currently, we only support the following datasets: + - UDPOS - CoNLL2000Chunking """ def __init__(self, data, vocabs, transforms): """Initiate sequence tagging dataset. + Arguments: data: a list of word and its respective tags. Example: [[word, POS, dep_parsing label, ...]] @@ -74,7 +82,7 @@ def __init__(self, data, vocabs, transforms): found in the data. transforms: a list of string transforms for words and tags. The number of transforms must be the same as the number of columns - found in the data. + found in the data. """ super(SequenceTaggingDataset, self).__init__() @@ -122,6 +130,7 @@ def UDPOS(root=".data", vocabs=None, data_select=("train", "valid", "test")): >>> from torchtext.datasets.raw import UDPOS >>> train_dataset, valid_dataset, test_dataset = UDPOS() """ + return _setup_datasets("UDPOS", root, vocabs, data_select) @@ -147,6 +156,7 @@ def CoNLL2000Chunking(root=".data", vocabs=None, data_select=("train", "test")): >>> from torchtext.datasets.raw import CoNLL2000Chunking >>> train_dataset, test_dataset = CoNLL2000Chunking() """ + return _setup_datasets("CoNLL2000Chunking", root, vocabs, data_select) diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index 4374ad2594..1ba9819f9b 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -1,4 +1,5 @@ import torch +import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.datasets.raw import text_classification as raw @@ -10,6 +11,8 @@ sequential_transforms, ) +logger_ = logging.getLogger(__name__) + def build_vocab(data, transforms): def apply_transforms(data): @@ -21,14 +24,15 @@ def apply_transforms(data): class TextClassificationDataset(torch.utils.data.Dataset): """Defines an abstract text classification datasets. Currently, we only support the following datasets: - - AG_NEWS - - SogouNews - - DBpedia - - YelpReviewPolarity - - YelpReviewFull - - YahooAnswers - - AmazonReviewPolarity - - AmazonReviewFull + + - AG_NEWS + - SogouNews + - DBpedia + - YelpReviewPolarity + - YelpReviewFull + - YahooAnswers + - AmazonReviewPolarity + - AmazonReviewFull """ def __init__(self, data, vocab, transforms): @@ -71,17 +75,16 @@ def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, data_select): tokenizer = get_tokenizer("basic_english") text_transform = sequential_transforms(tokenizer, ngrams_func(ngrams)) data_select = check_default_set(data_select, ('train', 'test')) - train, test = raw.DATASETS[dataset_name](root=root) - # Cache raw text iterable dataset - raw_data = { - "train": [(label, txt) for (label, txt) in train], - "test": [(label, txt) for (label, txt) in test], - } + raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select) + # Materialize raw text iterable dataset + raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(data_select, raw_datasets)} if vocab is None: if "train" not in data_select: raise TypeError("Must pass a vocab if train is not selected.") + logger_.info('Building Vocab based on train data') vocab = build_vocab(raw_data["train"], text_transform) + logger_.info('Vocab has %d entries', len(vocab)) text_transform = sequential_transforms( text_transform, vocab_func(vocab), totensor(dtype=torch.long) ) @@ -89,6 +92,7 @@ def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, data_select): label_transform = sequential_transforms(lambda x: 1 if x == 'pos' else 0, totensor(dtype=torch.long)) else: label_transform = sequential_transforms(totensor(dtype=torch.long)) + logger_.info('Building datasets for {}'.format(data_select)) return tuple( TextClassificationDataset( raw_data[item], vocab, (label_transform, text_transform) diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index 8f1473e933..abd626d2ec 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -6,6 +6,8 @@ from torchtext.data.utils import get_tokenizer from ..functional import vocab_func, totensor, sequential_transforms +logger_ = logging.getLogger(__name__) + def build_vocab(data, transforms, index): def apply_transforms(data): @@ -32,43 +34,39 @@ def _setup_datasets(dataset_name, raise ValueError( "tokenizer must be an instance of tuple with length two" "or None") - train, val, test = raw.DATASETS[dataset_name](train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - root=root) - raw_data = { - "train": [line for line in train], - "valid": [line for line in val], - "test": [line for line in test] - } + raw_datasets = raw.DATASETS[dataset_name](train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames, + data_select=data_select, root=root) + raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(data_select, raw_datasets)} src_text_vocab_transform = sequential_transforms(src_tokenizer) tgt_text_vocab_transform = sequential_transforms(tgt_tokenizer) if src_vocab is None: if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - logging.info('Building src Vocab based on train data') + logger_.info('Building src Vocab based on train data') src_vocab = build_vocab(raw_data["train"], src_text_vocab_transform, index=0) else: if not isinstance(src_vocab, Vocab): raise TypeError("Passed src vocabulary is not of type Vocab") - logging.info('src Vocab has {} entries'.format(len(src_vocab))) + logger_.info('src Vocab has %d entries', len(src_vocab)) if tgt_vocab is None: if 'train' not in data_select: raise TypeError("Must pass a vocab if train is not selected.") - logging.info('Building tgt Vocab based on train data') + logger_.info('Building tgt Vocab based on train data') tgt_vocab = build_vocab(raw_data["train"], tgt_text_vocab_transform, index=1) else: if not isinstance(tgt_vocab, Vocab): raise TypeError("Passed tgt vocabulary is not of type Vocab") - logging.info('tgt Vocab has {} entries'.format(len(tgt_vocab))) + logger_.info('tgt Vocab has %d entries', len(tgt_vocab)) - logging.info('Building datasets for {}'.format(data_select)) + logger_.info('Building datasets for {}'.format(data_select)) datasets = [] for key in data_select: src_text_transform = sequential_transforms(src_text_vocab_transform, @@ -86,10 +84,12 @@ def _setup_datasets(dataset_name, class TranslationDataset(torch.utils.data.Dataset): """Defines a dataset for translation. - Currently, we only support the following datasets: - - Multi30k - - WMT14 - - IWSLT + + Currently, we only support the following datasets: + + - Multi30k + - WMT14 + - IWSLT """ def __init__(self, data, vocab, transforms): @@ -141,7 +141,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), tokenizer=None): """ Define translation datasets: Multi30k - Separately returns train/valid/test datasets as a tuple + Separately returns train/valid/test datasets as a tuple Arguments: train_filenames: the source and target filenames for training. @@ -163,9 +163,10 @@ def Multi30k(train_filenames=("train.de", "train.en"), tokenizer: the tokenizer used to preprocess source and target raw text data. It has to be in a form of tuple. Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) + get_tokenizer("spacy", language='en_core_web_sm')) The available dataset include: + test_2016_flickr.cs test_2016_flickr.de test_2016_flickr.en @@ -217,7 +218,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), val.5.en Examples: - >>> from torchtext.datasets import Multi30k + >>> from torchtext.experimental.datasets import Multi30k >>> from torchtext.data.utils import get_tokenizer >>> tokenizer = (get_tokenizer("spacy", language='de'), get_tokenizer("basic_english")) @@ -225,6 +226,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] """ + return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, data_select, root, vocab, tokenizer) @@ -240,8 +242,8 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), tokenizer=None): """ Define translation datasets: IWSLT - Separately returns train/valid/test datasets - The available datasets include: + Separately returns train/valid/test datasets + The available datasets include: Arguments: train_filenames: the source and target filenames for training. @@ -263,9 +265,10 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), tokenizer: the tokenizer used to preprocess source and target raw text data. It has to be in a form of tuple. Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) + get_tokenizer("spacy", language='en_core_web_sm')) The available datasets include: + IWSLT16.TED.dev2010.ar-en.ar IWSLT16.TED.dev2010.ar-en.en IWSLT16.TED.dev2010.cs-en.cs @@ -403,7 +406,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), train.tags.fr-en.fr Examples: - >>> from torchtext.datasets import IWSLT + >>> from torchtext.experimental.datasets import IWSLT >>> from torchtext.data.utils import get_tokenizer >>> src_tokenizer = get_tokenizer("spacy", language='de') >>> tgt_tokenizer = get_tokenizer("basic_english") @@ -412,6 +415,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] """ + return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, data_select, root, vocab, tokenizer) @@ -428,8 +432,9 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', tokenizer=None): """ Define translation datasets: WMT14 - Separately returns train/valid/test datasets - The available datasets include: + Separately returns train/valid/test datasets + The available datasets include: + newstest2016.en newstest2016.de newstest2015.en @@ -501,10 +506,10 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', tokenizer: the tokenizer used to preprocess source and target raw text data. It has to be in a form of tuple. Default: (get_tokenizer("spacy", language='de_core_news_sm'), - get_tokenizer("spacy", language='en_core_web_sm')) + get_tokenizer("spacy", language='en_core_web_sm')) Examples: - >>> from torchtext.datasets import WMT14 + >>> from torchtext.experimental.datasets import WMT14 >>> from torchtext.data.utils import get_tokenizer >>> src_tokenizer = get_tokenizer("spacy", language='de') >>> tgt_tokenizer = get_tokenizer("basic_english") @@ -513,6 +518,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] """ + return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, data_select, root, vocab, tokenizer) diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 011f1bf165..6c3896aa61 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -31,6 +31,7 @@ def basic_english_normalize(): Normalization includes - lowercasing - complete some basic text normalization for English words as follows: + - add spaces before and after '\'' - remove '\"', - add spaces before and after '.' @@ -52,6 +53,7 @@ def basic_english_normalize(): >>> jit_basic_eng_norm = torch.jit.script(basic_eng_norm.to_ivalue()) >>> tokens = jit_basic_eng_norm(test_sample) """ + patterns_list = [ (r'\'', ' \' '), (r'\"', ''), @@ -89,6 +91,7 @@ def regex_tokenizer(patterns_list): >>> jit_reg_tokenizer = torch.jit.script(reg_tokenizer) >>> tokens = jit_reg_tokenizer(test_sample) """ + patterns = [pair[0] for pair in patterns_list] replacements = [pair[1] for pair in patterns_list] return RegexTokenizer(RegexTokenizerPybind(patterns, replacements, False)) @@ -101,6 +104,7 @@ class BasicEnglishNormalize(nn.Module): Args: regex_tokenizer (torch.classes.torchtext.RegexTokenizer or torchtext._torchtext.RegexTokenizer): a cpp regex tokenizer object. """ + def __init__(self, regex_tokenizer): super(BasicEnglishNormalize, self).__init__() self.regex_tokenizer = regex_tokenizer @@ -117,11 +121,13 @@ def forward(self, line: str) -> List[str]: Returns: List[str]: a token list after normalizing and splitting on whitespace. """ + return self.regex_tokenizer.forward(line) def to_ivalue(self): r"""Return a JITable BasicEnglishNormalize. """ + regex_tokenizer = torch.classes.torchtext.RegexTokenizer(self.regex_tokenizer.patterns_, self.regex_tokenizer.replacements_, True) return BasicEnglishNormalize(regex_tokenizer) @@ -133,6 +139,7 @@ class RegexTokenizer(nn.Module): Args: regex_tokenizer (torch.classes.torchtext.RegexTokenizer or torchtext._torchtext.RegexTokenizer): a cpp regex tokenizer object. """ + def __init__(self, regex_tokenzier): super(RegexTokenizer, self).__init__() self.regex_tokenizer = regex_tokenzier @@ -149,17 +156,20 @@ def forward(self, line: str) -> List[str]: Returns: List[str]: a token list after regex. """ + return self.regex_tokenizer.forward(line) def to_ivalue(self): r"""Return a JITable RegexTokenizer. """ + regex_tokenizer = torch.classes.torchtext.RegexTokenizer(self.regex_tokenizer.patterns_, self.regex_tokenizer.replacements_, False) return RegexTokenizer(regex_tokenizer) class TextSequentialTransforms(nn.Sequential): r"""A container to host a sequential text transforms. + Example: >>> import torch >>> from torchtext.experimental.transforms import basic_english_normalize, TextSequentialTransforms @@ -169,6 +179,7 @@ class TextSequentialTransforms(nn.Sequential): ['here', 'is', 'an', 'example'] >>> jit_txt_pipeline = torch.jit.script(txt_pipeline.to_ivalue()) """ + def forward(self, input: str): for module in self: input = module(input) @@ -177,6 +188,7 @@ def forward(self, input: str): def to_ivalue(self): r"""Return a JITable TextSequentialTransforms. """ + module_list = [] for _idx, _module in enumerate(self): if hasattr(_module, 'to_ivalue'): @@ -213,6 +225,7 @@ def load_sp_model(sp_model): details please refer to SentencePiece GitHub https://github.com/google/sentencepiece). We also provide the pretrained model with a different size of the vocabulary (i.e. 15000, 25000, 50000). The following pretrained sentencepiece models are provided: + - text_unigram_15000 - text_unigram_25000 - text_unigram_50000 @@ -225,6 +238,7 @@ def load_sp_model(sp_model): >>> sp_model_path = torchtext.utils.download_from_url(PRETRAINED_SP_MODEL['text_unigram_25000']) >>> sp_model = load_sp_model(sp_model_path) """ + if isinstance(sp_model, str): with open(sp_model, 'rb') as f: return SentencePiecePybind(f.read()) @@ -251,6 +265,7 @@ def sentencepiece_tokenizer(sp_model): >>> spm_tokenizer = sentencepiece_tokenizer('m_user.model') >>> jit_spm_tokenizer = torch.jit.script(spm_tokenizer.to_ivalue()) """ + spm = load_sp_model(sp_model) return SentencePieceTokenizer(spm) @@ -277,6 +292,7 @@ def forward(self, line: str) -> List[str]: Note: SentencePiece treats the input text just as a sequence of Unicode characters. Whitespace is also handled as a normal symbol. To handle the whitespace as a basic token explicitly, SentencePiece first escapes the whitespace with a meta symbol "▁" (U+2581) as follows. """ + return self.sp_model.EncodeAsPieces(line) @torch.jit.export @@ -289,6 +305,7 @@ def decode(self, tokens: List[str]) -> str: >>> spm_transform.decoder(['▁the', '▁pre', 'trained', '▁sp', '▁model', '▁names']) >>> 'the pretrained sp model names' """ + return self.sp_model.DecodePieces(tokens) def to_ivalue(self): @@ -308,6 +325,7 @@ def sentencepiece_processor(sp_model): >>> spm_processor = sentencepiece_processor('m_user.model') >>> jit_spm_processor = torch.jit.script(spm_processor.to_ivalue()) """ + spm = load_sp_model(sp_model) return SentencePieceProcessor(spm) @@ -332,6 +350,7 @@ def forward(self, line: str) -> List[int]: >>> spm_processor('the pretrained sp model names') >>> [9, 1546, 18811, 2849, 2759, 2202] """ + return self.sp_model.EncodeAsIds(line) @torch.jit.export @@ -344,6 +363,7 @@ def decode(self, ids: List[int]) -> str: >>> spm_processor.decoder([9, 1546, 18811, 2849, 2759, 2202]) >>> 'the pretrained sp model names' """ + return self.sp_model.DecodeIds(ids) def to_ivalue(self): @@ -379,6 +399,7 @@ def forward(self, tokens: List[str]) -> List[int]: >>> vocab_transform(['here', 'is', 'an', 'example']) """ + return self.vocab.lookup_indices(tokens) def to_ivalue(self): @@ -415,6 +436,7 @@ def forward(self, tokens: List[str]) -> Tensor: >>> vector_transform(['here', 'is', 'an', 'example']) """ + return self.vector.lookup_vectors(tokens) def to_ivalue(self): diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index 61b1e20ec4..a606e12bcc 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -17,8 +17,8 @@ __all__ = [ 'FastText', 'GloVe', - 'vectors_from_file_object', - 'vectors', + 'load_vectors_from_file_path', + 'build_vectors', 'Vectors' ] @@ -65,21 +65,30 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru Args: name (str): the name of the GloVe dataset to use. Options are: + - 42B - 840B - twitter.27B - 6B dim (int): the dimension for the GloVe dataset to load. Options are: + 42B: + - 300 + 840B: + - 300 + twitter.27B: + - 25 - 50 - 100 - 200 + 6B: + - 50 - 100 - 200 @@ -144,8 +153,8 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru return vectors_obj -def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None, num_cpus=10): - r"""Create a Vectors object from a csv file like object. +def load_vectors_from_file_path(filepath, delimiter=",", unk_tensor=None, num_cpus=10): + r"""Create a Vectors object from a csv file path. Note that the tensor corresponding to each vector is of type `torch.float`. @@ -156,7 +165,7 @@ def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None, n token_nnum_m num_j num_k Args: - file_like_object (FileObject): a file like object to read data from. + filepath: a file path to read data from. delimiter (char): a character to delimit between the token and the vector. Default value is "," unk_tensor (Tensor): a 1d tensor representing the vector associated with an unknown token. num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. @@ -168,13 +177,13 @@ def vectors_from_file_object(file_like_object, delimiter=",", unk_tensor=None, n ValueError: if duplicate tokens are found in FastText file. """ - vectors_obj, dup_tokens = _load_token_and_vectors_from_file(file_like_object.name, delimiter, num_cpus, unk_tensor) + vectors_obj, dup_tokens = _load_token_and_vectors_from_file(filepath, delimiter, num_cpus, unk_tensor) if dup_tokens: raise ValueError("Found duplicate tokens in file: {}".format(str(dup_tokens))) return Vectors(vectors_obj) -def vectors(tokens, vectors, unk_tensor=None): +def build_vectors(tokens, vectors, unk_tensor=None): r"""Factory method for creating a vectors object which maps tokens to vectors. Arguments: tokens (List[str]): a list of tokens. diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 5fdf5751ec..a7707003ee 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -7,19 +7,19 @@ from torchtext._torchtext import ( Vocab as VocabPybind, _load_vocab_from_file, - _load_vocab_from_raw_text_file + _build_vocab_from_text_file ) __all__ = [ - 'vocab_from_raw_text_file', - 'vocab_from_file', + 'build_vocab_from_text_file', + 'load_vocab_from_file', 'vocab', 'Vocab', ] logger = logging.getLogger(__name__) -def vocab_from_raw_text_file(file_object, jited_tokenizer, min_freq=1, unk_token='', num_cpus=4): +def build_vocab_from_text_file(file_object, jited_tokenizer, min_freq=1, unk_token='', num_cpus=4): r"""Create a `Vocab` object from a raw text file. The `file_object` can contain any raw text. This function applies a generic JITed tokenizer in @@ -38,27 +38,29 @@ def vocab_from_raw_text_file(file_object, jited_tokenizer, min_freq=1, unk_token Vocab: a `Vocab` object. Examples: - >>> from torchtext.experimental.vocab import vocab_from_raw_text_file + >>> from torchtext.experimental.vocab import build_vocab_from_text_file >>> from torchtext.experimental.transforms import basic_english_normalize >>> f = open('vocab.txt', 'r') >>> tokenizer = basic_english_normalize() >>> tokenizer = basic_english_normalize() >>> jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) - >>> v = vocab_from_raw_text_file(f, jit_tokenizer) + >>> v = build_vocab_from_text_file(f, jit_tokenizer) """ - vocab_obj = _load_vocab_from_raw_text_file(file_object.name, unk_token, min_freq, num_cpus, jited_tokenizer) + vocab_obj = _build_vocab_from_text_file(file_object.name, unk_token, min_freq, num_cpus, jited_tokenizer) return Vocab(vocab_obj) -def vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4): +def load_vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4): r"""Create a `Vocab` object from a text file. The `file_object` should contain tokens separated by new lines. Note that the vocab will be created in the order that the tokens first appear in the file (and not by the frequency of tokens). Format for txt file: + token1 token2 ... token_n + Args: file_object (FileObject): a file like object to read data from. min_freq: The minimum frequency needed to include a token in the vocabulary. @@ -68,11 +70,13 @@ def vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4): Returns: Vocab: a `Vocab` object. + Examples: - >>> from torchtext.experimental.vocab import vocab_from_file + >>> from torchtext.experimental.vocab import load_vocab_from_file >>> f = open('vocab.txt', 'r') - >>> v = vocab_from_file(f) + >>> v = load_vocab_from_file(f) """ + vocab_obj = _load_vocab_from_file(file_object.name, unk_token, min_freq, num_cpus) return Vocab(vocab_obj) @@ -80,6 +84,7 @@ def vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4): def build_vocab_from_iterator(iterator, min_freq=1, unk_token=''): """ Build a Vocab from an iterator. + Arguments: iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. min_freq: The minimum frequency needed to include a token in the vocabulary. @@ -122,6 +127,7 @@ def vocab(ordered_dict, min_freq=1, unk_token=''): >>> tokens = ['e', 'd', 'c', 'b', 'a'] >>> v2 = vocab(OrderedDict([(token, 1) for token in tokens])) """ + if not unk_token: raise ValueError("A default unk token wasn't provided.") diff --git a/torchtext/nn/modules/multiheadattention.py b/torchtext/nn/modules/multiheadattention.py index 4ce2a23bc0..08b19f563e 100644 --- a/torchtext/nn/modules/multiheadattention.py +++ b/torchtext/nn/modules/multiheadattention.py @@ -206,6 +206,7 @@ def __init__(self, query_proj, key_proj, value_proj): query_proj: a proj layer for query. key_proj: a proj layer for key. value_proj: a proj layer for value. + """ super(InProjContainer, self).__init__() @@ -224,8 +225,10 @@ def forward(self, Shape: - query, key, value: :math:`(S, N, E)` - - Output: :math:`(S, N, E)` - where S is the sequence length, N is the batch size, and E is the embedding dimension. + - Output: :math:`(S, N, E)`. + + Note: S is the sequence length, N is the batch size, and E is the embedding dimension. + """ return self.query_proj(query), self.key_proj(key), self.value_proj(value) diff --git a/torchtext/vocab.py b/torchtext/vocab.py index 59f63105b5..fe5101d16d 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -49,7 +49,7 @@ def __init__(self, counter, max_size=None, min_freq=1, specials=('', ' or a list of aforementioned vectors unk_init (callback): by default, initialize out-of-vocabulary word vectors to zero vectors; can be any function that takes in a Tensor and - returns a Tensor of the same size. Default: torch.Tensor.zero_ + returns a Tensor of the same size. Default: 'torch.zeros' vectors_cache: directory for cached vectors. Default: '.vector_cache' specials_first: Whether to add special tokens into the vocabulary at first. If it is False, they are added into the vocabulary at last. @@ -153,6 +153,7 @@ def load_vectors(self, vectors, **kwargs): vectors: one of or a list containing instantiations of the GloVe, CharNGram, or Vectors classes. Alternatively, one of or a list of available pretrained vectors: + charngram.100d fasttext.en.300d fasttext.simple.300d @@ -166,6 +167,7 @@ def load_vectors(self, vectors, **kwargs): glove.6B.100d glove.6B.200d glove.6B.300d + Remaining keyword arguments: Passed to the constructor of Vectors classes. """ if not isinstance(vectors, list): @@ -209,7 +211,7 @@ def set_vectors(self, stoi, vectors, dim, unk_init=torch.Tensor.zero_): dim: The dimensionality of the vectors. unk_init (callback): by default, initialize out-of-vocabulary word vectors to zero vectors; can be any function that takes in a Tensor and - returns a Tensor of the same size. Default: torch.Tensor.zero_ + returns a Tensor of the same size. Default: 'torch.zeros' """ self.vectors = torch.Tensor(len(self), dim) for i, token in enumerate(self.itos): @@ -239,7 +241,7 @@ def __init__(self, counter, max_size=None, specials=(''), or a list of aforementioned vectors unk_init (callback): by default, initialize out-of-vocabulary word vectors to zero vectors; can be any function that takes in a Tensor and - returns a Tensor of the same size. Default: torch.Tensor.zero_ + returns a Tensor of the same size. Default: 'torch.zeros """ try: import revtok @@ -300,20 +302,21 @@ def __init__(self, name, cache=None, url=None, unk_init=None, max_vectors=None): """ Arguments: - name: name of the file that contains the vectors - cache: directory for cached vectors - url: url for download if vectors not found in cache - unk_init (callback): by default, initialize out-of-vocabulary word vectors - to zero vectors; can be any function that takes in a Tensor and - returns a Tensor of the same size - max_vectors (int): this can be used to limit the number of - pre-trained vectors loaded. - Most pre-trained vector sets are sorted - in the descending order of word frequency. - Thus, in situations where the entire set doesn't fit in memory, - or is not needed for another reason, passing `max_vectors` - can limit the size of the loaded set. + + name: name of the file that contains the vectors + cache: directory for cached vectors + url: url for download if vectors not found in cache + unk_init (callback): by default, initialize out-of-vocabulary word vectors + to zero vectors; can be any function that takes in a Tensor and returns a Tensor of the same size + max_vectors (int): this can be used to limit the number of + pre-trained vectors loaded. + Most pre-trained vector sets are sorted + in the descending order of word frequency. + Thus, in situations where the entire set doesn't fit in memory, + or is not needed for another reason, passing `max_vectors` + can limit the size of the loaded set. """ + cache = '.vector_cache' if cache is None else cache self.itos = None self.stoi = None From d1686a9f8c5885aea4ed4e91745e249c9c02988b Mon Sep 17 00:00:00 2001 From: Brian Hirsh Date: Wed, 2 Dec 2020 11:09:12 -0800 Subject: [PATCH 33/68] Updating all call-sites of the legacy dispatcher registration API in fbcode to the new API. (#48178) Summary: Pull Request resolved: https://github.com/pytorch/pytorch/pull/48178 I migrated all call sites that used the legacy dispatcher registration API (RegisterOperators()) to use the new API (TORCH_LIBRARY...). I found all call-sites by running `fbgs RegisterOperators()`. This includes several places, including other OSS code (nestedtensor, torchtext, torchvision). A few things to call out: For simple ops that only had one registered kernel without a dispatch key, I replaced them with: ``` TORCH_LIBRARY_FRAGMENT(ns, m) { m.def("opName", fn_name); } ``` For ops that registered to a specific dispatch key / had multiple kernels registered, I registered the common kernel (math/cpu) directly inside a `TORCH_LIBRARY_FRAGMENT` block, and registered any additional kernels from other files (e.g. cuda) in a separate `TORCH_LIBRARY_IMPL` block. ``` // cpu file TORCH_LIBRARY_FRAGMENT(ns, m) { m.def("opName(schema_inputs) -> schema_outputs"); m.impl("opName", torch::dispatch(c10::DispatchKey::CPU, TORCH_FN(cpu_kernel))); } // cuda file TORCH_LIBRARY_IMPL(ns, CUDA, m) { m.impl("opName", torch::dispatch(c10::DispatchKey::CUDA, TORCH_FN(cuda_kernel))); } ``` Special cases: I found a few ops that used a (legacy) `CPUTensorId`/`CUDATensorId` dispatch key. Updated those to use CPU/CUDA- this seems safe because the keys are aliased to one another in `DispatchKey.h` There were a handful of ops that registered a functor (function class) to the legacy API. As far as I could tell we don't allow this case in the new API, mainly because you can accomplish the same thing more cleanly with lambdas. Rather than delete the class I wrote a wrapper function on top of the class, which I passed to the new API. There were a handful of ops that were registered only to a CUDA dispatch key. I put them inside a TORCH_LIBRARY_FRAGMENT block, and used a `def()` and `impl()` call like in case two above. Test Plan: Imported from OSS Reviewed By: ezyang Differential Revision: D25056090 Pulled By: bdhirsh fbshipit-source-id: 8f868b45f545e5da2f21924046e786850eba70d9 --- torchtext/csrc/register_bindings.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 6cc192c9b4..6f77e8e3b8 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -5,6 +5,7 @@ #include // @manual #include // @manual #include +#include // @manual #include // @manual #include // @manual @@ -174,16 +175,14 @@ static auto vectors = }); // Registers our custom op with torch. -static auto registry = - torch::RegisterOperators() - .op("torchtext::generate_sp_model", &generate_sp_model) - .op(torch::RegisterOperators::options() - .schema("torchtext::load_sp_model(str path) -> " - "__torch__.torch.classes.torchtext.SentencePiece model") - .catchAllKernel()) - .op(torch::RegisterOperators::options() - .schema("torchtext::load_sp_model_string(str content) -> " - "__torch__.torch.classes.torchtext.SentencePiece model") - .catchAllKernel()); +TORCH_LIBRARY_FRAGMENT(torchtext, m) { + m.def("generate_sp_model", generate_sp_model); + m.def("load_sp_model(str path) -> " + "__torch__.torch.classes.torchtext.SentencePiece model", + load_sp_model); + m.def("load_sp_model_string(str content) -> " + "__torch__.torch.classes.torchtext.SentencePiece model", + load_sp_model_string); +} + } // namespace torchtext From e22375e456ecb745305dc23bd4649987ce811f4c Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Mon, 11 Jan 2021 15:15:45 -0800 Subject: [PATCH 34/68] Import torchtext from github into fbcode on 1/11/2021 Reviewed By: cpuhrsch Differential Revision: D25873762 fbshipit-source-id: 0d34d36aeb8e7e2ce72fcf345c5e7e713ef3663c --- README.rst | 4 +- .../text_classification/iterable_train.py | 8 +- examples/text_classification/model.py | 2 +- examples/text_classification/predict.py | 2 +- examples/text_classification/train.py | 4 +- packaging/torchtext/meta.yaml | 1 + test/data/test_batch.py | 4 +- test/data/test_builtin_datasets.py | 34 +++ test/data/test_functional.py | 61 +++- test/experimental/test_transforms.py | 24 ++ test/experimental/test_vectors.py | 40 ++- test/experimental/test_vocab.py | 19 +- torchtext/csrc/regex.cpp | 8 + torchtext/csrc/regex.h | 4 + torchtext/csrc/regex_tokenizer.cpp | 11 + torchtext/csrc/regex_tokenizer.h | 6 + torchtext/csrc/register_bindings.cpp | 286 ++++++++++-------- torchtext/csrc/vectors.cpp | 4 +- torchtext/csrc/vectors.h | 4 +- torchtext/csrc/vocab.cpp | 12 +- torchtext/csrc/vocab.h | 8 +- torchtext/data/dataset.py | 14 +- torchtext/data/field.py | 16 +- torchtext/data/functional.py | 10 +- torchtext/data/iterator.py | 2 +- torchtext/data/metrics.py | 4 +- torchtext/data/pipeline.py | 10 +- torchtext/data/utils.py | 4 +- torchtext/datasets/imdb.py | 6 +- torchtext/datasets/language_modeling.py | 14 +- torchtext/datasets/nli.py | 4 +- torchtext/datasets/sst.py | 6 +- torchtext/datasets/text_classification.py | 18 +- torchtext/datasets/translation.py | 10 +- torchtext/datasets/trec.py | 6 +- torchtext/datasets/unsupervised_learning.py | 2 +- .../datasets/language_modeling.py | 10 +- .../experimental/datasets/question_answer.py | 6 +- .../datasets/raw/language_modeling.py | 11 +- .../datasets/raw/question_answer.py | 4 +- .../datasets/raw/sequence_tagging.py | 4 +- .../datasets/raw/text_classification.py | 18 +- .../experimental/datasets/raw/translation.py | 32 +- .../experimental/datasets/sequence_tagging.py | 6 +- .../datasets/text_classification.py | 20 +- .../experimental/datasets/translation.py | 8 +- torchtext/experimental/transforms.py | 2 +- torchtext/experimental/vectors.py | 2 +- torchtext/experimental/vocab.py | 6 +- torchtext/nn/modules/multiheadattention.py | 29 +- torchtext/utils.py | 6 +- torchtext/vocab.py | 14 +- 52 files changed, 530 insertions(+), 320 deletions(-) diff --git a/README.rst b/README.rst index 06d5a3ddc9..501388d543 100644 --- a/README.rst +++ b/README.rst @@ -19,7 +19,7 @@ Note: we are currently re-designing the torchtext library to make it more compat pip install --pre torch torchtext -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html -For more detail instructions, please refer to `Install PyTorch `_. It should be noted that the new building blocks are still under development, and the APIs have not been solidified. +For more detailed instructions, please refer to `Install PyTorch `_. It should be noted that the new building blocks are still under development, and the APIs have not been solidified. Installation ============ @@ -81,7 +81,7 @@ To build torchtext from source, you need ``git``, ``CMake`` and C++11 compiler s **Note** When building from source, make sure that you have the same C++ compiler as the one used to build PyTorch. A simple way is to build PyTorch from source and use the same environment to build torchtext. -If you are using nightly build of PyTorch, checkout the environment it was built `here (conda) `_ and `here (pip) `_. +If you are using the nightly build of PyTorch, checkout the environment it was built with `conda (here) `_ and `pip (here) `_. Documentation ============= diff --git a/examples/text_classification/iterable_train.py b/examples/text_classification/iterable_train.py index d4e6507bc5..94b3c1c3a3 100644 --- a/examples/text_classification/iterable_train.py +++ b/examples/text_classification/iterable_train.py @@ -60,7 +60,7 @@ def train_and_valid(lr_, num_epoch, train_data_, valid_data_): r""" Here we use SGD optimizer to train the model. - Arguments: + Args: lr_: learning rate num_epoch: the number of epoches for training the model train_data_: the data used to train the model @@ -108,7 +108,7 @@ def train_and_valid(lr_, num_epoch, train_data_, valid_data_): def test(data_): r""" - Arguments: + Args: data_: the data used to train the model """ data = DataLoader( @@ -137,7 +137,7 @@ def get_csv_iterator(data_path, ngrams, vocab, start=0, num_lines=None): Generate an iterator to read CSV file. The yield values are an integer for the label and a tensor for the text part. - Arguments: + Args: data_path: a path for the data file. ngrams: the number used for ngrams. vocab: a vocab object saving the string-to-index information @@ -171,7 +171,7 @@ class Dataset(torch.utils.data.IterableDataset): An iterable dataset to save the data. This dataset supports multi-processing to load the data. - Arguments: + Args: iterator: the iterator to read data. num_lines: the number of lines read by the individual iterator. """ diff --git a/examples/text_classification/model.py b/examples/text_classification/model.py index e96d1d0125..1314b1b55a 100644 --- a/examples/text_classification/model.py +++ b/examples/text_classification/model.py @@ -31,7 +31,7 @@ def init_weights(self): def forward(self, text, offsets): r""" - Arguments: + Args: text: 1-D tensor representing a bag of text tensors offsets: a list of offsets to delimit the 1-D text tensor into the individual sequences. diff --git a/examples/text_classification/predict.py b/examples/text_classification/predict.py index b11de131a9..4bdd1f7fce 100644 --- a/examples/text_classification/predict.py +++ b/examples/text_classification/predict.py @@ -11,7 +11,7 @@ def predict(text, model, dictionary, ngrams): The input text is numericalized with the vocab and then sent to the model for inference. - Arguments: + Args: text: a sample text string model: the trained model dictionary: a vocab object for the information of string-to-index diff --git a/examples/text_classification/train.py b/examples/text_classification/train.py index fbd0831832..84f20fb0d4 100644 --- a/examples/text_classification/train.py +++ b/examples/text_classification/train.py @@ -56,7 +56,7 @@ def train_and_valid(lr_, sub_train_, sub_valid_): We use a SGD optimizer to train the model here and the learning rate decreases linearly with the progress of the training process. - Arguments: + Args: lr_: learning rate sub_train_: the data used to train the model sub_valid_: the data used for validation @@ -94,7 +94,7 @@ def train_and_valid(lr_, sub_train_, sub_valid_): def test(data_): r""" - Arguments: + Args: data_: the data used to train the model """ data = DataLoader(data_, batch_size=batch_size, collate_fn=generate_batch) diff --git a/packaging/torchtext/meta.yaml b/packaging/torchtext/meta.yaml index a79d8eafb7..c75e497736 100644 --- a/packaging/torchtext/meta.yaml +++ b/packaging/torchtext/meta.yaml @@ -38,6 +38,7 @@ test: requires: - pytest + - cpuonly about: home: https://github.com/pytorch/text diff --git a/test/data/test_batch.py b/test/data/test_batch.py index 76017784e9..d24b2cce33 100644 --- a/test/data/test_batch.py +++ b/test/data/test_batch.py @@ -37,7 +37,7 @@ def test_batch_iter(self): batch = next(iter(itr)) (x1, x2), y = batch x = (x1, x2)[fld_order.index("float")] - self.assertEquals(y.data[0], 1) - self.assertEquals(y.data[1], 12) + self.assertEqual(y.data[0], 1) + self.assertEqual(y.data[1], 12) self.assertAlmostEqual(x.data[0], 0.1, places=4) self.assertAlmostEqual(x.data[1], 0.5, places=4) diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 0e2d320f42..fcef4f1507 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -162,6 +162,40 @@ def test_imdb(self): self._helper_test_func(len(test_iter), 25000, next(iter(test_iter))[1][:25], 'I love sci-fi and am will') del train_iter, test_iter + def test_iwslt(self): + from torchtext.experimental.datasets import IWSLT + + train_dataset, valid_dataset, test_dataset = IWSLT() + + self.assertEqual(len(train_dataset), 196884) + self.assertEqual(len(valid_dataset), 993) + self.assertEqual(len(test_dataset), 1305) + + de_vocab, en_vocab = train_dataset.get_vocab() + + def assert_nth_pair_is_equal(n, expected_sentence_pair): + de_sentence = [de_vocab.itos[index] for index in train_dataset[n][0]] + en_sentence = [en_vocab.itos[index] for index in train_dataset[n][1]] + expected_de_sentence, expected_en_sentence = expected_sentence_pair + + self.assertEqual(de_sentence, expected_de_sentence) + self.assertEqual(en_sentence, expected_en_sentence) + + assert_nth_pair_is_equal(0, (['David', 'Gallo', ':', 'Das', 'ist', 'Bill', 'Lange', + '.', 'Ich', 'bin', 'Dave', 'Gallo', '.', '\n'], + ['David', 'Gallo', ':', 'This', 'is', 'Bill', 'Lange', + '.', 'I', "'m", 'Dave', 'Gallo', '.', '\n'])) + assert_nth_pair_is_equal(10, (['Die', 'meisten', 'Tiere', 'leben', 'in', + 'den', 'Ozeanen', '.', '\n'], + ['Most', 'of', 'the', 'animals', 'are', 'in', + 'the', 'oceans', '.', '\n'])) + assert_nth_pair_is_equal(20, (['Es', 'ist', 'einer', 'meiner', 'Lieblinge', ',', 'weil', 'es', + 'alle', 'möglichen', 'Funktionsteile', 'hat', '.', '\n'], + ['It', "'s", 'one', 'of', 'my', 'favorites', ',', 'because', 'it', "'s", + 'got', 'all', 'sorts', 'of', 'working', 'parts', '.', '\n'])) + datafile = os.path.join(self.project_root, ".data", "2016-01.tgz") + conditional_remove(datafile) + def test_multi30k(self): from torchtext.experimental.datasets import Multi30k # smoke test to ensure multi30k works properly diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 66fda21154..509a0e9fc3 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -107,13 +107,24 @@ def test_BasicEnglishNormalize(self): self.assertEqual(eager_tokens, ref_results) self.assertEqual(experimental_eager_tokens, ref_results) - # test load and save - save_path = os.path.join(self.test_dir, 'basic_english_normalize.pt') - torch.save(basic_eng_norm.to_ivalue(), save_path) - loaded_basic_eng_norm = torch.load(save_path) + def test_basicEnglishNormalize_load_and_save(self): + test_sample = '\'".
      ,()!?;: Basic English Normalization for a Line of Text \'".
      ,()!?;:' + ref_results = ["'", '.', ',', '(', ')', '!', '?', 'basic', 'english', 'normalization', + 'for', 'a', 'line', 'of', 'text', "'", '.', ',', '(', ')', '!', '?'] - loaded_eager_tokens = loaded_basic_eng_norm(test_sample) - self.assertEqual(loaded_eager_tokens, ref_results) + with self.subTest('pybind'): + save_path = os.path.join(self.test_dir, 'ben_pybind.pt') + ben = basic_english_normalize() + torch.save(ben, save_path) + loaded_ben = torch.load(save_path) + self.assertEqual(loaded_ben(test_sample), ref_results) + + with self.subTest('torchscript'): + save_path = os.path.join(self.test_dir, 'ben_torchscrip.pt') + ben = basic_english_normalize().to_ivalue() + torch.save(ben, save_path) + loaded_ben = torch.load(save_path) + self.assertEqual(loaded_ben(test_sample), ref_results) # TODO(Nayef211): remove decorator once https://github.com/pytorch/pytorch/issues/38207 is closed @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") @@ -147,13 +158,39 @@ def test_RegexTokenizer(self): self.assertEqual(eager_tokens, ref_results) self.assertEqual(jit_tokens, ref_results) - # test load and save - save_path = os.path.join(self.test_dir, 'regex.pt') - torch.save(r_tokenizer.to_ivalue(), save_path) - loaded_r_tokenizer = torch.load(save_path) + def test_load_and_save(self): + test_sample = '\'".
      ,()!?;: Basic Regex Tokenization for a Line of Text \'".
      ,()!?;:' + ref_results = ["'", '.', ',', '(', ')', '!', '?', 'Basic', 'Regex', 'Tokenization', + 'for', 'a', 'Line', 'of', 'Text', "'", '.', ',', '(', ')', '!', '?'] + patterns_list = [ + (r'\'', ' \' '), + (r'\"', ''), + (r'\.', ' . '), + (r'
      ', ' '), + (r',', ' , '), + (r'\(', ' ( '), + (r'\)', ' ) '), + (r'\!', ' ! '), + (r'\?', ' ? '), + (r'\;', ' '), + (r'\:', ' '), + (r'\s+', ' ')] - loaded_eager_tokens = loaded_r_tokenizer(test_sample) - self.assertEqual(loaded_eager_tokens, ref_results) + with self.subTest('pybind'): + save_path = os.path.join(self.test_dir, 'regex_pybind.pt') + tokenizer = regex_tokenizer(patterns_list) + torch.save(tokenizer, save_path) + loaded_tokenizer = torch.load(save_path) + results = loaded_tokenizer(test_sample) + self.assertEqual(results, ref_results) + + with self.subTest('torchscript'): + save_path = os.path.join(self.test_dir, 'regex_torchscript.pt') + tokenizer = regex_tokenizer(patterns_list).to_ivalue() + torch.save(tokenizer, save_path) + loaded_tokenizer = torch.load(save_path) + results = loaded_tokenizer(test_sample) + self.assertEqual(results, ref_results) def test_custom_replace(self): custom_replace_transform = custom_replace([(r'S', 's'), (r'\s+', ' ')]) diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py index 69816dd6e7..1994c3c396 100644 --- a/test/experimental/test_transforms.py +++ b/test/experimental/test_transforms.py @@ -54,3 +54,27 @@ def test_vector_transform(self): [-0.32423, -0.098845, -0.0073467]]) self.assertEqual(vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) self.assertEqual(jit_vector_transform(['the', 'world'])[:, 0:3], expected_fasttext_simple_en) + + def test_sentencepiece_load_and_save(self): + model_path = get_asset_path('spm_example.model') + input = 'SentencePiece is an unsupervised text tokenizer and detokenizer' + expected = [ + '▁Sent', 'ence', 'P', 'ie', 'ce', '▁is', + '▁an', '▁un', 'super', 'vis', 'ed', '▁text', + '▁to', 'ken', 'izer', '▁and', + '▁de', 'to', 'ken', 'izer', + ] + + with self.subTest('pybind'): + save_path = os.path.join(self.test_dir, 'spm_pybind.pt') + spm = sentencepiece_tokenizer((model_path)) + torch.save(spm, save_path) + loaded_spm = torch.load(save_path) + self.assertEqual(expected, loaded_spm(input)) + + with self.subTest('torchscript'): + save_path = os.path.join(self.test_dir, 'spm_torchscript.pt') + spm = sentencepiece_tokenizer((model_path)).to_ivalue() + torch.save(spm, save_path) + loaded_spm = torch.load(save_path) + self.assertEqual(expected, loaded_spm(input)) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index 946c436e95..ff5293b402 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -111,25 +111,49 @@ def test_vectors_add_item(self): self.assertEqual(vectors_obj['b'], tensorB) self.assertEqual(vectors_obj['not_in_it'], unk_tensor) - def test_vectors_load_and_save(self): + def test_vectors_update(self): tensorA = torch.tensor([1, 0], dtype=torch.float) tensorB = torch.tensor([0, 1], dtype=torch.float) + tensorC = torch.tensor([1, 1], dtype=torch.float) + expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) vectors_obj = build_vectors(tokens, vecs) - tensorC = torch.tensor([1, 1], dtype=torch.float) vectors_obj['b'] = tensorC - vector_path = os.path.join(self.test_dir, 'vectors.pt') - torch.save(vectors_obj.to_ivalue(), vector_path) - loaded_vectors_obj = torch.load(vector_path) + self.assertEqual(vectors_obj['a'], tensorA) + self.assertEqual(vectors_obj['b'], tensorC) + self.assertEqual(vectors_obj['not_in_it'], expected_unk_tensor) + + def test_vectors_load_and_save(self): + tensorA = torch.tensor([1, 0], dtype=torch.float) + tensorB = torch.tensor([0, 1], dtype=torch.float) + expected_unk_tensor = torch.tensor([0, 0], dtype=torch.float) + + tokens = ['a', 'b'] + vecs = torch.stack((tensorA, tensorB), 0) + vectors_obj = build_vectors(tokens, vecs) + + with self.subTest('pybind'): + vector_path = os.path.join(self.test_dir, 'vectors_pybind.pt') + torch.save(vectors_obj, vector_path) + loaded_vectors_obj = torch.load(vector_path) + + self.assertEqual(loaded_vectors_obj['a'], tensorA) + self.assertEqual(loaded_vectors_obj['b'], tensorB) + self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) + + with self.subTest('torchscript'): + vector_path = os.path.join(self.test_dir, 'vectors_torchscript.pt') + torch.save(vectors_obj.to_ivalue(), vector_path) + loaded_vectors_obj = torch.load(vector_path) - self.assertEqual(loaded_vectors_obj['a'], tensorA) - self.assertEqual(loaded_vectors_obj['b'], tensorC) - self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) + self.assertEqual(loaded_vectors_obj['a'], tensorA) + self.assertEqual(loaded_vectors_obj['b'], tensorB) + self.assertEqual(loaded_vectors_obj['not_in_it'], expected_unk_tensor) # we separate out these errors because Windows runs into seg faults when propagating # exceptions from C++ using pybind11 diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 626db2e726..662aa6667a 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -199,12 +199,19 @@ def test_vocab_load_and_save(self): self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) - vocab_path = os.path.join(self.test_dir, 'vocab.pt') - torch.save(v.to_ivalue(), vocab_path) - loaded_v = torch.load(vocab_path) - - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + with self.subTest('pybind'): + vocab_path = os.path.join(self.test_dir, 'vocab_pybind.pt') + torch.save(v, vocab_path) + loaded_v = torch.load(vocab_path) + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + + with self.subTest('torchscript'): + vocab_path = os.path.join(self.test_dir, 'vocab_torchscript.pt') + torch.save(v.to_ivalue(), vocab_path) + loaded_v = torch.load(vocab_path) + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) def test_build_vocab_iterator(self): iterator = [['hello', 'hello', 'hello', 'freq_low', 'hello', 'world', 'world', 'world', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', diff --git a/torchtext/csrc/regex.cpp b/torchtext/csrc/regex.cpp index f2051e0de0..32da33d2cf 100644 --- a/torchtext/csrc/regex.cpp +++ b/torchtext/csrc/regex.cpp @@ -11,4 +11,12 @@ std::string Regex::Sub(std::string str, const std::string &repl) const { return str; } +std::string _serialize_regex(const c10::intrusive_ptr &self) { + return self->re_str_; +} + +c10::intrusive_ptr _deserialize_regex(std::string &&state) { + return c10::make_intrusive(std::move(state)); +} + } // namespace torchtext diff --git a/torchtext/csrc/regex.h b/torchtext/csrc/regex.h index c5d871479c..4e5dfbfee4 100644 --- a/torchtext/csrc/regex.h +++ b/torchtext/csrc/regex.h @@ -13,4 +13,8 @@ struct Regex : torch::CustomClassHolder { Regex(const std::string &re_str); std::string Sub(std::string str, const std::string &repl) const; }; + +std::string _serialize_regex(const c10::intrusive_ptr &self); +c10::intrusive_ptr _deserialize_regex(std::string &&state); + } // namespace torchtext diff --git a/torchtext/csrc/regex_tokenizer.cpp b/torchtext/csrc/regex_tokenizer.cpp index c31ca36226..9ad20df9a7 100644 --- a/torchtext/csrc/regex_tokenizer.cpp +++ b/torchtext/csrc/regex_tokenizer.cpp @@ -44,4 +44,15 @@ void RegexTokenizer::split_(std::string &str, std::vector &tokens, } } +RegexTokenizerStates _serialize_regex_tokenizer(const c10::intrusive_ptr &self) { + return std::make_tuple(self->patterns_, self->replacements_, self->to_lower_); +} + +c10::intrusive_ptr _deserialize_regex_tokenizer(RegexTokenizerStates &&states) { + return c10::make_intrusive( + std::move(std::get<0>(states)), + std::move(std::get<1>(states)), + std::get<2>(states)); +} + } // namespace torchtext diff --git a/torchtext/csrc/regex_tokenizer.h b/torchtext/csrc/regex_tokenizer.h index d0d9cfbb62..02d898eb4a 100644 --- a/torchtext/csrc/regex_tokenizer.h +++ b/torchtext/csrc/regex_tokenizer.h @@ -3,6 +3,9 @@ namespace torchtext { +typedef std::tuple, std::vector, bool> + RegexTokenizerStates; + struct RegexTokenizer : torch::CustomClassHolder { private: std::vector compiled_patterns_; @@ -20,4 +23,7 @@ struct RegexTokenizer : torch::CustomClassHolder { std::vector forward(std::string str) const; }; +RegexTokenizerStates _serialize_regex_tokenizer(const c10::intrusive_ptr &self); +c10::intrusive_ptr _deserialize_regex_tokenizer(RegexTokenizerStates &&states); + } // namespace torchtext diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 6f77e8e3b8..4c3ef76399 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -3,30 +3,60 @@ #include #include // @manual #include // @manual +#include // @manual #include // @manual #include -#include // @manual #include // @manual #include // @manual namespace torchtext { namespace py = pybind11; + +namespace { +Vocab build_vocab_from_text_file(const std::string &file_path, + const std::string &unk_token, + const int64_t min_freq, + const int64_t num_cpus, + py::object fn) { + torch::jit::script::Module module(*torch::jit::as_module(fn)); + return _build_vocab_from_text_file(file_path, unk_token, min_freq, num_cpus, module); +} +} // namespace + // Registers our custom classes with pybind11. PYBIND11_MODULE(_torchtext, m) { // Classes - py::class_(m, "Regex") + py::class_>(m, "Regex") .def(py::init()) - .def("Sub", &Regex::Sub); + .def("Sub", &Regex::Sub) + .def(py::pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return _serialize_regex(self); + }, + // __setstate__ + [](std::string state) -> c10::intrusive_ptr { + return _deserialize_regex(std::move(state)); + })); - py::class_(m, "RegexTokenizer") + py::class_>(m, "RegexTokenizer") .def_readonly("patterns_", &RegexTokenizer::patterns_) .def_readonly("replacements_", &RegexTokenizer::replacements_) .def_readonly("to_lower_", &RegexTokenizer::to_lower_) .def(py::init, std::vector, bool>()) - .def("forward", &RegexTokenizer::forward); + .def("forward", &RegexTokenizer::forward) + .def(py::pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> RegexTokenizerStates { + return _serialize_regex_tokenizer(self); + }, + // __setstate__ + [](RegexTokenizerStates states) -> c10::intrusive_ptr { + return _deserialize_regex_tokenizer(std::move(states)); + })); - py::class_(m, "SentencePiece") + py::class_>(m, "SentencePiece") .def(py::init()) .def("_return_content", [](const SentencePiece &self) { return py::bytes(self.content_); }) @@ -38,9 +68,18 @@ PYBIND11_MODULE(_torchtext, m) { .def("GetPieceSize", &SentencePiece::GetPieceSize) .def("unk_id", &SentencePiece::unk_id) .def("PieceToId", &SentencePiece::PieceToId) - .def("IdToPiece", &SentencePiece::IdToPiece); + .def("IdToPiece", &SentencePiece::IdToPiece) + .def(py::pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> py::bytes{ + return py::bytes(self->content_); + }, + // __setstate__ + [](py::bytes state) -> c10::intrusive_ptr { + return c10::make_intrusive(std::string(state)); + })); - py::class_(m, "Vectors") + py::class_>(m, "Vectors") .def(py::init, std::vector, torch::Tensor, torch::Tensor>()) .def_readonly("vectors_", &Vectors::vectors_) @@ -49,9 +88,18 @@ PYBIND11_MODULE(_torchtext, m) { .def("__getitem__", &Vectors::__getitem__) .def("lookup_vectors", &Vectors::lookup_vectors) .def("__setitem__", &Vectors::__setitem__) - .def("__len__", &Vectors::__len__); + .def("__len__", &Vectors::__len__) + .def(py::pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> VectorsStates { + return _serialize_vectors(self); + }, + // __setstate__ + [](VectorsStates states) -> c10::intrusive_ptr { + return _deserialize_vectors(states); + })); - py::class_(m, "Vocab") + py::class_>(m, "Vocab") .def(py::init, std::string>()) .def_readonly("itos_", &Vocab::itos_) .def_readonly("unk_token_", &Vocab::unk_token_) @@ -63,126 +111,120 @@ PYBIND11_MODULE(_torchtext, m) { .def("lookup_tokens", &Vocab::lookup_tokens) .def("lookup_indices", &Vocab::lookup_indices) .def("get_stoi", &Vocab::get_stoi) - .def("get_itos", &Vocab::get_itos); + .def("get_itos", &Vocab::get_itos) + .def(py::pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> VocabStates { + return _serialize_vocab(self); + }, + // __setstate__ + [](VocabStates states) -> c10::intrusive_ptr { + return _deserialize_vocab(states); + })); // Functions m.def("_load_token_and_vectors_from_file", &_load_token_and_vectors_from_file); m.def("_load_vocab_from_file", &_load_vocab_from_file); - m.def("_build_vocab_from_text_file", _build_vocab_from_text_file); + m.def("_build_vocab_from_text_file", &build_vocab_from_text_file); } -// Registers our custom classes with torch. -static auto regex = - torch::class_("torchtext", "Regex") - .def(torch::init()) - .def("Sub", &Regex::Sub) - .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> std::string { - return self->re_str_; - }, - // __setstate__ - [](std::string state) -> c10::intrusive_ptr { - return c10::make_intrusive(std::move(state)); - }); - -static auto regex_tokenizer = - torch::class_("torchtext", "RegexTokenizer") - .def(torch::init, std::vector, - bool>()) - .def("forward", &RegexTokenizer::forward) - .def_pickle( - // __setstate__ - [](const c10::intrusive_ptr &self) - -> std::tuple, - std::vector, bool> { - return std::make_tuple(self->patterns_, self->replacements_, - self->to_lower_); - }, - // __getstate__ - [](std::tuple, std::vector, - bool> - states) -> c10::intrusive_ptr { - auto patterns = std::get<0>(states); - auto replacements = std::get<1>(states); - auto to_lower = std::get<2>(states); - - return c10::make_intrusive( - std::move(patterns), std::move(replacements), to_lower); - }); - -static auto sentencepiece = - torch::class_("torchtext", "SentencePiece") - .def(torch::init()) - .def("Encode", &SentencePiece::Encode) - .def("EncodeAsIds", &SentencePiece::EncodeAsIds) - .def("DecodeIds", &SentencePiece::DecodeIds) - .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) - .def("DecodePieces", &SentencePiece::DecodePieces) - .def("GetPieceSize", &SentencePiece::GetPieceSize) - .def("unk_id", &SentencePiece::unk_id) - .def("PieceToId", &SentencePiece::PieceToId) - .def("IdToPiece", &SentencePiece::IdToPiece) - .def_pickle( - // __setstate__ - [](const c10::intrusive_ptr &self) -> std::string { - return self->content_; - }, - // __getstate__ - [](std::string state) -> c10::intrusive_ptr { - return c10::make_intrusive(std::move(state)); - }); - -static auto vocab = - torch::class_("torchtext", "Vocab") - .def(torch::init()) - .def("__getitem__", &Vocab::__getitem__) - .def("__len__", &Vocab::__len__) - .def("insert_token", &Vocab::insert_token) - .def("append_token", &Vocab::append_token) - .def("lookup_token", &Vocab::lookup_token) - .def("lookup_tokens", &Vocab::lookup_tokens) - .def("lookup_indices", &Vocab::lookup_indices) - .def("get_stoi", &Vocab::get_stoi) - .def("get_itos", &Vocab::get_itos) - .def_pickle( - // __setstate__ - [](const c10::intrusive_ptr &self) -> VocabStates { - return _set_vocab_states(self); - }, - // __getstate__ - [](VocabStates states) -> c10::intrusive_ptr { - return _get_vocab_from_states(states); - }); - -static auto vectors = - torch::class_("torchtext", "Vectors") - .def(torch::init, std::vector, - torch::Tensor, torch::Tensor>()) - .def("__getitem__", &Vectors::__getitem__) - .def("lookup_vectors", &Vectors::lookup_vectors) - .def("__setitem__", &Vectors::__setitem__) - .def("__len__", &Vectors::__len__) - .def_pickle( - // __setstate__ - [](const c10::intrusive_ptr &self) -> VectorsStates { - return _set_vectors_states(self); - }, - // __getstate__ - [](VectorsStates states) -> c10::intrusive_ptr { - return _get_vectors_from_states(states); - }); - -// Registers our custom op with torch. TORCH_LIBRARY_FRAGMENT(torchtext, m) { - m.def("generate_sp_model", generate_sp_model); - m.def("load_sp_model(str path) -> " - "__torch__.torch.classes.torchtext.SentencePiece model", - load_sp_model); - m.def("load_sp_model_string(str content) -> " - "__torch__.torch.classes.torchtext.SentencePiece model", - load_sp_model_string); + m.class_("Regex") + .def(torch::init()) + .def("Sub", &Regex::Sub) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return _serialize_regex(self); + }, + // __setstate__ + [](std::string state) -> c10::intrusive_ptr { + return _deserialize_regex(std::move(state)); + }); + + m.class_("RegexTokenizer") + .def(torch::init, std::vector, bool>()) + .def("forward", &RegexTokenizer::forward) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> RegexTokenizerStates { + return _serialize_regex_tokenizer(self); + }, + // __setstate__ + [](RegexTokenizerStates states) -> c10::intrusive_ptr { + return _deserialize_regex_tokenizer(std::move(states)); + }); + + m.class_("SentencePiece") + .def(torch::init()) + .def("Encode", &SentencePiece::Encode) + .def("EncodeAsIds", &SentencePiece::EncodeAsIds) + .def("DecodeIds", &SentencePiece::DecodeIds) + .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) + .def("DecodePieces", &SentencePiece::DecodePieces) + .def("GetPieceSize", &SentencePiece::GetPieceSize) + .def("unk_id", &SentencePiece::unk_id) + .def("PieceToId", &SentencePiece::PieceToId) + .def("IdToPiece", &SentencePiece::IdToPiece) + .def_pickle( + // The underlying content of SentencePiece contains byte string, + // and returing it as std::string cause UTF8 decoding error. + // Since TorchScript does not support byte string, we use byte Tensor to + // pass around the data. + // __getstate__ + [](const c10::intrusive_ptr &self) -> torch::Tensor { + auto *data = static_cast(const_cast(self->content_.data())); + auto numel = static_cast(self->content_.size()); + return torch::from_blob(data, {numel}, {torch::kUInt8}).clone(); + }, + // __setstate__ + [](torch::Tensor state) -> c10::intrusive_ptr { + auto *data = static_cast(state.data_ptr()); + auto numel = state.size(0); + return c10::make_intrusive(std::string(data, numel)); + }); + + m.class_("Vectors") + .def(torch::init, std::vector, torch::Tensor, torch::Tensor>()) + .def("__getitem__", &Vectors::__getitem__) + .def("lookup_vectors", &Vectors::lookup_vectors) + .def("__setitem__", &Vectors::__setitem__) + .def("__len__", &Vectors::__len__) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> VectorsStates { + return _serialize_vectors(self); + }, + // __setstate__ + [](VectorsStates states) -> c10::intrusive_ptr { + return _deserialize_vectors(states); + }); + + m.class_("Vocab") + .def(torch::init()) + .def("__getitem__", &Vocab::__getitem__) + .def("__len__", &Vocab::__len__) + .def("insert_token", &Vocab::insert_token) + .def("append_token", &Vocab::append_token) + .def("lookup_token", &Vocab::lookup_token) + .def("lookup_tokens", &Vocab::lookup_tokens) + .def("lookup_indices", &Vocab::lookup_indices) + .def("get_stoi", &Vocab::get_stoi) + .def("get_itos", &Vocab::get_itos) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> VocabStates { + return _serialize_vocab(self); + }, + // __setstate__ + [](VocabStates states) -> c10::intrusive_ptr { + return _deserialize_vocab(states); + }); + + m.def("torchtext::generate_sp_model", &generate_sp_model); + m.def("torchtext::load_sp_model", &load_sp_model); + m.def("torchtext::load_sp_model_string", &load_sp_model_string); } } // namespace torchtext diff --git a/torchtext/csrc/vectors.cpp b/torchtext/csrc/vectors.cpp index 029b3abb0d..c5410b1496 100644 --- a/torchtext/csrc/vectors.cpp +++ b/torchtext/csrc/vectors.cpp @@ -275,7 +275,7 @@ std::tuple> _load_token_and_vectors_from_file( return result; } -VectorsStates _set_vectors_states(const c10::intrusive_ptr &self) { +VectorsStates _serialize_vectors(const c10::intrusive_ptr &self) { std::vector tokens; std::vector indices; tokens.reserve(self->stoi_.size()); @@ -299,7 +299,7 @@ VectorsStates _set_vectors_states(const c10::intrusive_ptr &self) { return states; } -c10::intrusive_ptr _get_vectors_from_states(VectorsStates states) { +c10::intrusive_ptr _deserialize_vectors(VectorsStates states) { auto state_size = std::tuple_size::value; if (state_size != 4) { throw std::runtime_error( diff --git a/torchtext/csrc/vectors.h b/torchtext/csrc/vectors.h index fde1f257f0..09716258ca 100644 --- a/torchtext/csrc/vectors.h +++ b/torchtext/csrc/vectors.h @@ -32,8 +32,8 @@ struct Vectors : torch::CustomClassHolder { int64_t __len__(); }; -c10::intrusive_ptr _get_vectors_from_states(VectorsStates states); -VectorsStates _set_vectors_states(const c10::intrusive_ptr &self); +VectorsStates _serialize_vectors(const c10::intrusive_ptr &self); +c10::intrusive_ptr _deserialize_vectors(VectorsStates states); std::tuple> _load_token_and_vectors_from_file( const std::string &file_path, const std::string delimiter_str, diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index a9a5f0c844..0e324dbbf5 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -2,7 +2,6 @@ #include #include #include -#include // @manual #include // @manual #include // @manual @@ -333,10 +332,9 @@ Vocab _load_vocab_from_file(const std::string &file_path, Vocab _build_vocab_from_text_file(const std::string &file_path, const std::string &unk_token, const int64_t min_freq, - const int64_t num_cpus, py::object fn) { + const int64_t num_cpus, + torch::jit::script::Module tokenizer) { std::cerr << "[INFO] Reading file " << file_path << std::endl; - - torch::jit::script::Module module(*torch::jit::as_module(fn)); int64_t num_lines = _infer_lines(file_path); int64_t chunk_size = impl::divup(num_lines, num_cpus); // Launching a thread on less lines than this likely has too much overhead. @@ -359,7 +357,7 @@ Vocab _build_vocab_from_text_file(const std::string &file_path, at::launch([&, file_path, num_lines, chunk_size, j, i, counter_ptr]() { parse_raw_text_file_chunk(file_path, offsets[j], i, std::min(num_lines, i + chunk_size), - counter_ptr, module); + counter_ptr, tokenizer); std::lock_guard lk(m); thread_count--; cv.notify_all(); @@ -381,7 +379,7 @@ Vocab _build_vocab_from_text_file(const std::string &file_path, return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); } -VocabStates _set_vocab_states(const c10::intrusive_ptr &self) { +VocabStates _serialize_vocab(const c10::intrusive_ptr &self) { std::vector integers; StringList strings = self->itos_; strings.push_back(self->unk_token_); @@ -392,7 +390,7 @@ VocabStates _set_vocab_states(const c10::intrusive_ptr &self) { return states; } -c10::intrusive_ptr _get_vocab_from_states(VocabStates states) { +c10::intrusive_ptr _deserialize_vocab(VocabStates states) { auto state_size = std::tuple_size::value; if (state_size != 4) { #ifdef _MSC_VER diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h index 594f44f2fb..0da660a633 100644 --- a/torchtext/csrc/vocab.h +++ b/torchtext/csrc/vocab.h @@ -1,4 +1,3 @@ -#include #include namespace torchtext { @@ -36,8 +35,9 @@ struct Vocab : torch::CustomClassHolder { std::vector get_itos() const; }; -c10::intrusive_ptr _get_vocab_from_states(VocabStates states); -VocabStates _set_vocab_states(const c10::intrusive_ptr &self); +VocabStates _serialize_vocab(const c10::intrusive_ptr &self); +c10::intrusive_ptr _deserialize_vocab(VocabStates states); + Vocab _load_vocab_from_file(const std::string &file_path, const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus); @@ -45,6 +45,6 @@ Vocab _build_vocab_from_text_file(const std::string &file_path, const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus, - py::object tokenizer); + torch::jit::script::Module tokenizer); } // namespace torchtext diff --git a/torchtext/data/dataset.py b/torchtext/data/dataset.py index c9efe9168b..eecfc49d9c 100644 --- a/torchtext/data/dataset.py +++ b/torchtext/data/dataset.py @@ -29,7 +29,7 @@ class Dataset(torch.utils.data.Dataset): def __init__(self, examples, fields, filter_pred=None): """Create a dataset from a list of Examples and Fields. - Arguments: + Args: examples: List of Examples. fields (List(tuple(str, Field))): The Fields to use in this tuple. The string is a field name, and the Field is the associated field. @@ -55,7 +55,7 @@ def splits(cls, path=None, root='.data', train=None, validation=None, test=None, **kwargs): """Create Dataset objects for multiple splits of a dataset. - Arguments: + Args: path (str): Common prefix of the splits' file paths, or None to use the result of cls.download(root). root (str): Root dataset storage directory. Default is '.data'. @@ -87,7 +87,7 @@ def split(self, split_ratio=0.7, stratified=False, strata_field='label', random_state=None): """Create train-test(-valid?) splits from the instance's examples. - Arguments: + Args: split_ratio (float or List of floats): a number [0, 1] denoting the amount of data to be used for the training split (rest is used for test), or a list of numbers denoting the relative sizes of train, test and valid @@ -157,7 +157,7 @@ def __getattr__(self, attr): def download(cls, root, check=None): """Download and unzip an online archive (.zip, .gz, or .tgz). - Arguments: + Args: root (str): Folder to download data to. check (str or None): Folder whose existence indicates that the dataset has already been downloaded, or @@ -201,7 +201,7 @@ def download(cls, root, check=None): def filter_examples(self, field_names): """Remove unknown words from dataset examples with respect to given field. - Arguments: + Args: field_names (list(str)): Within example only the parts with field names in field_names will have their unknown words deleted. """ @@ -221,7 +221,7 @@ def __init__(self, path, format, fields, skip_header=False, csv_reader_params={}, **kwargs): """Create a TabularDataset given a path, file format, and field list. - Arguments: + Args: path (str): Path to the data file. format (str): The format of the data file. One of "CSV", "TSV", or "JSON" (case-insensitive). @@ -325,7 +325,7 @@ def stratify(examples, strata_field): def rationed_split(examples, train_ratio, test_ratio, val_ratio, rnd): """Create a random permutation of examples, then split them by ratios - Arguments: + Args: examples: a list of data train_ratio, test_ratio, val_ratio: split fractions. rnd: a random shuffler diff --git a/torchtext/data/field.py b/torchtext/data/field.py index e117b2edb7..95be1b85f2 100644 --- a/torchtext/data/field.py +++ b/torchtext/data/field.py @@ -274,7 +274,7 @@ def pad(self, minibatch): def build_vocab(self, *args, **kwargs): """Construct the Vocab object for this field from one or more datasets. - Arguments: + Args: Positional arguments: Dataset objects or other iterable data sources from which to construct the Vocab object that represents the set of possible values for this field. If @@ -311,7 +311,7 @@ def numericalize(self, arr, device=None): If the field has include_lengths=True, a tensor of lengths will be included in the return value. - Arguments: + Args: arr (List[List[str]], or tuple of (List[List[str]], List[int])): List of tokenized and padded examples, or tuple of List of tokenized and padded examples and List of lengths of each @@ -423,7 +423,7 @@ def __init__(self, **kwargs): def segment(self, *args): """Segment one or more datasets with this subword field. - Arguments: + Args: Positional arguments: Dataset objects or other indexable mutable sequences to segment. If a Dataset object is provided, all columns corresponding to this field are used; individual @@ -455,7 +455,7 @@ class NestedField(Field): primarily used to implement character embeddings. See ``tests/data/test_field.py`` for examples on how to use this field. - Arguments: + Args: nesting_field (Field): A field contained in this nested field. use_vocab (bool): Whether to use a Vocab object. If False, the data in this field should already be numerical. Default: ``True``. @@ -533,7 +533,7 @@ def preprocess(self, xs): the list is preprocessed using ``self.nesting_field.preprocess`` and the resulting list is returned. - Arguments: + Args: xs (list or str): The input to preprocess. Returns: @@ -576,7 +576,7 @@ def pad(self, minibatch): ['', '
      ', '
      ', '', '', '', ''], ['', '', '', '', '', '', '']]] - Arguments: + Args: minibatch (list): Each element is a list of string if ``self.nesting_field.sequential`` is ``False``, a list of list of string otherwise. @@ -646,7 +646,7 @@ def pad(self, minibatch): def build_vocab(self, *args, **kwargs): """Construct the Vocab object for nesting field and combine it with this field's vocab. - Arguments: + Args: Positional arguments: Dataset objects or other iterable data sources from which to construct the Vocab object that represents the set of possible values for the nesting field. If @@ -697,7 +697,7 @@ def numericalize(self, arrs, device=None): Each item in the minibatch will be numericalized independently and the resulting tensors will be stacked at the first dimension. - Arguments: + Args: arr (List[List[str]]): List of tokenized and padded examples. device (str or torch.device): A string or instance of `torch.device` specifying which device the Variables are going to be created on. diff --git a/torchtext/data/functional.py b/torchtext/data/functional.py index 6e20c8e667..995025e929 100644 --- a/torchtext/data/functional.py +++ b/torchtext/data/functional.py @@ -21,7 +21,7 @@ def generate_sp_model(filename, vocab_size=20000, model_prefix='m_user'): r"""Train a SentencePiece tokenizer. - Arguments: + Args: filename: the data file for training SentencePiece model. vocab_size: the size of vocabulary (Default: 20,000). model_type: the type of SentencePiece model, including unigram, @@ -42,7 +42,7 @@ def generate_sp_model(filename, vocab_size=20000, def load_sp_model(spm): r"""Load a sentencepiece model for file. - Arguments: + Args: spm: the file path or a file object saving the sentencepiece model. Outputs: @@ -70,7 +70,7 @@ def sentencepiece_numericalizer(sp_model): r"""A sentencepiece model to numericalize a text sentence into a generator over the ids. - Arguments: + Args: sp_model: a SentencePiece model. Outputs: @@ -96,7 +96,7 @@ def sentencepiece_tokenizer(sp_model): r"""A sentencepiece model to tokenize a text sentence into a generator over the tokens. - Arguments: + Args: sp_model: a SentencePiece model. Outputs: @@ -157,7 +157,7 @@ def simple_space_split(iterator): def numericalize_tokens_from_iterator(vocab, iterator, removed_tokens=None): r"""Yield a list of ids from an token iterator with a vocab. - Arguments: + Args: vocab: the vocabulary convert token into id. iterator: the iterator yield a list of tokens. removed_tokens: removed tokens from output dataset (Default: None) diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py index 4c1119cb8c..3dfa807138 100644 --- a/torchtext/data/iterator.py +++ b/torchtext/data/iterator.py @@ -85,7 +85,7 @@ def __init__(self, dataset, batch_size, sort_key=None, device=None, def splits(cls, datasets, batch_sizes=None, **kwargs): """Create Iterator objects for multiple splits of a dataset. - Arguments: + Args: datasets: Tuple of Dataset objects corresponding to the splits. The first such object should be the train set. batch_sizes: Tuple of batch sizes to use for the different splits, diff --git a/torchtext/data/metrics.py b/torchtext/data/metrics.py index 63e07cdb21..c5c2983ee4 100644 --- a/torchtext/data/metrics.py +++ b/torchtext/data/metrics.py @@ -7,7 +7,7 @@ def _compute_ngram_counter(tokens, max_n): """ Create a Counter with a count of unique n-grams in the tokens list - Arguments: + Args: tokens: a list of tokens (typically a string split on whitespaces) max_n: the maximum order of n-gram wanted @@ -36,7 +36,7 @@ def bleu_score(candidate_corpus, references_corpus, max_n=4, weights=[0.25] * 4) """Computes the BLEU score between a candidate translation corpus and a references translation corpus. Based on https://www.aclweb.org/anthology/P02-1040.pdf - Arguments: + Args: candidate_corpus: an iterable of candidate translations. Each translation is an iterable of tokens references_corpus: an iterable of iterables of reference translations. Each diff --git a/torchtext/data/pipeline.py b/torchtext/data/pipeline.py index f576fdc720..d72ef5ef4c 100644 --- a/torchtext/data/pipeline.py +++ b/torchtext/data/pipeline.py @@ -12,7 +12,7 @@ class Pipeline(object): def __init__(self, convert_token=None): """Create a pipeline. - Arguments: + Args: convert_token: The function to apply to input sequence data. If None, the identity function is used. Default: None """ @@ -28,7 +28,7 @@ def __init__(self, convert_token=None): def __call__(self, x, *args): """Apply the the current Pipeline(s) to an input. - Arguments: + Args: x: The input to process with the Pipeline(s). Positional arguments: Forwarded to the `call` function of the Pipeline(s). @@ -43,7 +43,7 @@ def call(self, x, *args): applying the `convert_token` function to all input elements is returned. - Arguments: + Args: x: The input to apply the convert_token function to. Positional arguments: Forwarded to the `convert_token` function of the current Pipeline. @@ -55,7 +55,7 @@ def call(self, x, *args): def add_before(self, pipeline): """Add a Pipeline to be applied before this processing pipeline. - Arguments: + Args: pipeline: The Pipeline or callable to apply before this Pipeline. """ @@ -67,7 +67,7 @@ def add_before(self, pipeline): def add_after(self, pipeline): """Add a Pipeline to be applied after this processing pipeline. - Arguments: + Args: pipeline: The Pipeline or callable to apply after this Pipeline. """ diff --git a/torchtext/data/utils.py b/torchtext/data/utils.py index 5ecfad1958..045c2646fb 100644 --- a/torchtext/data/utils.py +++ b/torchtext/data/utils.py @@ -76,7 +76,7 @@ def get_tokenizer(tokenizer, language='en'): r""" Generate tokenizer function for a string sentence. - Arguments: + Args: tokenizer: the name of tokenizer function. If None, it returns split() function, which splits the string sentence by space. If basic_english, it returns _basic_english_normalize() function, @@ -205,7 +205,7 @@ def dtype_to_attr(dtype): def ngrams_iterator(token_list, ngrams): """Return an iterator that yields the given tokens and their ngrams. - Arguments: + Args: token_list: A list of tokens ngrams: the number of ngrams. diff --git a/torchtext/datasets/imdb.py b/torchtext/datasets/imdb.py index 38fccb97be..e59ce19ecb 100644 --- a/torchtext/datasets/imdb.py +++ b/torchtext/datasets/imdb.py @@ -18,7 +18,7 @@ def sort_key(ex): def __init__(self, path, text_field, label_field, **kwargs): """Create an IMDB dataset instance given a path and fields. - Arguments: + Args: path: Path to the dataset's highest level directory text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -41,7 +41,7 @@ def splits(cls, text_field, label_field, root='.data', train='train', test='test', **kwargs): """Create dataset objects for splits of the IMDB dataset. - Arguments: + Args: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: Root dataset storage directory. Default is '.data'. @@ -58,7 +58,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the IMDB dataset. - Arguments: + Args: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/language_modeling.py b/torchtext/datasets/language_modeling.py index 0002aabc04..7ebcca71b1 100644 --- a/torchtext/datasets/language_modeling.py +++ b/torchtext/datasets/language_modeling.py @@ -9,7 +9,7 @@ def __init__(self, path, text_field, newline_eos=True, encoding='utf-8', **kwargs): """Create a LanguageModelingDataset given a path and a field. - Arguments: + Args: path: Path to the data file. text_field: The field that will be used for text data. newline_eos: Whether to add an token for every newline in the @@ -44,7 +44,7 @@ def splits(cls, text_field, root='.data', train='wiki.train.tokens', This is the most flexible way to use the dataset. - Arguments: + Args: text_field: The field that will be used for text data. root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-2 @@ -67,7 +67,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for @@ -105,7 +105,7 @@ def splits(cls, text_field, root='.data', train='wiki.train.tokens', This is the most flexible way to use the dataset. - Arguments: + Args: text_field: The field that will be used for text data. root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-103 @@ -128,7 +128,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for @@ -174,7 +174,7 @@ def splits(cls, text_field, root='.data', train='ptb.train.txt', **kwargs): """Create dataset objects for splits of the Penn Treebank dataset. - Arguments: + Args: text_field: The field that will be used for text data. root: The root directory where the data files will be stored. train: The filename of the train data. Default: 'ptb.train.txt'. @@ -195,7 +195,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for diff --git a/torchtext/datasets/nli.py b/torchtext/datasets/nli.py index 9b3d758b06..758576e7cc 100644 --- a/torchtext/datasets/nli.py +++ b/torchtext/datasets/nli.py @@ -51,7 +51,7 @@ def splits(cls, text_field, label_field, parse_field=None, This is the most flexible way to use the dataset. - Arguments: + Args: text_field: The field that will be used for premise and hypothesis data. label_field: The field that will be used for label data. @@ -96,7 +96,7 @@ def iters(cls, batch_size=32, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. device: Device to create batches on. Use -1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/sst.py b/torchtext/datasets/sst.py index 95a04e3f6b..8c793fad93 100644 --- a/torchtext/datasets/sst.py +++ b/torchtext/datasets/sst.py @@ -17,7 +17,7 @@ def __init__(self, path, text_field, label_field, subtrees=False, fine_grained=False, **kwargs): """Create an SST dataset instance given a path and fields. - Arguments: + Args: path: Path to the data file text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -49,7 +49,7 @@ def splits(cls, text_field, label_field, root='.data', train_subtrees=False, **kwargs): """Create dataset objects for splits of the SST dataset. - Arguments: + Args: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: The root directory that the dataset's zip archive will be @@ -81,7 +81,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the SST dataset. - Arguments: + Args: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/text_classification.py b/torchtext/datasets/text_classification.py index be7400f91b..fc08876a34 100644 --- a/torchtext/datasets/text_classification.py +++ b/torchtext/datasets/text_classification.py @@ -78,7 +78,7 @@ class TextClassificationDataset(torch.utils.data.Dataset): def __init__(self, vocab, data, labels): """Initiate text-classification dataset. - Arguments: + Args: vocab: Vocabulary object used for dataset. data: a list of label/tokens tuple. tokens are a tensor after numericalizing the string tokens. label is an integer. @@ -154,7 +154,7 @@ def AG_NEWS(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -183,7 +183,7 @@ def SogouNews(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -221,7 +221,7 @@ def DBpedia(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -247,7 +247,7 @@ def YelpReviewPolarity(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -272,7 +272,7 @@ def YelpReviewFull(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -306,7 +306,7 @@ def YahooAnswers(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -332,7 +332,7 @@ def AmazonReviewPolarity(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -357,7 +357,7 @@ def AmazonReviewFull(*args, **kwargs): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the dataset are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 diff --git a/torchtext/datasets/translation.py b/torchtext/datasets/translation.py index 058022999f..cbb7ebdb39 100644 --- a/torchtext/datasets/translation.py +++ b/torchtext/datasets/translation.py @@ -17,7 +17,7 @@ def sort_key(ex): def __init__(self, path, exts, fields, **kwargs): """Create a TranslationDataset given paths and fields. - Arguments: + Args: path: Common prefix of paths to the data files for both languages. exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data @@ -46,7 +46,7 @@ def splits(cls, exts, fields, path=None, root='.data', train='train', validation='val', test='test', **kwargs): """Create dataset objects for splits of a TranslationDataset. - Arguments: + Args: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -87,7 +87,7 @@ def splits(cls, exts, fields, root='.data', train='train', validation='val', test='test2016', **kwargs): """Create dataset objects for splits of the Multi30k dataset. - Arguments: + Args: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -127,7 +127,7 @@ def splits(cls, exts, fields, root='.data', test='IWSLT16.TED.tst2014', **kwargs): """Create dataset objects for splits of the IWSLT dataset. - Arguments: + Args: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -201,7 +201,7 @@ def splits(cls, exts, fields, root='.data', test='newstest2014.tok.bpe.32000', **kwargs): """Create dataset objects for splits of the WMT 2014 dataset. - Arguments: + Args: exts: A tuple containing the extensions for each language. Must be either ('.en', '.de') or the reverse. fields: A tuple containing the fields that will be used for data diff --git a/torchtext/datasets/trec.py b/torchtext/datasets/trec.py index d96723c672..6e8792b519 100644 --- a/torchtext/datasets/trec.py +++ b/torchtext/datasets/trec.py @@ -18,7 +18,7 @@ def __init__(self, path, text_field, label_field, fine_grained=False, **kwargs): """Create an TREC dataset instance given a path and fields. - Arguments: + Args: path: Path to the data file. text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -46,7 +46,7 @@ def splits(cls, text_field, label_field, root='.data', train='train_5500.label', test='TREC_10.label', **kwargs): """Create dataset objects for splits of the TREC dataset. - Arguments: + Args: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: Root dataset storage directory. Default is '.data'. @@ -64,7 +64,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the TREC dataset. - Arguments: + Args: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/unsupervised_learning.py b/torchtext/datasets/unsupervised_learning.py index f1a97459b4..1babf1bfca 100644 --- a/torchtext/datasets/unsupervised_learning.py +++ b/torchtext/datasets/unsupervised_learning.py @@ -85,7 +85,7 @@ class EnWik9(torch.utils.data.Dataset): def __init__(self, begin_line=0, num_lines=6348957, root='.data'): """Initiate EnWik9 dataset. - Arguments: + Args: begin_line: the number of beginning line. Default: 0 num_lines: the number of lines to be loaded. Default: 6348957 root: Directory where the datasets are saved. Default: ".data" diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index 777f04d93c..3350c3f3b0 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -30,7 +30,7 @@ class LanguageModelingDataset(torch.utils.data.Dataset): def __init__(self, data, vocab, transform): """Initiate language modeling dataset. - Arguments: + Args: data: a tensor of tokens. tokens are ids after numericalizing the string tokens. torch.tensor([token_id_1, token_id_2, token_id_3, token_id1]).long() @@ -94,7 +94,7 @@ def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 'v Create language modeling dataset: WikiText2 Separately returns the train/test/valid set - Arguments: + Args: tokenizer: the tokenizer used to preprocess raw text data. The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well (see example below). A custom tokenizer is callable @@ -128,7 +128,7 @@ def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', Create language modeling dataset: WikiText103 Separately returns the train/test/valid set - Arguments: + Args: tokenizer: the tokenizer used to preprocess raw text data. The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well (see example below). A custom tokenizer is callable @@ -163,7 +163,7 @@ def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', Create language modeling dataset: PennTreebank Separately returns the train/test/valid set - Arguments: + Args: tokenizer: the tokenizer used to preprocess raw text data. The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well (see example below). A custom tokenizer is callable @@ -198,7 +198,7 @@ def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, data_select=('train') Create language modeling dataset: WMTNewsCrawl returns the train set - Arguments: + Args: tokenizer: the tokenizer used to preprocess raw text data. The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well (see example below). A custom tokenizer is callable diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index fb3b390dd8..ec239deb97 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -24,7 +24,7 @@ class QuestionAnswerDataset(torch.utils.data.Dataset): def __init__(self, data, vocab, transforms): """Initiate question answer dataset. - Arguments: + Args: data: a tuple of (context, question, answers, ans_pos). vocab: Vocabulary object used for dataset. transforms: a dictionary of transforms. @@ -96,7 +96,7 @@ def SQuAD1(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev' Separately returns the train and dev dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. @@ -130,7 +130,7 @@ def SQuAD2(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev' Separately returns the train and dev dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py index 0e7b4c26fe..b14c127316 100644 --- a/torchtext/experimental/datasets/raw/language_modeling.py +++ b/torchtext/experimental/datasets/raw/language_modeling.py @@ -55,8 +55,7 @@ def _setup_datasets(dataset_name, root, data_select, year, language): data[item] = iter(io.open(_path[item], encoding="utf8")) return tuple(RawTextIterableDataset(dataset_name, - NUM_LINES[dataset_name][item], - data[item]) for item in data_select) + NUM_LINES[dataset_name][item], data[item]) for item in data_select) def WikiText2(root='.data', data_select=('train', 'valid', 'test')): @@ -65,7 +64,7 @@ def WikiText2(root='.data', data_select=('train', 'valid', 'test')): Create language modeling dataset: WikiText2 Separately returns the train/test/valid set - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tupel for the returned datasets. Default: ('train', 'valid, 'test') By default, all the three datasets (train, test, valid) are generated. Users @@ -90,7 +89,7 @@ def WikiText103(root='.data', data_select=('train', 'valid', 'test')): Create language modeling dataset: WikiText103 Separately returns the train/test/valid set - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: the returned datasets. Default: ('train', 'valid','test') By default, all the three datasets (train, test, valid) are generated. Users @@ -113,7 +112,7 @@ def PennTreebank(root='.data', data_select=('train', 'valid', 'test')): Create language modeling dataset: PennTreebank Separately returns the train/test/valid set - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets (Default: ('train', 'test','valid')) @@ -138,7 +137,7 @@ def WMTNewsCrawl(root='.data', data_select=('train'), year=2010, language='en'): Create language modeling dataset: WMTNewsCrawl - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. (Default: 'train') diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py index 71b63df5d5..d21dbdbc55 100644 --- a/torchtext/experimental/datasets/raw/question_answer.py +++ b/torchtext/experimental/datasets/raw/question_answer.py @@ -46,7 +46,7 @@ def SQuAD1(root='.data', data_select=('train', 'dev')): ['Saint Bernadette Soubirous'], [515]) - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, @@ -70,7 +70,7 @@ def SQuAD2(root='.data', data_select=('train', 'dev')): ['in the late 1990s'], [269]) - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, diff --git a/torchtext/experimental/datasets/raw/sequence_tagging.py b/torchtext/experimental/datasets/raw/sequence_tagging.py index b584d147ab..c1a67261f1 100644 --- a/torchtext/experimental/datasets/raw/sequence_tagging.py +++ b/torchtext/experimental/datasets/raw/sequence_tagging.py @@ -69,7 +69,7 @@ def UDPOS(root=".data", data_select=('train', 'valid', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets (Default: ('train', 'valid', 'test')) By default, all the datasets (train, valid, test) are generated. @@ -88,7 +88,7 @@ def CoNLL2000Chunking(root=".data", data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, both datasets (train, test) are generated. Users could also choose any one or two of them, diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py index 46ee16b982..694e4d5d29 100644 --- a/torchtext/experimental/datasets/raw/text_classification.py +++ b/torchtext/experimental/datasets/raw/text_classification.py @@ -61,7 +61,7 @@ def AG_NEWS(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -81,7 +81,7 @@ def SogouNews(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -101,7 +101,7 @@ def DBpedia(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -121,7 +121,7 @@ def YelpReviewPolarity(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -141,7 +141,7 @@ def YelpReviewFull(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -161,7 +161,7 @@ def YahooAnswers(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -181,7 +181,7 @@ def AmazonReviewPolarity(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -201,7 +201,7 @@ def AmazonReviewFull(root='.data', data_select=('train', 'test')): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, @@ -231,7 +231,7 @@ def IMDB(root='.data', data_select=('train', 'test')): Separately returns the raw training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" data_select: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py index c36f9abd87..25960bead8 100644 --- a/torchtext/experimental/datasets/raw/translation.py +++ b/torchtext/experimental/datasets/raw/translation.py @@ -62,7 +62,7 @@ 'WMT14': 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8', 'IWSLT': - 'https://wit3.fbk.eu/archive/2016-01//texts/{}/{}/{}.tgz' + 'https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8' } @@ -125,14 +125,26 @@ def _setup_datasets(dataset_name, src_eval, tgt_eval = valid_filenames src_test, tgt_test = test_filenames - extracted_files = [] + extracted_files = [] # list of paths to the extracted files if isinstance(URLS[dataset_name], list): for idx, f in enumerate(URLS[dataset_name]): - dataset_tar = download_from_url(f, root=root, hash_value=MD5[dataset_name][idx], hash_type='md5') + dataset_tar = download_from_url( + f, root=root, hash_value=MD5[dataset_name][idx], hash_type='md5') extracted_files.extend(extract_archive(dataset_tar)) elif isinstance(URLS[dataset_name], str): dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5[dataset_name], hash_type='md5') - extracted_files.extend(extract_archive(dataset_tar)) + extracted_dataset_tar = extract_archive(dataset_tar) + if dataset_name == 'IWSLT': + # IWSLT dataset's url downloads a multilingual tgz. + # We need to take an extra step to pick out the specific language pair from it. + src_language = train_filenames[0].split(".")[-1] + tgt_language = train_filenames[1].split(".")[-1] + languages = "-".join([src_language, tgt_language]) + iwslt_tar = '.data/2016-01/texts/{}/{}/{}.tgz' + iwslt_tar = iwslt_tar.format( + src_language, tgt_language, languages) + extracted_dataset_tar = extract_archive(iwslt_tar) + extracted_files.extend(extracted_dataset_tar) else: raise ValueError( "URLS for {} has to be in a form or list or string".format( @@ -234,7 +246,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), val.5.de val.5.en - Arguments: + Args: train_filenames: the source and target filenames for training. Default: ('train.de', 'train.en') valid_filenames: the source and target filenames for valid. @@ -400,7 +412,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), train.tags.fr-en.en train.tags.fr-en.fr - Arguments: + Args: train_filenames: the source and target filenames for training. Default: ('train.de-en.de', 'train.de-en.en') valid_filenames: the source and target filenames for valid. @@ -418,10 +430,6 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), >>> from torchtext.experimental.datasets.raw import IWSLT >>> train_dataset, valid_dataset, test_dataset = IWSLT() """ - src_language = train_filenames[0].split(".")[-1] - tgt_language = train_filenames[1].split(".")[-1] - languages = "-".join([src_language, tgt_language]) - URLS["IWSLT"] = URLS["IWSLT"].format(src_language, tgt_language, languages) return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, data_select, root) @@ -486,7 +494,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', newstest2015.tok.bpe.32000.de train.tok.clean.bpe.32000.de - Arguments: + Args: train_filenames: the source and target filenames for training. Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') valid_filenames: the source and target filenames for valid. @@ -567,6 +575,6 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', 'acb5ea26a577ceccfae6337181c31716', '873a377a348713d3ab84db1fb57cdede', '680816e0938fea5cf5331444bc09a4cf'], - 'IWSLT': '6ff9ab8ea16fb352597c2784e0391fa8', + 'IWSLT': 'c393ed3fc2a1b0f004b3331043f615ae', 'WMT14': '874ab6bbfe9c21ec987ed1b9347f95ec' } diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index 3c0448e292..26b52ab206 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -74,7 +74,7 @@ class SequenceTaggingDataset(torch.utils.data.Dataset): def __init__(self, data, vocabs, transforms): """Initiate sequence tagging dataset. - Arguments: + Args: data: a list of word and its respective tags. Example: [[word, POS, dep_parsing label, ...]] vocabs: a list of vocabularies for its respective tags. @@ -113,7 +113,7 @@ def UDPOS(root=".data", vocabs=None, data_select=("train", "valid", "test")): Separately returns the training, validation, and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" vocabs: A list of voabularies for each columns in the dataset. Must be in an instance of List @@ -139,7 +139,7 @@ def CoNLL2000Chunking(root=".data", vocabs=None, data_select=("train", "test")): Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" vocabs: A list of voabularies for each columns in the dataset. Must be in an instance of List diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index 1ba9819f9b..0646e8d63a 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -38,7 +38,7 @@ class TextClassificationDataset(torch.utils.data.Dataset): def __init__(self, data, vocab, transforms): """Initiate text-classification dataset. - Arguments: + Args: data: a list of label and text tring tuple. label is an integer. [(label1, text1), (label2, text2), (label2, text3)] vocab: Vocabulary object used for dataset. @@ -113,7 +113,7 @@ def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('tr Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -157,7 +157,7 @@ def SogouNews(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=(' Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -210,7 +210,7 @@ def DBpedia(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('tr Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -251,7 +251,7 @@ def YelpReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, data_ Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -291,7 +291,7 @@ def YelpReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_sele Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -340,7 +340,7 @@ def YahooAnswers(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -381,7 +381,7 @@ def AmazonReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, dat Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -421,7 +421,7 @@ def AmazonReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_se Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 @@ -462,7 +462,7 @@ def IMDB(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train Separately returns the training and test dataset - Arguments: + Args: root: Directory where the datasets are saved. Default: ".data" ngrams: a contiguous sequence of n items from s string text. Default: 1 diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index abd626d2ec..c38d17401d 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -95,7 +95,7 @@ class TranslationDataset(torch.utils.data.Dataset): def __init__(self, data, vocab, transforms): """Initiate translation dataset. - Arguments: + Args: data: a tuple of source and target tensors, which include token ids numericalizing the string tokens. [(src_tensor0, tgt_tensor0), (src_tensor1, tgt_tensor1)] @@ -143,7 +143,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple - Arguments: + Args: train_filenames: the source and target filenames for training. Default: ('train.de', 'train.en') valid_filenames: the source and target filenames for valid. @@ -245,7 +245,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), Separately returns train/valid/test datasets The available datasets include: - Arguments: + Args: train_filenames: the source and target filenames for training. Default: ('train.de-en.de', 'train.de-en.en') valid_filenames: the source and target filenames for valid. @@ -486,7 +486,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', newstest2015.tok.bpe.32000.de train.tok.clean.bpe.32000.de - Arguments: + Args: train_filenames: the source and target filenames for training. Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') valid_filenames: the source and target filenames for valid. diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 6c3896aa61..1f62ea7032 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -209,7 +209,7 @@ def to_ivalue(self): def load_sp_model(sp_model): r"""Load a sentencepiece model for file. - Arguments: + Args: sp_model: the file path or a file object saving the sentencepiece model. Outputs: diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index a606e12bcc..72bae2351b 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -185,7 +185,7 @@ def load_vectors_from_file_path(filepath, delimiter=",", unk_tensor=None, num_cp def build_vectors(tokens, vectors, unk_tensor=None): r"""Factory method for creating a vectors object which maps tokens to vectors. - Arguments: + Args: tokens (List[str]): a list of tokens. vectors (torch.Tensor): a 2d tensor representing the vector associated with each token. unk_tensor (torch.Tensor): a 1d tensors representing the vector associated with an unknown token. diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index a7707003ee..6883326938 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -85,7 +85,7 @@ def build_vocab_from_iterator(iterator, min_freq=1, unk_token=''): """ Build a Vocab from an iterator. - Arguments: + Args: iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. min_freq: The minimum frequency needed to include a token in the vocabulary. Values less than 1 will be set to 1. Default: 1. @@ -108,7 +108,7 @@ def vocab(ordered_dict, min_freq=1, unk_token=''): Therefore if sorting by token frequency is important to the user, the `ordered_dict` should be created in a way to reflect this. Additionally, the if the `unk_token` isn't found inside of the `ordered_dict`, it will be added to the end of the vocab. - Arguments: + Args: ordered_dict (collections.OrderedDict): object holding the frequencies of each token found in the data. min_freq: The minimum frequency needed to include a token in the vocabulary. Values less than 1 will be set to 1. Default: 1. @@ -147,7 +147,7 @@ class Vocab(nn.Module): __jit_unused_properties__ = ["is_jitable"] r"""Creates a vocab object which maps tokens to indices. - Arguments: + Args: vocab (torch.classes.torchtext.Vocab or torchtext._torchtext.Vocab): a cpp vocab object. """ diff --git a/torchtext/nn/modules/multiheadattention.py b/torchtext/nn/modules/multiheadattention.py index 08b19f563e..aac7419d0b 100644 --- a/torchtext/nn/modules/multiheadattention.py +++ b/torchtext/nn/modules/multiheadattention.py @@ -200,13 +200,15 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, class InProjContainer(torch.nn.Module): def __init__(self, query_proj, key_proj, value_proj): - r"""A in-proj container to process inputs. + r"""A in-proj container to project query/key/value in MultiheadAttention. This module happens before reshaping + the projected query/key/value into multiple heads. See the linear layers (bottom) of Multi-head Attention in + Fig 2 of Attention Is All You Need paper. Also check the usage example + in torchtext.nn.MultiheadAttentionContainer. Args: - query_proj: a proj layer for query. - key_proj: a proj layer for key. - value_proj: a proj layer for value. - + query_proj: a proj layer for query. A typical projection layer is torch.nn.Linear. + key_proj: a proj layer for key. A typical projection layer is torch.nn.Linear. + value_proj: a proj layer for value. A typical projection layer is torch.nn.Linear. """ super(InProjContainer, self).__init__() @@ -218,16 +220,21 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: - r"""Projects the input sequences using in-proj layers. + r"""Projects the input sequences using in-proj layers. query/key/value are simply passed to + the forward func of query/key/value_proj, respectively. Args: query, key, value (Tensors): sequence to be projected - Shape: - - query, key, value: :math:`(S, N, E)` - - Output: :math:`(S, N, E)`. - - Note: S is the sequence length, N is the batch size, and E is the embedding dimension. + Examples:: + >>> from torchtext.nn import InProjContainer + >>> embed_dim, bsz = 10, 64 + >>> in_proj_container = InProjContainer(torch.nn.Linear(embed_dim, embed_dim), + torch.nn.Linear(embed_dim, embed_dim), + torch.nn.Linear(embed_dim, embed_dim)) + >>> q = torch.rand((5, bsz, embed_dim)) + >>> k = v = torch.rand((6, bsz, embed_dim)) + >>> q, k, v = in_proj_container(q, k, v) """ return self.query_proj(query), self.key_proj(key), self.value_proj(value) diff --git a/torchtext/utils.py b/torchtext/utils.py index 1e4974df21..d5a749487f 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -38,7 +38,7 @@ def download_from_url(url, path=None, root='.data', overwrite=False, hash_value= """Download file, with logic (from tensor2tensor) for Google Drive. Returns the path to the downloaded file. - Arguments: + Args: url: the url of the file from URL header. (None) root: download folder used to store the file in (.data) overwrite: overwrite existing files (False) @@ -136,7 +136,7 @@ def unicode_csv_reader(unicode_csv_data, **kwargs): Borrowed and slightly modified from the Python docs: https://docs.python.org/2/library/csv.html#csv-examples - Arguments: + Args: unicode_csv_data: unicode csv data (see example below) Examples: @@ -171,7 +171,7 @@ def utf_8_encoder(unicode_csv_data): def extract_archive(from_path, to_path=None, overwrite=False): """Extract archive. - Arguments: + Args: from_path: the path of the archive. to_path: the root path of the extracted files (directory of from_path) overwrite: overwrite existing files (False) diff --git a/torchtext/vocab.py b/torchtext/vocab.py index fe5101d16d..516f158a16 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -35,7 +35,7 @@ def __init__(self, counter, max_size=None, min_freq=1, specials=('', ' vectors=None, unk_init=None, vectors_cache=None, specials_first=True): """Create a Vocab object from a collections.Counter. - Arguments: + Args: counter: collections.Counter object holding the frequencies of each value found in the data. max_size: The maximum size of the vocabulary, or None for no @@ -149,7 +149,7 @@ def extend(self, v, sort=False): def load_vectors(self, vectors, **kwargs): """ - Arguments: + Args: vectors: one of or a list containing instantiations of the GloVe, CharNGram, or Vectors classes. Alternatively, one of or a list of available pretrained vectors: @@ -201,7 +201,7 @@ def set_vectors(self, stoi, vectors, dim, unk_init=torch.Tensor.zero_): """ Set the vectors for the Vocab instance from a collection of Tensors. - Arguments: + Args: stoi: A dictionary of string to the index of the associated vector in the `vectors` input argument. vectors: An indexed iterable (or other structure supporting __getitem__) that @@ -228,7 +228,7 @@ def __init__(self, counter, max_size=None, specials=(''), vectors=None, unk_init=torch.Tensor.zero_): """Create a revtok subword vocabulary from a collections.Counter. - Arguments: + Args: counter: collections.Counter object holding the frequencies of each word found in the data. max_size: The maximum size of the subword vocabulary, or None for no @@ -301,7 +301,7 @@ class Vectors(object): def __init__(self, name, cache=None, url=None, unk_init=None, max_vectors=None): """ - Arguments: + Args: name: name of the file that contains the vectors cache: directory for cached vectors @@ -440,7 +440,7 @@ def __len__(self): def get_vecs_by_tokens(self, tokens, lower_case_backup=False): """Look up embedding vectors of tokens. - Arguments: + Args: tokens: a token or a list of tokens. if `tokens` is a string, returns a 1-D tensor of shape `self.dim`; if `tokens` is a list of strings, returns a 2-D tensor of shape=(len(tokens), @@ -549,7 +549,7 @@ def build_vocab_from_iterator(iterator, num_lines=None): """ Build a Vocab from an iterator. - Arguments: + Args: iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. num_lines: The expected number of elements returned by the iterator. (Default: None) From 83e53ba1eb66c230116aa1aa86d0b57fb956fabc Mon Sep 17 00:00:00 2001 From: Moto Hira Date: Wed, 20 Jan 2021 11:30:19 -0800 Subject: [PATCH 35/68] Import torchtext from github #1121 d56fffe Summary: Import torchtext from github #1121 d56fffe Reviewed By: zhangguanheng66 Differential Revision: D25976268 fbshipit-source-id: 81589f8988a54cc12f17f0a6f298a915e829a830 --- docs/source/datasets.rst | 4 ++-- packaging/pkg_helpers.bash | 10 +++------- packaging/torchtext/meta.yaml | 2 ++ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index 708fe943a7..6df98d612f 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -74,13 +74,13 @@ SST ~~~ .. autoclass:: SST - :members: splits, iters + :members: __init__, splits, iters IMDb ~~~~ .. autoclass:: IMDB - :members: splits, iters + :members: __init__, splits, iters Text Classification diff --git a/packaging/pkg_helpers.bash b/packaging/pkg_helpers.bash index 7ce802ed14..e2e411b2ee 100644 --- a/packaging/pkg_helpers.bash +++ b/packaging/pkg_helpers.bash @@ -163,13 +163,9 @@ setup_pip_pytorch_version() { # Install latest prerelease version of torch, per our nightlies, consistent # with the requested cuda version pip_install --pre torch -f "https://download.pytorch.org/whl/nightly/${WHEEL_DIR}torch_nightly.html" - if [[ "$CUDA_VERSION" == "cpu" ]]; then - # CUDA and CPU are ABI compatible on the CPU-only parts, so strip - # in this case - export PYTORCH_VERSION="$(pip show torch | grep ^Version: | sed 's/Version: *//' | sed 's/+.\+//')" - else - export PYTORCH_VERSION="$(pip show torch | grep ^Version: | sed 's/Version: *//')" - fi + # CUDA and CPU are ABI compatible on the CPU-only parts, so strip + # in this case + export PYTORCH_VERSION="$(pip show torch | grep ^Version: | sed 's/Version: *//' | sed 's/+.\+//')" else pip_install "torch==$PYTORCH_VERSION$PYTORCH_VERSION_SUFFIX" \ -f https://download.pytorch.org/whl/torch_stable.html \ diff --git a/packaging/torchtext/meta.yaml b/packaging/torchtext/meta.yaml index c75e497736..36008e5cf5 100644 --- a/packaging/torchtext/meta.yaml +++ b/packaging/torchtext/meta.yaml @@ -25,6 +25,8 @@ requirements: build: string: py{{py}} + script_env: + - BUILD_VERSION test: imports: From 6f8a2ce3780608881c43c6676c73da6957f60b9e Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Mon, 25 Jan 2021 15:26:58 -0800 Subject: [PATCH 36/68] Import the hidden files in torchtext github repo Reviewed By: mthrok Differential Revision: D26001386 fbshipit-source-id: f822f0f32232d3006ef629937520dee6c0faf414 --- .circleci/build_docs/commit_docs.sh | 35 + .circleci/config.yml | 1085 +++++++++++++++++ .circleci/config.yml.in | 553 +++++++++ .circleci/regenerate.py | 173 +++ .circleci/smoke_test/docker/Dockerfile | 36 + .../unittest/linux/scripts/environment.yml | 21 + .circleci/unittest/linux/scripts/install.sh | 18 + .../unittest/linux/scripts/post_process.sh | 8 + .../linux/scripts/run_style_checks.sh | 32 + .circleci/unittest/linux/scripts/run_test.sh | 9 + .circleci/unittest/linux/scripts/setup_env.sh | 48 + .../unittest/windows/scripts/environment.yml | 23 + .circleci/unittest/windows/scripts/install.sh | 23 + .../windows/scripts/install_conda.bat | 1 + .../unittest/windows/scripts/post_process.sh | 8 + .../unittest/windows/scripts/run_test.sh | 9 + .../unittest/windows/scripts/setup_env.sh | 42 + .circleci/utils/test_sort_yaml.py | 14 + .flake8 | 5 +- .github/ISSUE_TEMPLATE/bug-report.md | 48 - .github/ISSUE_TEMPLATE/documentation.md | 10 - .github/ISSUE_TEMPLATE/feature-request.md | 24 - .../ISSUE_TEMPLATE/questions-help-support.md | 10 - .gitignore | 11 + .gitmodules | 13 + 25 files changed, 2165 insertions(+), 94 deletions(-) create mode 100755 .circleci/build_docs/commit_docs.sh create mode 100644 .circleci/config.yml create mode 100644 .circleci/config.yml.in create mode 100755 .circleci/regenerate.py create mode 100644 .circleci/smoke_test/docker/Dockerfile create mode 100644 .circleci/unittest/linux/scripts/environment.yml create mode 100755 .circleci/unittest/linux/scripts/install.sh create mode 100755 .circleci/unittest/linux/scripts/post_process.sh create mode 100755 .circleci/unittest/linux/scripts/run_style_checks.sh create mode 100755 .circleci/unittest/linux/scripts/run_test.sh create mode 100755 .circleci/unittest/linux/scripts/setup_env.sh create mode 100644 .circleci/unittest/windows/scripts/environment.yml create mode 100644 .circleci/unittest/windows/scripts/install.sh create mode 100644 .circleci/unittest/windows/scripts/install_conda.bat create mode 100644 .circleci/unittest/windows/scripts/post_process.sh create mode 100644 .circleci/unittest/windows/scripts/run_test.sh create mode 100644 .circleci/unittest/windows/scripts/setup_env.sh create mode 100755 .circleci/utils/test_sort_yaml.py delete mode 100644 .github/ISSUE_TEMPLATE/bug-report.md delete mode 100644 .github/ISSUE_TEMPLATE/documentation.md delete mode 100644 .github/ISSUE_TEMPLATE/feature-request.md delete mode 100644 .github/ISSUE_TEMPLATE/questions-help-support.md create mode 100644 .gitmodules diff --git a/.circleci/build_docs/commit_docs.sh b/.circleci/build_docs/commit_docs.sh new file mode 100755 index 0000000000..a1b4b05297 --- /dev/null +++ b/.circleci/build_docs/commit_docs.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -ex + + +if [ "$2" == "" ]; then + echo call as "$0" "" "" + echo where src is the root of the built documentation git checkout and + echo branch should be "master" or "1.7" or so + exit 1 +fi + +src=$1 +target=$2 + +echo "committing docs from ${src} to ${target}" + +pushd $src +git checkout gh-pages +mkdir -p ./"${target}" +rm -rf ./"${target}"/* +cp -r "${src}/docs/build/html/"* ./"$target" +if [ "${target}" == "master" ]; then + mkdir -p ./_static + rm -rf ./_static/* + cp -r "${src}/docs/build/html/_static/"* ./_static + git add --all ./_static || true +fi +git add --all ./"${target}" || true +git config user.email "soumith+bot@pytorch.org" +git config user.name "pytorchbot" +# If there aren't changes, don't make a commit; push is no-op +git commit -m "auto-generating sphinx docs" || true +git remote add https https://github.com/pytorch/text.git +git push -u https gh-pages diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..f18b086090 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,1085 @@ +version: 2.1 + +# How to test the Linux jobs: +# - Install CircleCI local CLI: https://circleci.com/docs/2.0/local-cli/ +# - circleci config process .circleci/config.yml > gen.yml && circleci local execute -c gen.yml --job binary_linux_wheel_py3.8 +# - Replace binary_linux_wheel_py3.8 with the name of the job you want to test. +# Job names are 'name:' key. + +orbs: + win: circleci/windows@2.0.0 + +executors: + windows-cpu: + machine: + resource_class: windows.xlarge + image: windows-server-2019-vs2019:stable + shell: bash.exe + +commands: + designate_upload_channel: + description: "inserts the correct upload channel into ${BASH_ENV}" + steps: + - run: + name: adding UPLOAD_CHANNEL to BASH_ENV + command: | + our_upload_channel=nightly + # On tags upload to test instead + if [[ -n "${CIRCLE_TAG}" ]] || [[ ${CIRCLE_BRANCH} =~ release/* ]]; then + our_upload_channel=test + fi + echo "export UPLOAD_CHANNEL=${our_upload_channel}" >> ${BASH_ENV} + +binary_common: &binary_common + parameters: + # Edit these defaults to do a release + build_version: + description: "version number of release binary; by default, build a nightly" + type: string + default: "" + pytorch_version: + description: "PyTorch version to build against; by default, use a nightly" + type: string + default: "" + # Don't edit these + python_version: + description: "Python version to build against (e.g., 3.8)" + type: string + environment: + PYTHON_VERSION: << parameters.python_version >> + BUILD_VERSION: << parameters.build_version >> + PYTORCH_VERSION: << parameters.pytorch_version >> + CU_VERSION: cpu + +smoke_test_common: &smoke_test_common + <<: *binary_common + docker: + - image: pytorch/torchtext_smoke_base:latest + +jobs: + circleci_consistency: + docker: + - image: circleci/python:3.8 + steps: + - checkout + - run: + command: | + pip install --user --progress-bar off jinja2 pyyaml + python .circleci/regenerate.py + git diff --exit-code || (echo ".circleci/config.yml not in sync with config.yml.in! Run .circleci/regenerate.py to update config"; exit 1) + + binary_linux_wheel: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda100" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - run: packaging/build_wheel.sh + - store_artifacts: + path: dist + - persist_to_workspace: + root: dist + paths: + - "*" + + binary_linux_conda: + <<: *binary_common + docker: + - image: "pytorch/conda-cuda" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - run: packaging/build_conda.sh + - store_artifacts: + path: /opt/conda/conda-bld/linux-64 + - persist_to_workspace: + root: /opt/conda + paths: + - "conda-bld/*" + + binary_windows_wheel: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - run: + name: build + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate base + bash packaging/build_wheel.sh + - store_artifacts: + path: dist + - persist_to_workspace: + root: dist + paths: + - "*" + + binary_windows_conda: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - run: + name: build + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate base + conda install -yq conda-build "conda-package-handling!=1.5.0" + bash packaging/build_conda.sh + rm /C/tools/miniconda3/conda-bld/win-64/vs2019*.tar.bz2 + - store_artifacts: + path: C:/tools/miniconda3/conda-bld/win-64 + - persist_to_workspace: + root: C:/tools/miniconda3 + paths: + - "conda-bld/*" + + binary_macos_wheel: + <<: *binary_common + macos: + xcode: "9.4.1" + steps: + - checkout + - designate_upload_channel + - run: + # Installing cmake with `brew install cmake` takes 30 mins, so we use binary distribution. + command: | + curl -o cmake.tar.gz -L https://github.com/Kitware/CMake/releases/download/v3.17.2/cmake-3.17.2-Darwin-x86_64.tar.gz + tar -xzf cmake.tar.gz + cp cmake-3.17.2-Darwin-x86_64/CMake.app/Contents/bin/* /usr/local/bin/ + cp -r cmake-3.17.2-Darwin-x86_64/CMake.app/Contents/share/* /usr/local/share/ + export PATH="${PATH}:/usr/local/bin" + curl -o conda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh + sh conda.sh -b + source $HOME/miniconda3/bin/activate + packaging/build_wheel.sh + - store_artifacts: + path: dist + - persist_to_workspace: + root: dist + paths: + - "*" + + binary_macos_conda: + <<: *binary_common + macos: + xcode: "9.4.1" + steps: + - checkout + - designate_upload_channel + - run: + command: | + curl -o conda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh + sh conda.sh -b + source $HOME/miniconda3/bin/activate + conda install -yq conda-build + packaging/build_conda.sh + - store_artifacts: + path: /Users/distiller/miniconda3/conda-bld/osx-64 + - persist_to_workspace: + root: /Users/distiller/miniconda3 + paths: + - "conda-bld/*" + + # Requires org-member context + binary_conda_upload: + docker: + - image: continuumio/miniconda + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + command: | + # Prevent credential from leaking + conda install -yq anaconda-client + set -x + anaconda -t "${CONDA_PYTORCHBOT_TOKEN}" upload ~/workspace/conda-bld/*/*.tar.bz2 -u "pytorch-${UPLOAD_CHANNEL}" --label main --no-progress --force + + # Requires org-member context + binary_wheel_upload: + docker: + - image: circleci/python:3.8 + steps: + - attach_workspace: + at: ~/workspace + - checkout + - designate_upload_channel + - run: + command: | + pip install --user awscli + export PATH="$HOME/.local/bin:$PATH" + # Prevent credential from leaking + set +x + export AWS_ACCESS_KEY_ID="${PYTORCH_BINARY_AWS_ACCESS_KEY_ID}" + export AWS_SECRET_ACCESS_KEY="${PYTORCH_BINARY_AWS_SECRET_ACCESS_KEY}" + set -x + for pkg in ~/workspace/*.whl; do + aws s3 cp "$pkg" "s3://pytorch/whl/${UPLOAD_CHANNEL}/" --acl public-read + done + + smoke_test_linux_conda: + <<: *smoke_test_common + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + conda install -v -y -c pytorch-${UPLOAD_CHANNEL} pytorch cpuonly + conda install -v -y -c file://$HOME/workspace/conda-bld torchtext + - run: + name: smoke test + command: | + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + smoke_test_linux_pip: + <<: *smoke_test_common + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + pip install $(ls ~/workspace/torchtext*.whl) --pre -f "https://download.pytorch.org/whl/${UPLOAD_CHANNEL}/cpu/torch_${UPLOAD_CHANNEL}.html" + - run: + name: smoke test + command: | + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + smoke_test_docker_image_build: + machine: + image: ubuntu-1604:201903-01 + resource_class: large + environment: + image_name: torchtext/smoke_test + steps: + - checkout + - run: + name: Build and push Docker image + no_output_timeout: "1h" + command: | + set +x + echo "${DOCKER_HUB_TOKEN}" | docker login --username "${DOCKER_HUB_USERNAME}" --password-stdin + set -x + cd .circleci/smoke_test/docker && docker build . -t ${image_name}:${CIRCLE_WORKFLOW_ID} + docker tag ${image_name}:${CIRCLE_WORKFLOW_ID} ${image_name}:latest + docker push ${image_name}:${CIRCLE_WORKFLOW_ID} + docker push ${image_name}:latest + + smoke_test_windows_conda: + <<: *binary_common + executor: + name: windows-cpu + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda env remove -n python${PYTHON_VERSION} || true + conda create -yn python${PYTHON_VERSION} python=${PYTHON_VERSION} + conda activate python${PYTHON_VERSION} + conda install -v -y -c pytorch-"${UPLOAD_CHANNEL}" pytorch cpuonly + conda install -v -y -c ~/workspace/conda-bld torchtext + - run: + name: smoke test + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + smoke_test_windows_pip: + <<: *binary_common + executor: + name: windows-cpu + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda env remove -n python${PYTHON_VERSION} || true + conda create -yn python${PYTHON_VERSION} python=${PYTHON_VERSION} + conda activate python${PYTHON_VERSION} + pip install $(ls ~/workspace/torchtext*.whl) --pre -f "https://download.pytorch.org/whl/${UPLOAD_CHANNEL}/torch_${UPLOAD_CHANNEL}.html" + - run: + name: smoke test + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + unittest_linux: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda100" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - run: + name: Generate cache key + # This will refresh cache on Sundays, nightly build should generate new cache. + command: echo "$(date +"%Y-%U")" > .circleci-weekly + - restore_cache: + + keys: + - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + - run: + name: Setup + command: .circleci/unittest/linux/scripts/setup_env.sh + - save_cache: + + key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + paths: + - conda + - env + - run: + name: Install torchtext + command: .circleci/unittest/linux/scripts/install.sh + - restore_cache: + keys: + + - data-linux-v1-{{ checksum ".circleci-weekly" }} + + - run: + name: Run tests + # Downloading embedding vector takes long time. + no_output_timeout: 30m + command: .circleci/unittest/linux/scripts/run_test.sh + - save_cache: + + key: data-linux-v1-{{ checksum ".circleci-weekly" }} + + paths: + - .vector_cache + - .data + - run: + name: Post process + command: .circleci/unittest/linux/scripts/post_process.sh + - store_test_results: + path: test-results + + unittest_windows: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - run: + name: Generate cache key + # This will refresh cache on Sundays, nightly build should generate new cache. + command: echo "$(date +"%Y-%U")" > .circleci-weekly + - restore_cache: + + keys: + - env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + - run: + name: Setup + command: .circleci/unittest/windows/scripts/setup_env.sh + - save_cache: + + key: env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + paths: + - conda + - env + - run: + name: Install torchtext + command: .circleci/unittest/windows/scripts/install.sh + - restore_cache: + keys: + + - data-windows-v1-{{ checksum ".circleci-weekly" }} + + - run: + name: Run tests + # Downloading embedding vector takes long time. + no_output_timeout: 30m + command: .circleci/unittest/windows/scripts/run_test.sh + - save_cache: + + key: data-windows-v1-{{ checksum ".circleci-weekly" }} + + paths: + - .vector_cache + - .data + - run: + name: Post process + command: .circleci/unittest/windows/scripts/post_process.sh + - store_test_results: + path: test-results + + stylecheck: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda100" + resource_class: medium + steps: + - checkout + - designate_upload_channel + - run: + name: Generate cache key + # This will refresh cache on Sundays, nightly build should generate new cache. + command: echo "$(date +"%Y-%U")" > .circleci-weekly + - restore_cache: + + keys: + - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + - run: + name: Setup + command: .circleci/unittest/linux/scripts/setup_env.sh + - save_cache: + + key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + paths: + - conda + - env + - run: + name: Run style check + command: .circleci/unittest/linux/scripts/run_style_checks.sh + build_docs: + <<: *binary_common + docker: + - image: continuumio/miniconda3 + resource_class: medium + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - checkout + - run: + name: install binaries + command: | + set -x + conda install make + pip install $(ls ~/workspace/torchtext*.whl) --pre -f "https://download.pytorch.org/whl/${UPLOAD_CHANNEL}/cpu/torch_${UPLOAD_CHANNEL}.html" + - run: + name: Build docs + command: | + set -x + pushd docs + pip install -r requirements.txt + make html + popd + - persist_to_workspace: + root: ./ + paths: + - "*" + + upload_docs: + <<: *binary_common + docker: + - image: continuumio/miniconda3 + resource_class: medium + steps: + - attach_workspace: + at: ~/workspace + - run: + name: Generate netrc + command: | + # set credentials for https pushing + # requires the org-member context + cat > ~/.netrc \< gen.yml && circleci local execute -c gen.yml --job binary_linux_wheel_py3.8 +# - Replace binary_linux_wheel_py3.8 with the name of the job you want to test. +# Job names are 'name:' key. + +orbs: + win: circleci/windows@2.0.0 + +executors: + windows-cpu: + machine: + resource_class: windows.xlarge + image: windows-server-2019-vs2019:stable + shell: bash.exe + +commands: + designate_upload_channel: + description: "inserts the correct upload channel into ${BASH_ENV}" + steps: + - run: + name: adding UPLOAD_CHANNEL to BASH_ENV + command: | + our_upload_channel=nightly + # On tags upload to test instead + if [[ -n "${CIRCLE_TAG}" ]] || [[ ${CIRCLE_BRANCH} =~ release/* ]]; then + our_upload_channel=test + fi + echo "export UPLOAD_CHANNEL=${our_upload_channel}" >> ${BASH_ENV} + +binary_common: &binary_common + parameters: + # Edit these defaults to do a release + build_version: + description: "version number of release binary; by default, build a nightly" + type: string + default: "" + pytorch_version: + description: "PyTorch version to build against; by default, use a nightly" + type: string + default: "" + # Don't edit these + python_version: + description: "Python version to build against (e.g., 3.8)" + type: string + environment: + PYTHON_VERSION: << parameters.python_version >> + BUILD_VERSION: << parameters.build_version >> + PYTORCH_VERSION: << parameters.pytorch_version >> + CU_VERSION: cpu + +smoke_test_common: &smoke_test_common + <<: *binary_common + docker: + - image: pytorch/torchtext_smoke_base:latest + +jobs: + circleci_consistency: + docker: + - image: circleci/python:3.8 + steps: + - checkout + - run: + command: | + pip install --user --progress-bar off jinja2 pyyaml + python .circleci/regenerate.py + git diff --exit-code || (echo ".circleci/config.yml not in sync with config.yml.in! Run .circleci/regenerate.py to update config"; exit 1) + + binary_linux_wheel: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda100" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - run: packaging/build_wheel.sh + - store_artifacts: + path: dist + - persist_to_workspace: + root: dist + paths: + - "*" + + binary_linux_conda: + <<: *binary_common + docker: + - image: "pytorch/conda-cuda" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - run: packaging/build_conda.sh + - store_artifacts: + path: /opt/conda/conda-bld/linux-64 + - persist_to_workspace: + root: /opt/conda + paths: + - "conda-bld/*" + + binary_windows_wheel: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - run: + name: build + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate base + bash packaging/build_wheel.sh + - store_artifacts: + path: dist + - persist_to_workspace: + root: dist + paths: + - "*" + + binary_windows_conda: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - run: + name: build + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate base + conda install -yq conda-build "conda-package-handling!=1.5.0" + bash packaging/build_conda.sh + rm /C/tools/miniconda3/conda-bld/win-64/vs2019*.tar.bz2 + - store_artifacts: + path: C:/tools/miniconda3/conda-bld/win-64 + - persist_to_workspace: + root: C:/tools/miniconda3 + paths: + - "conda-bld/*" + + binary_macos_wheel: + <<: *binary_common + macos: + xcode: "9.4.1" + steps: + - checkout + - designate_upload_channel + - run: + # Installing cmake with `brew install cmake` takes 30 mins, so we use binary distribution. + command: | + curl -o cmake.tar.gz -L https://github.com/Kitware/CMake/releases/download/v3.17.2/cmake-3.17.2-Darwin-x86_64.tar.gz + tar -xzf cmake.tar.gz + cp cmake-3.17.2-Darwin-x86_64/CMake.app/Contents/bin/* /usr/local/bin/ + cp -r cmake-3.17.2-Darwin-x86_64/CMake.app/Contents/share/* /usr/local/share/ + export PATH="${PATH}:/usr/local/bin" + curl -o conda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh + sh conda.sh -b + source $HOME/miniconda3/bin/activate + packaging/build_wheel.sh + - store_artifacts: + path: dist + - persist_to_workspace: + root: dist + paths: + - "*" + + binary_macos_conda: + <<: *binary_common + macos: + xcode: "9.4.1" + steps: + - checkout + - designate_upload_channel + - run: + command: | + curl -o conda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh + sh conda.sh -b + source $HOME/miniconda3/bin/activate + conda install -yq conda-build + packaging/build_conda.sh + - store_artifacts: + path: /Users/distiller/miniconda3/conda-bld/osx-64 + - persist_to_workspace: + root: /Users/distiller/miniconda3 + paths: + - "conda-bld/*" + + # Requires org-member context + binary_conda_upload: + docker: + - image: continuumio/miniconda + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + command: | + # Prevent credential from leaking + conda install -yq anaconda-client + set -x + anaconda -t "${CONDA_PYTORCHBOT_TOKEN}" upload ~/workspace/conda-bld/*/*.tar.bz2 -u "pytorch-${UPLOAD_CHANNEL}" --label main --no-progress --force + + # Requires org-member context + binary_wheel_upload: + docker: + - image: circleci/python:3.8 + steps: + - attach_workspace: + at: ~/workspace + - checkout + - designate_upload_channel + - run: + command: | + pip install --user awscli + export PATH="$HOME/.local/bin:$PATH" + # Prevent credential from leaking + set +x + export AWS_ACCESS_KEY_ID="${PYTORCH_BINARY_AWS_ACCESS_KEY_ID}" + export AWS_SECRET_ACCESS_KEY="${PYTORCH_BINARY_AWS_SECRET_ACCESS_KEY}" + set -x + for pkg in ~/workspace/*.whl; do + aws s3 cp "$pkg" "s3://pytorch/whl/${UPLOAD_CHANNEL}/" --acl public-read + done + + smoke_test_linux_conda: + <<: *smoke_test_common + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + conda install -v -y -c pytorch-${UPLOAD_CHANNEL} pytorch cpuonly + conda install -v -y -c file://$HOME/workspace/conda-bld torchtext + - run: + name: smoke test + command: | + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + smoke_test_linux_pip: + <<: *smoke_test_common + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + pip install $(ls ~/workspace/torchtext*.whl) --pre -f "https://download.pytorch.org/whl/${UPLOAD_CHANNEL}/cpu/torch_${UPLOAD_CHANNEL}.html" + - run: + name: smoke test + command: | + source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + smoke_test_docker_image_build: + machine: + image: ubuntu-1604:201903-01 + resource_class: large + environment: + image_name: torchtext/smoke_test + steps: + - checkout + - run: + name: Build and push Docker image + no_output_timeout: "1h" + command: | + set +x + echo "${DOCKER_HUB_TOKEN}" | docker login --username "${DOCKER_HUB_USERNAME}" --password-stdin + set -x + cd .circleci/smoke_test/docker && docker build . -t ${image_name}:${CIRCLE_WORKFLOW_ID} + docker tag ${image_name}:${CIRCLE_WORKFLOW_ID} ${image_name}:latest + docker push ${image_name}:${CIRCLE_WORKFLOW_ID} + docker push ${image_name}:latest + + smoke_test_windows_conda: + <<: *binary_common + executor: + name: windows-cpu + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda env remove -n python${PYTHON_VERSION} || true + conda create -yn python${PYTHON_VERSION} python=${PYTHON_VERSION} + conda activate python${PYTHON_VERSION} + conda install -v -y -c pytorch-"${UPLOAD_CHANNEL}" pytorch cpuonly + conda install -v -y -c ~/workspace/conda-bld torchtext + - run: + name: smoke test + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + smoke_test_windows_pip: + <<: *binary_common + executor: + name: windows-cpu + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - run: + name: install binaries + command: | + set -x + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda env remove -n python${PYTHON_VERSION} || true + conda create -yn python${PYTHON_VERSION} python=${PYTHON_VERSION} + conda activate python${PYTHON_VERSION} + pip install $(ls ~/workspace/torchtext*.whl) --pre -f "https://download.pytorch.org/whl/${UPLOAD_CHANNEL}/torch_${UPLOAD_CHANNEL}.html" + - run: + name: smoke test + command: | + eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" + conda activate python${PYTHON_VERSION} + python -c "import torchtext" + + unittest_linux: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda100" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - run: + name: Generate cache key + # This will refresh cache on Sundays, nightly build should generate new cache. + command: echo "$(date +"%Y-%U")" > .circleci-weekly + - restore_cache: + {% raw %} + keys: + - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% endraw %} + - run: + name: Setup + command: .circleci/unittest/linux/scripts/setup_env.sh + - save_cache: + {% raw %} + key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% endraw %} + paths: + - conda + - env + - run: + name: Install torchtext + command: .circleci/unittest/linux/scripts/install.sh + - restore_cache: + keys: + {% raw %} + - data-linux-v1-{{ checksum ".circleci-weekly" }} + {% endraw %} + - run: + name: Run tests + # Downloading embedding vector takes long time. + no_output_timeout: 30m + command: .circleci/unittest/linux/scripts/run_test.sh + - save_cache: + {% raw %} + key: data-linux-v1-{{ checksum ".circleci-weekly" }} + {% endraw %} + paths: + - .vector_cache + - .data + - run: + name: Post process + command: .circleci/unittest/linux/scripts/post_process.sh + - store_test_results: + path: test-results + + unittest_windows: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - run: + name: Generate cache key + # This will refresh cache on Sundays, nightly build should generate new cache. + command: echo "$(date +"%Y-%U")" > .circleci-weekly + - restore_cache: + {% raw %} + keys: + - env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% endraw %} + - run: + name: Setup + command: .circleci/unittest/windows/scripts/setup_env.sh + - save_cache: + {% raw %} + key: env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% endraw %} + paths: + - conda + - env + - run: + name: Install torchtext + command: .circleci/unittest/windows/scripts/install.sh + - restore_cache: + keys: + {% raw %} + - data-windows-v1-{{ checksum ".circleci-weekly" }} + {% endraw %} + - run: + name: Run tests + # Downloading embedding vector takes long time. + no_output_timeout: 30m + command: .circleci/unittest/windows/scripts/run_test.sh + - save_cache: + {% raw %} + key: data-windows-v1-{{ checksum ".circleci-weekly" }} + {% endraw %} + paths: + - .vector_cache + - .data + - run: + name: Post process + command: .circleci/unittest/windows/scripts/post_process.sh + - store_test_results: + path: test-results + + stylecheck: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda100" + resource_class: medium + steps: + - checkout + - designate_upload_channel + - run: + name: Generate cache key + # This will refresh cache on Sundays, nightly build should generate new cache. + command: echo "$(date +"%Y-%U")" > .circleci-weekly + - restore_cache: + {% raw %} + keys: + - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% endraw %} + - run: + name: Setup + command: .circleci/unittest/linux/scripts/setup_env.sh + - save_cache: + {% raw %} + key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% endraw %} + paths: + - conda + - env + - run: + name: Run style check + command: .circleci/unittest/linux/scripts/run_style_checks.sh + build_docs: + <<: *binary_common + docker: + - image: continuumio/miniconda3 + resource_class: medium + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - checkout + - run: + name: install binaries + command: | + set -x + conda install make + pip install $(ls ~/workspace/torchtext*.whl) --pre -f "https://download.pytorch.org/whl/${UPLOAD_CHANNEL}/cpu/torch_${UPLOAD_CHANNEL}.html" + - run: + name: Build docs + command: | + set -x + pushd docs + pip install -r requirements.txt + make html + popd + - persist_to_workspace: + root: ./ + paths: + - "*" + + upload_docs: + <<: *binary_common + docker: + - image: continuumio/miniconda3 + resource_class: medium + steps: + - attach_workspace: + at: ~/workspace + - run: + name: Generate netrc + command: | + # set credentials for https pushing + # requires the org-member context + cat > ~/.netrc \<> ~/.bashrc +RUN source /usr/local/etc/profile.d/conda.sh && conda activate python3.6 && conda install -y -c conda-forge sox && conda install -y numpy +RUN source /usr/local/etc/profile.d/conda.sh && conda activate python3.7 && conda install -y -c conda-forge sox && conda install -y numpy +RUN source /usr/local/etc/profile.d/conda.sh && conda activate python3.8 && conda install -y -c conda-forge sox && conda install -y numpy +CMD [ "/bin/bash"] diff --git a/.circleci/unittest/linux/scripts/environment.yml b/.circleci/unittest/linux/scripts/environment.yml new file mode 100644 index 0000000000..b60f219e16 --- /dev/null +++ b/.circleci/unittest/linux/scripts/environment.yml @@ -0,0 +1,21 @@ +channels: + - defaults +dependencies: + - flake8==3.7.9 + - codecov + - pip + - pip: + - dataclasses + - nltk + - requests + - revtok + - pytest + - pytest-cov + - pytest-pythonpath + - sacremoses + - spacy + - sphinx + - sphinx-rtd-theme + - tqdm + - https://github.com/explosion/spacy-models/releases/download/de_core_news_sm-2.2.5/de_core_news_sm-2.2.5.tar.gz#egg=de_core_news_sm==2.2.5 + - https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.5/en_core_web_sm-2.2.5.tar.gz#egg=en_core_web_sm==2.2.5 diff --git a/.circleci/unittest/linux/scripts/install.sh b/.circleci/unittest/linux/scripts/install.sh new file mode 100755 index 0000000000..41bca48068 --- /dev/null +++ b/.circleci/unittest/linux/scripts/install.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +unset PYTORCH_VERSION +# For unittest, nightly PyTorch is used as the following section, +# so no need to set PYTORCH_VERSION. +# In fact, keeping PYTORCH_VERSION forces us to hardcode PyTorch version in config. + +set -e + +eval "$(./conda/bin/conda shell.bash hook)" +conda activate ./env + +printf "* Installing PyTorch\n" +conda install -y -c "pytorch-${UPLOAD_CHANNEL}" pytorch cpuonly + +printf "* Installing torchtext\n" +git submodule update --init --recursive +python setup.py develop diff --git a/.circleci/unittest/linux/scripts/post_process.sh b/.circleci/unittest/linux/scripts/post_process.sh new file mode 100755 index 0000000000..a84a0dea55 --- /dev/null +++ b/.circleci/unittest/linux/scripts/post_process.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e + +eval "$(./conda/bin/conda shell.bash hook)" +conda activate ./env + +codecov diff --git a/.circleci/unittest/linux/scripts/run_style_checks.sh b/.circleci/unittest/linux/scripts/run_style_checks.sh new file mode 100755 index 0000000000..c44c1d6554 --- /dev/null +++ b/.circleci/unittest/linux/scripts/run_style_checks.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +set -u + +eval "$(./conda/bin/conda shell.bash hook)" +conda activate ./env + +# We want to run all the style checks even if one of them fail. + +exit_status=0 + +printf "\x1b[34mRunning flake8: " +flake8 --version +printf "\x1b[0m\n" +flake8 torchtext test build_tools/setup_helpers +status=$? +exit_status="$((exit_status+status))" +if [ "${status}" -ne 0 ]; then + printf "\x1b[31mflake8 failed. Check the format of Python files.\x1b[0m\n" +fi + +printf "\x1b[34mRunning clang-format: " +./clang-format --version +printf "\x1b[0m\n" +git-clang-format --binary ./clang-format origin/master +git diff --exit-code +status=$? +exit_status="$((exit_status+status))" +if [ "${status}" -ne 0 ]; then + printf "\x1b[31mC++ files are not formatted. Please use git-clang-format to format CPP files.\x1b[0m\n" +fi +exit $exit_status diff --git a/.circleci/unittest/linux/scripts/run_test.sh b/.circleci/unittest/linux/scripts/run_test.sh new file mode 100755 index 0000000000..c8322ea5f9 --- /dev/null +++ b/.circleci/unittest/linux/scripts/run_test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +eval "$(./conda/bin/conda shell.bash hook)" +conda activate ./env + +python -m torch.utils.collect_env +pytest --cov=torchtext --junitxml=test-results/junit.xml -v --durations 20 test diff --git a/.circleci/unittest/linux/scripts/setup_env.sh b/.circleci/unittest/linux/scripts/setup_env.sh new file mode 100755 index 0000000000..d4f5457906 --- /dev/null +++ b/.circleci/unittest/linux/scripts/setup_env.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# This script is for setting up environment in which unit test is ran. +# To speed up the CI time, the resulting environment is cached. +# +# Do not install PyTorch and torchtext here, otherwise they also get cached. + +set -e + +this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +root_dir="$(git rev-parse --show-toplevel)" +conda_dir="${root_dir}/conda" +env_dir="${root_dir}/env" + +cd "${root_dir}" + +case "$(uname -s)" in + Darwin*) os=MacOSX;; + *) os=Linux +esac + +# 1. Install conda at ./conda +if [ ! -d "${conda_dir}" ]; then + printf "* Installing conda\n" + wget -O miniconda.sh http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh + bash ./miniconda.sh -b -f -p "${conda_dir}" +fi +eval "$(${conda_dir}/bin/conda shell.bash hook)" + +# 2. Create test environment at ./env +if [ ! -d "${env_dir}" ]; then + printf "* Creating a test environment\n" + conda create --prefix "${env_dir}" -y python="$PYTHON_VERSION" +fi +conda activate "${env_dir}" + +# 3. Install Conda dependencies +printf "* Installing dependencies (except PyTorch)\n" +conda env update --file "${this_dir}/environment.yml" --prune +if [ "${os}" == Linux ] ; then + clangformat_path="${root_dir}/clang-format" + curl https://oss-clang-format.s3.us-east-2.amazonaws.com/linux64/clang-format-linux64 -o "${clangformat_path}" + chmod +x "${clangformat_path}" +fi + +# 4. Download +printf "* Downloading SpaCy English models\n" +python -m spacy download en diff --git a/.circleci/unittest/windows/scripts/environment.yml b/.circleci/unittest/windows/scripts/environment.yml new file mode 100644 index 0000000000..28790d2585 --- /dev/null +++ b/.circleci/unittest/windows/scripts/environment.yml @@ -0,0 +1,23 @@ +channels: + - defaults +dependencies: + - flake8==3.7.9 + - codecov + - pip + - pip: + - dataclasses + - nltk + - requests + - revtok + - pytest + - pytest-cov + - pytest-pythonpath + - sacremoses + - spacy + - sphinx + - sphinx-rtd-theme + - tqdm + - certifi + - future + - https://github.com/explosion/spacy-models/releases/download/de_core_news_sm-2.2.5/de_core_news_sm-2.2.5.tar.gz#egg=de_core_news_sm==2.2.5 + - https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.5/en_core_web_sm-2.2.5.tar.gz#egg=en_core_web_sm==2.2.5 diff --git a/.circleci/unittest/windows/scripts/install.sh b/.circleci/unittest/windows/scripts/install.sh new file mode 100644 index 0000000000..72a042c080 --- /dev/null +++ b/.circleci/unittest/windows/scripts/install.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +unset PYTORCH_VERSION +# For unittest, nightly PyTorch is used as the following section, +# so no need to set PYTORCH_VERSION. +# In fact, keeping PYTORCH_VERSION forces us to hardcode PyTorch version in config. + +set -e + +this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +root_dir="$(git rev-parse --show-toplevel)" + +cd "${root_dir}" + +eval "$(./conda/Scripts/conda.exe 'shell.bash' 'hook')" +conda activate ./env + +printf "* Installing PyTorch\n" +conda install -y -c "pytorch-${UPLOAD_CHANNEL}" pytorch cpuonly + +printf "* Installing torchtext\n" +git submodule update --init --recursive +"$root_dir/packaging/vc_env_helper.bat" python setup.py develop diff --git a/.circleci/unittest/windows/scripts/install_conda.bat b/.circleci/unittest/windows/scripts/install_conda.bat new file mode 100644 index 0000000000..6052ad08b1 --- /dev/null +++ b/.circleci/unittest/windows/scripts/install_conda.bat @@ -0,0 +1 @@ +start /wait "" "%miniconda_exe%" /S /InstallationType=JustMe /RegisterPython=0 /AddToPath=0 /D=%tmp_conda% diff --git a/.circleci/unittest/windows/scripts/post_process.sh b/.circleci/unittest/windows/scripts/post_process.sh new file mode 100644 index 0000000000..b132113194 --- /dev/null +++ b/.circleci/unittest/windows/scripts/post_process.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e + +eval "$(./conda/Scripts/conda.exe 'shell.bash' 'hook')" +conda activate ./env + +codecov diff --git a/.circleci/unittest/windows/scripts/run_test.sh b/.circleci/unittest/windows/scripts/run_test.sh new file mode 100644 index 0000000000..909177e2d4 --- /dev/null +++ b/.circleci/unittest/windows/scripts/run_test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e + +eval "$(./conda/Scripts/conda.exe 'shell.bash' 'hook')" +conda activate ./env + +python -m torch.utils.collect_env +pytest --cov=torchtext --junitxml=test-results/junit.xml -v --durations 20 test diff --git a/.circleci/unittest/windows/scripts/setup_env.sh b/.circleci/unittest/windows/scripts/setup_env.sh new file mode 100644 index 0000000000..cd44b436dc --- /dev/null +++ b/.circleci/unittest/windows/scripts/setup_env.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# This script is for setting up environment in which unit test is ran. +# To speed up the CI time, the resulting environment is cached. +# +# Do not install PyTorch and torchtext here, otherwise they also get cached. + +set -e + +this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +root_dir="$(git rev-parse --show-toplevel)" +conda_dir="${root_dir}/conda" +env_dir="${root_dir}/env" + +cd "${root_dir}" + +# 1. Install conda at ./conda +if [ ! -d "${conda_dir}" ]; then + printf "* Installing conda\n" + export tmp_conda="$(echo $conda_dir | tr '/' '\\')" + export miniconda_exe="$(echo $root_dir | tr '/' '\\')\\miniconda.exe" + curl --output miniconda.exe https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe -O + "$this_dir/install_conda.bat" + unset tmp_conda + unset miniconda_exe +fi +eval "$(${conda_dir}/Scripts/conda.exe 'shell.bash' 'hook')" + +# 2. Create test environment at ./env +if [ ! -d "${env_dir}" ]; then + printf "* Creating a test environment\n" + conda create --prefix "${env_dir}" -y python="$PYTHON_VERSION" +fi +conda activate "${env_dir}" + +# 3. Install Conda dependencies +printf "* Installing dependencies (except PyTorch)\n" +conda env update --file "${this_dir}/environment.yml" --prune + +# 4. Download +printf "* Downloading SpaCy English models\n" +python -m spacy download en diff --git a/.circleci/utils/test_sort_yaml.py b/.circleci/utils/test_sort_yaml.py new file mode 100755 index 0000000000..dc6db481dd --- /dev/null +++ b/.circleci/utils/test_sort_yaml.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +""" +To compare new version with previous: + + ./regenerate.sh + meld <(git show HEAD:./config.yml | ./sort-yaml.py) <(cat config.yml | ./sort-yaml.py) +""" + + +import sys +import yaml + +sys.stdout.write(yaml.dump(yaml.load(sys.stdin, Loader=yaml.FullLoader), sort_keys=True)) diff --git a/.flake8 b/.flake8 index 50ecc8aa11..80872e2c3e 100644 --- a/.flake8 +++ b/.flake8 @@ -1,4 +1,5 @@ [flake8] -ignore = E402,E722,W503,W504,F821 +# E501 is not flexible enough, we're using B950 instead. Consistent with pytorch +ignore = E402,E722,W503,W504,F821,E501 max-line-length = 120 -exclude = docs/source +exclude = docs/source,third_party diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md deleted file mode 100644 index 15104939bf..0000000000 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: "\U0001F41B Bug Report" -about: Submit a bug report to help us improve TorchText - ---- - -## 🐛 Bug -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Environment** - -Please copy and paste the output from our -[environment collection script](https://raw.githubusercontent.com/pytorch/text/master/torchtext/utils/collect_env.py) -(or fill out the checklist below manually). - -You can get the script and run it with: -``` -wget https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect_env.py -# For security purposes, please check the contents of collect_env.py before running it. -python collect_env.py -python -c "import torchtext; print(\"torchtext version is \", torchtext.__version__)" -``` - - - PyTorch Version (e.g., 1.0): - - OS (e.g., Linux): - - How you installed PyTorch (`conda`, `pip`, source): - - Build command you used (if compiling from source): - - Python version: - - CUDA/cuDNN version: - - GPU models and configuration: - - Any other relevant information: - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md deleted file mode 100644 index b9e37a2774..0000000000 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: "\U0001F4DA Documentation" -about: Report an issue related to TorchText - ---- - -## 📚 Documentation - -**Description** - diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md deleted file mode 100644 index 4872607a45..0000000000 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: "\U0001F680Feature Request" -about: Submit a proposal/request for a new TorchText feature - ---- - -## 🚀 Feature - - -**Motivation** - - - -**Pitch** - - - -**Alternatives** - - - -**Additional context** - - diff --git a/.github/ISSUE_TEMPLATE/questions-help-support.md b/.github/ISSUE_TEMPLATE/questions-help-support.md deleted file mode 100644 index d1e8eab0dc..0000000000 --- a/.github/ISSUE_TEMPLATE/questions-help-support.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: "❓Questions/Help/Support" -about: Do you need support? We have resources. - ---- - -## ❓ Questions and Help - -**Description** - diff --git a/.gitignore b/.gitignore index 8e2279529b..99d4e175b9 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,9 @@ docs/_build/ # PyBuilder target/ +# computed checksum files +torchtext/experimental/asset/.checksums/ + # Jupyter Notebook .ipynb_checkpoints @@ -109,6 +112,9 @@ venv.bak/ # Rope project settings .ropeproject +# VSCode project settings +.vscode + # mkdocs documentation /site @@ -120,3 +126,8 @@ venv.bak/ # vim *.swp *.swo + +torchtext/version.py + +# Thirdparty directories +third_party/*/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..14a0054ef9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,13 @@ +[submodule "third_party/sentencepiece"] + path = third_party/sentencepiece + url = https://github.com/google/sentencepiece + ignore = dirty +[submodule "third_party/re2"] + path = third_party/re2 + url = https://github.com/google/re2 + ignore = dirty +[submodule "third_party/double-conversion"] + path = third_party/double-conversion + url = https://github.com/google/double-conversion + ignore = dirty + From 310eac1e99caff86da056cd522aaff5008098f1e Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 37/68] add a newline mark to config.yml file (#1128) Reviewed By: zhangguanheng66 Differential Revision: D26369003 fbshipit-source-id: 09ca48f9705d8663b06e6a329a6b64b24f9c148e --- .circleci/regenerate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/regenerate.py b/.circleci/regenerate.py index 257f3021b0..6ab710bdf6 100755 --- a/.circleci/regenerate.py +++ b/.circleci/regenerate.py @@ -171,3 +171,4 @@ def unittest_workflows(indentation=6): build_workflows=build_workflows, unittest_workflows=unittest_workflows, )) + f.write("\n") From 35a87205b7977e7d9a7d83ad194659137cc298fa Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 38/68] Replace model with full name when spacy load is used (#1140) Reviewed By: zhangguanheng66 Differential Revision: D26369005 fbshipit-source-id: b1e6b5d77810bb8f67d14b8a1c7ec0a9f4831cab --- torchtext/data/utils.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/torchtext/data/utils.py b/torchtext/data/utils.py index 045c2646fb..12f653290b 100644 --- a/torchtext/data/utils.py +++ b/torchtext/data/utils.py @@ -112,7 +112,17 @@ def get_tokenizer(tokenizer, language='en'): if tokenizer == "spacy": try: import spacy - spacy = spacy.load(language) + try: + spacy = spacy.load(language) + except IOError: + # Model shortcuts no longer work in spaCy 3.0+, try using fullnames + # List is from https://github.com/explosion/spaCy/blob/b903de3fcb56df2f7247e5b6cfa6b66f4ff02b62/spacy/errors.py#L789 + OLD_MODEL_SHORTCUTS = spacy.errors.OLD_MODEL_SHORTCUTS if hasattr(spacy.errors, 'OLD_MODEL_SHORTCUTS') else {} + if language not in OLD_MODEL_SHORTCUTS: + raise + import warnings + warnings.warn(f'Spacy model "{language}" could not be loaded, trying "{OLD_MODEL_SHORTCUTS[language]}" instead') + spacy = spacy.load(OLD_MODEL_SHORTCUTS[language]) return partial(_spacy_tokenize, spacy=spacy) except ImportError: print("Please install SpaCy. " From ab53f2f79fb42227d8993dd658cda08668d2b016 Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 39/68] Fix the num_lines argument of the setup_iter func in RawTextIterableDataset (#1142) Reviewed By: zhangguanheng66 Differential Revision: D26368999 fbshipit-source-id: 4b50e5d9e5fbdf633e8b3f0072223eed050af793 --- test/data/test_builtin_datasets.py | 6 ++++++ torchtext/experimental/datasets/raw/common.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index fcef4f1507..ca53feff6a 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -138,6 +138,12 @@ def test_text_classification(self): self._helper_test_func(len(test_iter), 7600, next(iter(test_iter))[1][:25], 'Fears for T N pension aft') del train_iter, test_iter + def test_num_lines_of_setup_iter_dataset(self): + train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() + train_iter.setup_iter(start=10, num_lines=100) + _data = [item for item in train_iter] + self.assertEqual(len(_data), 100) + def test_imdb(self): from torchtext.experimental.datasets import IMDB from torchtext.vocab import Vocab diff --git a/torchtext/experimental/datasets/raw/common.py b/torchtext/experimental/datasets/raw/common.py index 9be6505168..06415830c3 100644 --- a/torchtext/experimental/datasets/raw/common.py +++ b/torchtext/experimental/datasets/raw/common.py @@ -40,7 +40,7 @@ def __iter__(self): for i, item in enumerate(self._iterator): if i < self.start: continue - if self.num_lines and i > (self.start + self.num_lines): + if self.num_lines and i >= (self.start + self.num_lines): break yield item From 8168aba9e93d02dc230e37d8689a8c42c39e0989 Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 40/68] Fix broken CI tests due to spacy 3.0 release (#1138) Reviewed By: zhangguanheng66 Differential Revision: D26368998 fbshipit-source-id: 84e883562a9a3d0fe47b54823b22f7b2cd82fca4 --- .../unittest/linux/scripts/environment.yml | 4 ++-- .circleci/unittest/linux/scripts/setup_env.sh | 4 +++- .../unittest/windows/scripts/environment.yml | 4 ++-- .../unittest/windows/scripts/setup_env.sh | 4 +++- test/data/test_builtin_datasets.py | 20 +++++++++++++++---- test/test_build.py | 2 +- test/translation.py | 4 ++-- torchtext/data/utils.py | 1 - 8 files changed, 29 insertions(+), 14 deletions(-) diff --git a/.circleci/unittest/linux/scripts/environment.yml b/.circleci/unittest/linux/scripts/environment.yml index b60f219e16..282877c207 100644 --- a/.circleci/unittest/linux/scripts/environment.yml +++ b/.circleci/unittest/linux/scripts/environment.yml @@ -17,5 +17,5 @@ dependencies: - sphinx - sphinx-rtd-theme - tqdm - - https://github.com/explosion/spacy-models/releases/download/de_core_news_sm-2.2.5/de_core_news_sm-2.2.5.tar.gz#egg=de_core_news_sm==2.2.5 - - https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.5/en_core_web_sm-2.2.5.tar.gz#egg=en_core_web_sm==2.2.5 + - https://github.com/explosion/spacy-models/releases/download/de_core_news_sm-3.0.0/de_core_news_sm-3.0.0.tar.gz#egg=de_core_news_sm==3.0.0 + - https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.0.0/en_core_web_sm-3.0.0.tar.gz#egg=en_core_web_sm==3.0.0 diff --git a/.circleci/unittest/linux/scripts/setup_env.sh b/.circleci/unittest/linux/scripts/setup_env.sh index d4f5457906..eb075b1eb1 100755 --- a/.circleci/unittest/linux/scripts/setup_env.sh +++ b/.circleci/unittest/linux/scripts/setup_env.sh @@ -45,4 +45,6 @@ fi # 4. Download printf "* Downloading SpaCy English models\n" -python -m spacy download en +python -m spacy download en_core_web_sm +printf "* Downloading SpaCy German models\n" +python -m spacy download de_core_news_sm diff --git a/.circleci/unittest/windows/scripts/environment.yml b/.circleci/unittest/windows/scripts/environment.yml index 28790d2585..2d7c790b91 100644 --- a/.circleci/unittest/windows/scripts/environment.yml +++ b/.circleci/unittest/windows/scripts/environment.yml @@ -19,5 +19,5 @@ dependencies: - tqdm - certifi - future - - https://github.com/explosion/spacy-models/releases/download/de_core_news_sm-2.2.5/de_core_news_sm-2.2.5.tar.gz#egg=de_core_news_sm==2.2.5 - - https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.5/en_core_web_sm-2.2.5.tar.gz#egg=en_core_web_sm==2.2.5 + - https://github.com/explosion/spacy-models/releases/download/de_core_news_sm-3.0.0/de_core_news_sm-3.0.0.tar.gz#egg=de_core_news_sm==3.0.0 + - https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.0.0/en_core_web_sm-3.0.0.tar.gz#egg=en_core_web_sm==3.0.0 diff --git a/.circleci/unittest/windows/scripts/setup_env.sh b/.circleci/unittest/windows/scripts/setup_env.sh index cd44b436dc..ea99130c5e 100644 --- a/.circleci/unittest/windows/scripts/setup_env.sh +++ b/.circleci/unittest/windows/scripts/setup_env.sh @@ -39,4 +39,6 @@ conda env update --file "${this_dir}/environment.yml" --prune # 4. Download printf "* Downloading SpaCy English models\n" -python -m spacy download en +python -m spacy download en_core_web_sm +printf "* Downloading SpaCy German models\n" +python -m spacy download de_core_news_sm diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index ca53feff6a..8ed1a0c04e 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -206,14 +206,21 @@ def test_multi30k(self): from torchtext.experimental.datasets import Multi30k # smoke test to ensure multi30k works properly train_dataset, valid_dataset, test_dataset = Multi30k() + + # This change is due to the BC breaking in spacy 3.0 self._helper_test_func(len(train_dataset), 29000, train_dataset[20], - ([4, 444, 2531, 47, 17480, 7423, 8, 158, 10, 12, 5849, 3, 2], + # ([4, 444, 2531, 47, 17480, 7423, 8, 158, 10, 12, 5849, 3, 2], + ([4, 444, 2529, 47, 17490, 7422, 8, 158, 10, 12, 5846, 3, 2], [5, 61, 530, 137, 1494, 10, 9, 280, 6, 2, 3749, 4, 3])) + self._helper_test_func(len(valid_dataset), 1014, valid_dataset[30], ([4, 179, 26, 85, 1005, 57, 19, 154, 3, 2], [5, 24, 32, 81, 47, 1348, 6, 2, 119, 4, 3])) + + # This change is due to the BC breaking in spacy 3.0 self._helper_test_func(len(test_dataset), 1000, test_dataset[40], - ([4, 26, 6, 12, 3915, 1538, 21, 64, 3, 2], + # ([4, 26, 6, 12, 3915, 1538, 21, 64, 3, 2], + ([4, 26, 6, 12, 3913, 1537, 21, 64, 3, 2], [5, 32, 20, 2, 747, 345, 1915, 6, 46, 4, 3])) de_vocab, en_vocab = train_dataset.get_vocab() @@ -221,7 +228,9 @@ def test_multi30k(self): de_vocab[token] for token in 'Zwei Männer verpacken Donuts in Kunststofffolie'.split() ] - self.assertEqual(de_tokens_ids, [20, 30, 18705, 4448, 6, 6241]) + # This change is due to the BC breaking in spacy 3.0 + # self.assertEqual(de_tokens_ids, [20, 30, 18705, 4448, 6, 6241]) + self.assertEqual(de_tokens_ids, [20, 30, 18714, 4447, 6, 6239]) en_tokens_ids = [ en_vocab[token] for token in @@ -240,8 +249,11 @@ def test_multi30k(self): 'A group of men are loading cotton onto a truck\n'])) del train_iter, valid_iter train_dataset, = Multi30k(data_select=('train')) + + # This change is due to the BC breaking in spacy 3.0 self._helper_test_func(len(train_dataset), 29000, train_dataset[20], - ([4, 444, 2531, 47, 17480, 7423, 8, 158, 10, 12, 5849, 3, 2], + # ([4, 444, 2531, 47, 17480, 7423, 8, 158, 10, 12, 5849, 3, 2], + ([4, 444, 2529, 47, 17490, 7422, 8, 158, 10, 12, 5846, 3, 2], [5, 61, 530, 137, 1494, 10, 9, 280, 6, 2, 3749, 4, 3])) datafile = os.path.join(self.project_root, ".data", "train*") diff --git a/test/test_build.py b/test/test_build.py index d61e844280..2e29392562 100644 --- a/test/test_build.py +++ b/test/test_build.py @@ -107,7 +107,7 @@ class TestDataUtils(TorchtextTestCase): def test_get_tokenizer_spacy(self): # Test SpaCy option, and verify it properly handles punctuation. - assert torchtext.data.get_tokenizer("spacy")(str(self.TEST_STR)) == [ + assert torchtext.data.get_tokenizer("spacy", language='en_core_web_sm')(str(self.TEST_STR)) == [ "A", "string", ",", "particularly", "one", "with", "slightly", "complex", "punctuation", "."] diff --git a/test/translation.py b/test/translation.py index eb3c47a349..89a6f9017f 100644 --- a/test/translation.py +++ b/test/translation.py @@ -4,8 +4,8 @@ import re import spacy -spacy_de = spacy.load('de') -spacy_en = spacy.load('en') +spacy_de = spacy.load('de_core_news_sm') +spacy_en = spacy.load('en_core_web_sm') url = re.compile('(.*)') diff --git a/torchtext/data/utils.py b/torchtext/data/utils.py index 12f653290b..240a3799ff 100644 --- a/torchtext/data/utils.py +++ b/torchtext/data/utils.py @@ -2,7 +2,6 @@ from contextlib import contextmanager from copy import deepcopy import re - from functools import partial From 86cc913112c6a2bea89f12c54a624b5c5109c568 Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 41/68] Switch data_select in dataset signature to split (#1143) Reviewed By: zhangguanheng66 Differential Revision: D26369006 fbshipit-source-id: 608f42fa180db9ebcfaaeadc6b8cdd29393262af --- test/data/test_builtin_datasets.py | 26 +++--- test/experimental/test_with_asset.py | 4 +- .../datasets/language_modeling.py | 52 +++++------ .../experimental/datasets/question_answer.py | 26 +++--- .../datasets/raw/language_modeling.py | 54 ++++++------ .../datasets/raw/question_answer.py | 20 ++--- .../datasets/raw/sequence_tagging.py | 18 ++-- .../datasets/raw/text_classification.py | 62 ++++++------- .../experimental/datasets/raw/translation.py | 24 +++--- .../experimental/datasets/sequence_tagging.py | 26 +++--- .../datasets/text_classification.py | 86 +++++++++---------- .../experimental/datasets/translation.py | 34 ++++---- 12 files changed, 216 insertions(+), 216 deletions(-) diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 8ed1a0c04e..d7a02995d7 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -57,12 +57,12 @@ def test_wikitext2(self): self.assertEqual(tokens_ids, [2, 286, 503, 700]) # Add test for the subset of the standard datasets - train_iter, valid_iter, test_iter = torchtext.experimental.datasets.raw.WikiText2(data_select=('train', 'valid', 'test')) + train_iter, valid_iter, test_iter = torchtext.experimental.datasets.raw.WikiText2(split=('train', 'valid', 'test')) self._helper_test_func(len(train_iter), 36718, next(iter(train_iter)), ' \n') self._helper_test_func(len(valid_iter), 3760, next(iter(valid_iter)), ' \n') self._helper_test_func(len(test_iter), 4358, next(iter(test_iter)), ' \n') del train_iter, valid_iter, test_iter - train_dataset, test_dataset = WikiText2(data_select=('train', 'test')) + train_dataset, test_dataset = WikiText2(split=('train', 'test')) train_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) test_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) self._helper_test_func(len(train_data), 2049990, train_data[20:25], @@ -105,14 +105,14 @@ def test_penntreebank(self): self.assertEqual(tokens_ids, [2, 2550, 3344, 1125]) # Add test for the subset of the standard datasets - train_dataset, test_dataset = PennTreebank(data_select=('train', 'test')) + train_dataset, test_dataset = PennTreebank(split=('train', 'test')) train_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) test_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, test_dataset))) self._helper_test_func(len(train_data), 924412, train_data[20:25], [9919, 9920, 9921, 9922, 9188]) self._helper_test_func(len(test_data), 82114, test_data[30:35], [397, 93, 4, 16, 7]) - train_iter, test_iter = torchtext.experimental.datasets.raw.PennTreebank(data_select=('train', 'test')) + train_iter, test_iter = torchtext.experimental.datasets.raw.PennTreebank(split=('train', 'test')) self._helper_test_func(len(train_iter), 42068, next(iter(train_iter))[:15], ' aer banknote b') self._helper_test_func(len(test_iter), 3761, next(iter(test_iter))[:25], " no it was n't black mond") del train_iter, test_iter @@ -130,7 +130,7 @@ def test_text_classification(self): [2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]) # Add test for the subset of the standard datasets - train_dataset, = AG_NEWS(data_select=('train')) + train_dataset, = AG_NEWS(split=('train')) self._helper_test_func(len(train_dataset), 120000, train_dataset[-1][1][:10], [2155, 223, 2405, 30, 3010, 2204, 54, 3603, 4930, 2405]) train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() @@ -160,7 +160,7 @@ def test_imdb(self): new_train_data, new_test_data = IMDB(vocab=new_vocab) # Add test for the subset of the standard datasets - train_dataset, = IMDB(data_select=('train')) + train_dataset, = IMDB(split=('train')) self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], [13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]) train_iter, test_iter = torchtext.experimental.datasets.raw.IMDB() @@ -240,7 +240,7 @@ def test_multi30k(self): [18, 24, 1168, 807, 16, 56, 83, 335, 1338]) # Add test for the subset of the standard datasets - train_iter, valid_iter = torchtext.experimental.datasets.raw.Multi30k(data_select=('train', 'valid')) + train_iter, valid_iter = torchtext.experimental.datasets.raw.Multi30k(split=('train', 'valid')) self._helper_test_func(len(train_iter), 29000, ' '.join(next(iter(train_iter))), ' '.join(['Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n', 'Two young, White males are outside near many bushes.\n'])) @@ -248,7 +248,7 @@ def test_multi30k(self): ' '.join(['Eine Gruppe von Männern lädt Baumwolle auf einen Lastwagen\n', 'A group of men are loading cotton onto a truck\n'])) del train_iter, valid_iter - train_dataset, = Multi30k(data_select=('train')) + train_dataset, = Multi30k(split=('train')) # This change is due to the BC breaking in spacy 3.0 self._helper_test_func(len(train_dataset), 29000, train_dataset[20], @@ -311,11 +311,11 @@ def test_udpos_sequence_tagging(self): self.assertEqual(tokens_ids, [1206, 8, 69, 60, 157, 452]) # Add test for the subset of the standard datasets - train_dataset, = UDPOS(data_select=('train')) + train_dataset, = UDPOS(split=('train')) self._helper_test_func(len(train_dataset), 12543, (train_dataset[0][0][:10], train_dataset[-1][2][:10]), ([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585], [6, 20, 8, 10, 8, 8, 24, 13, 8, 15])) - train_iter, valid_iter = torchtext.experimental.datasets.raw.UDPOS(data_select=('train', 'valid')) + train_iter, valid_iter = torchtext.experimental.datasets.raw.UDPOS(split=('train', 'valid')) self._helper_test_func(len(train_iter), 12543, ' '.join(next(iter(train_iter))[0][:5]), ' '.join(['Al', '-', 'Zaman', ':', 'American'])) self._helper_test_func(len(valid_iter), 2002, ' '.join(next(iter(valid_iter))[0][:5]), @@ -358,7 +358,7 @@ def test_conll_sequence_tagging(self): self.assertEqual(tokens_ids, [970, 5, 135, 43, 214, 690]) # Add test for the subset of the standard datasets - train_dataset, = CoNLL2000Chunking(data_select=('train')) + train_dataset, = CoNLL2000Chunking(split=('train')) self._helper_test_func(len(train_dataset), 8936, (train_dataset[0][0][:10], train_dataset[0][1][:10], train_dataset[0][2][:10], train_dataset[-1][0][:10], train_dataset[-1][1][:10], train_dataset[-1][2][:10]), @@ -393,7 +393,7 @@ def test_squad1(self): new_train_data, new_test_data = SQuAD1(vocab=new_vocab) # Add test for the subset of the standard datasets - train_dataset, = SQuAD1(data_select=('train')) + train_dataset, = SQuAD1(split=('train')) context, question, answers, ans_pos = train_dataset[100] self._helper_test_func(len(train_dataset), 87599, (question[:5], ans_pos[0]), ([7, 24, 86, 52, 2], [72, 72])) @@ -422,7 +422,7 @@ def test_squad2(self): new_train_data, new_test_data = SQuAD2(vocab=new_vocab) # Add test for the subset of the standard datasets - train_dataset, = SQuAD2(data_select=('train')) + train_dataset, = SQuAD2(split=('train')) context, question, answers, ans_pos = train_dataset[200] self._helper_test_func(len(train_dataset), 130319, (question[:5], ans_pos[0]), ([84, 50, 1421, 12, 5439], [9, 9])) diff --git a/test/experimental/test_with_asset.py b/test/experimental/test_with_asset.py index 146eec53ce..50c01935a9 100644 --- a/test/experimental/test_with_asset.py +++ b/test/experimental/test_with_asset.py @@ -62,10 +62,10 @@ def test_wikitext103(self): self.assertEqual(tokens_ids, [2, 320, 437, 687]) # Add test for the subset of the standard datasets - train_dataset, test_dataset = torchtext.experimental.datasets.raw.WikiText103(data_select=('train', 'test')) + train_dataset, test_dataset = torchtext.experimental.datasets.raw.WikiText103(split=('train', 'test')) self._helper_test_func(len(train_dataset), 1801350, next(iter(train_dataset)), ' \n') self._helper_test_func(len(test_dataset), 4358, next(iter(test_dataset)), ' \n') - train_dataset, test_dataset = WikiText103(vocab=builtin_vocab, data_select=('train', 'test')) + train_dataset, test_dataset = WikiText103(vocab=builtin_vocab, split=('train', 'test')) self._helper_test_func(len(train_dataset), 1801350, train_dataset[10][:5], [2, 69, 12, 14, 265]) self._helper_test_func(len(test_dataset), 4358, test_dataset[28][:5], diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index 3350c3f3b0..e841314c91 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -58,19 +58,19 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, tokenizer, root, vocab, data_select, year, language): +def _setup_datasets(dataset_name, tokenizer, root, vocab, split, year, language): if tokenizer is None: tokenizer = get_tokenizer('basic_english') - data_select = check_default_set(data_select, ('train', 'test', 'valid')) + split = check_default_set(split, ('train', 'test', 'valid')) if vocab is None: - if 'train' not in data_select: + if 'train' not in split: raise TypeError("Must pass a vocab if train is not selected.") if dataset_name == 'WMTNewsCrawl': - raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',), year=year, language=language) + raw_train, = raw.DATASETS[dataset_name](root=root, split=('train',), year=year, language=language) else: - raw_train, = raw.DATASETS[dataset_name](root=root, data_select=('train',)) + raw_train, = raw.DATASETS[dataset_name](root=root, split=('train',)) logger_.info('Building Vocab based on train data') vocab = build_vocab(raw_train, tokenizer) logger_.info('Vocab has %d entries', len(vocab)) @@ -79,16 +79,16 @@ def text_transform(line): return torch.tensor([vocab[token] for token in tokenizer(line)], dtype=torch.long) if dataset_name == 'WMTNewsCrawl': - raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select, year=year, language=language) + raw_datasets = raw.DATASETS[dataset_name](root=root, split=split, year=year, language=language) else: - raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select) - raw_data = {name: list(map(text_transform, raw_dataset)) for name, raw_dataset in zip(data_select, raw_datasets)} - logger_.info('Building datasets for {}'.format(data_select)) + raw_datasets = raw.DATASETS[dataset_name](root=root, split=split) + raw_data = {name: list(map(text_transform, raw_dataset)) for name, raw_dataset in zip(split, raw_datasets)} + logger_.info('Building datasets for {}'.format(split)) return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform) - for item in data_select) + for item in split) -def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 'valid', 'test')): +def WikiText2(tokenizer=None, root='.data', vocab=None, split=('train', 'valid', 'test')): """ Defines WikiText2 datasets. Create language modeling dataset: WikiText2 @@ -102,7 +102,7 @@ def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 'v root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets. Default: ('train', 'valid','test') + split: a string or tuple for the returned datasets. Default: ('train', 'valid','test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -116,13 +116,13 @@ def WikiText2(tokenizer=None, root='.data', vocab=None, data_select=('train', 'v >>> train_dataset, valid_dataset, test_dataset = WikiText2(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() >>> valid_dataset, = WikiText2(tokenizer=tokenizer, vocab=vocab, - data_select='valid') + split='valid') """ - return _setup_datasets("WikiText2", tokenizer, root, vocab, data_select, None, None) + return _setup_datasets("WikiText2", tokenizer, root, vocab, split, None, None) -def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', 'valid', 'test')): +def WikiText103(tokenizer=None, root='.data', vocab=None, split=('train', 'valid', 'test')): """ Defines WikiText103 datasets. Create language modeling dataset: WikiText103 @@ -136,7 +136,7 @@ def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets. Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'valid', 'test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -150,14 +150,14 @@ def WikiText103(tokenizer=None, root='.data', vocab=None, data_select=('train', >>> train_dataset, valid_dataset, test_dataset = WikiText103(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() >>> valid_dataset, = WikiText103(tokenizer=tokenizer, vocab=vocab, - data_select='valid') + split='valid') """ - return _setup_datasets("WikiText103", tokenizer, root, vocab, data_select, None, None) + return _setup_datasets("WikiText103", tokenizer, root, vocab, split, None, None) -def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', 'valid', 'test')): +def PennTreebank(tokenizer=None, root='.data', vocab=None, split=('train', 'valid', 'test')): """ Defines PennTreebank datasets. Create language modeling dataset: PennTreebank @@ -171,7 +171,7 @@ def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tupel for the returned datasets. Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'valid', 'test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -185,14 +185,14 @@ def PennTreebank(tokenizer=None, root='.data', vocab=None, data_select=('train', >>> train_dataset, valid_dataset, test_dataset = PennTreebank(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() >>> valid_dataset, = PennTreebank(tokenizer=tokenizer, vocab=vocab, - data_select='valid') + split='valid') """ - return _setup_datasets("PennTreebank", tokenizer, root, vocab, data_select, None, None) + return _setup_datasets("PennTreebank", tokenizer, root, vocab, split, None, None) -def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, data_select=('train'), year=2010, language='en'): +def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, split=('train'), year=2010, language='en'): """ Defines WMTNewsCrawl datasets. Create language modeling dataset: WMTNewsCrawl @@ -206,7 +206,7 @@ def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, data_select=('train') root: Directory where the datasets are saved. Default: ".data" vocab: Vocabulary used for dataset. If None, it will generate a new vocabulary based on the train data set. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train',)) year: the year of the dataset (Default: 2010) language: the language of the dataset (Default: 'en') @@ -215,12 +215,12 @@ def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, data_select=('train') >>> from torchtext.experimental.datasets import WMTNewsCrawl >>> from torchtext.data.utils import get_tokenizer >>> tokenizer = get_tokenizer("spacy") - >>> train_dataset, = WMTNewsCrawl(tokenizer=tokenizer, data_select='train') + >>> train_dataset, = WMTNewsCrawl(tokenizer=tokenizer, split='train') Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. """ - return _setup_datasets("WMTNewsCrawl", tokenizer, root, vocab, data_select, year, language) + return _setup_datasets("WMTNewsCrawl", tokenizer, root, vocab, split, year, language) DATASETS = { diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index ec239deb97..f24551c5a4 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -61,16 +61,16 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, root, vocab, tokenizer, data_select): +def _setup_datasets(dataset_name, root, vocab, tokenizer, split): text_transform = [] if tokenizer is None: tokenizer = get_tokenizer('basic_english') text_transform = sequential_transforms(tokenizer) - data_select = check_default_set(data_select, ('train', 'dev')) - raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select) - raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(data_select, raw_datasets)} + split = check_default_set(split, ('train', 'dev')) + raw_datasets = raw.DATASETS[dataset_name](root=root, split=split) + raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} if vocab is None: - if 'train' not in data_select: + if 'train' not in split: raise TypeError("Must pass a vocab if train is not selected.") def apply_transform(data): @@ -85,11 +85,11 @@ def apply_transform(data): text_transform = sequential_transforms(text_transform, vocab_func(vocab), totensor(dtype=torch.long)) transforms = {'context': text_transform, 'question': text_transform, 'answers': text_transform, 'ans_pos': totensor(dtype=torch.long)} - logger_.info('Building datasets for {}'.format(data_select)) - return tuple(QuestionAnswerDataset(raw_data[item], vocab, transforms) for item in data_select) + logger_.info('Building datasets for {}'.format(split)) + return tuple(QuestionAnswerDataset(raw_data[item], vocab, transforms) for item in split) -def SQuAD1(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev')): +def SQuAD1(root='.data', vocab=None, tokenizer=None, split=('train', 'dev')): """ Defines SQuAD1 datasets. Create question answer dataset: SQuAD1 @@ -104,7 +104,7 @@ def SQuAD1(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev' The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, all the two datasets (train, dev) are generated. Users could also choose any one of them, for example ('train', 'test') or @@ -120,10 +120,10 @@ def SQuAD1(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev' >>> train, dev = SQuAD1(tokenizer=tokenizer) """ - return _setup_datasets('SQuAD1', root, vocab, tokenizer, data_select) + return _setup_datasets('SQuAD1', root, vocab, tokenizer, split) -def SQuAD2(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev')): +def SQuAD2(root='.data', vocab=None, tokenizer=None, split=('train', 'dev')): """ Defines SQuAD2 datasets. Create question answer dataset: SQuAD2 @@ -138,7 +138,7 @@ def SQuAD2(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev' The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, all the two datasets (train, dev) are generated. Users could also choose any one of them, for example ('train', 'test') or @@ -154,7 +154,7 @@ def SQuAD2(root='.data', vocab=None, tokenizer=None, data_select=('train', 'dev' >>> train, dev = SQuAD2(tokenizer=tokenizer) """ - return _setup_datasets('SQuAD2', root, vocab, tokenizer, data_select) + return _setup_datasets('SQuAD2', root, vocab, tokenizer, split) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py index b14c127316..9edb6e735c 100644 --- a/torchtext/experimental/datasets/raw/language_modeling.py +++ b/torchtext/experimental/datasets/raw/language_modeling.py @@ -17,24 +17,24 @@ } -def _setup_datasets(dataset_name, root, data_select, year, language): - data_select = check_default_set(data_select, ('train', 'test', 'valid')) - if isinstance(data_select, str): - data_select = [data_select] - if not set(data_select).issubset(set(('train', 'test', 'valid'))): - raise TypeError('data_select is not supported!') +def _setup_datasets(dataset_name, root, split, year, language): + split = check_default_set(split, ('train', 'test', 'valid')) + if isinstance(split, str): + split = [split] + if not set(split).issubset(set(('train', 'test', 'valid'))): + raise TypeError('split is not supported!') if dataset_name == 'PennTreebank': extracted_files = [] select_to_index = {'train': 0, 'test': 1, 'valid': 2} extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], root=root, hash_value=MD5['PennTreebank'][key], - hash_type='md5') for key in data_select] + hash_type='md5') for key in split] elif dataset_name == 'WMTNewsCrawl': - if not (data_select == ['train'] or set(data_select).issubset(set(('train',)))): + if not (split == ['train'] or set(split).issubset(set(('train',)))): raise ValueError("WMTNewsCrawl only creates a training dataset. " - "data_select should be 'train' " - "or ('train',), got {}.".format(data_select)) + "split should be 'train' " + "or ('train',), got {}.".format(split)) dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5['WMTNewsCrawl'], hash_type='md5') extracted_files = extract_archive(dataset_tar) file_name = 'news.{}.{}.shuffled'.format(year, language) @@ -44,7 +44,7 @@ def _setup_datasets(dataset_name, root, data_select, year, language): extracted_files = extract_archive(dataset_tar) _path = {} - for item in data_select: + for item in split: for fname in extracted_files: if item in fname: _path[item] = fname @@ -55,10 +55,10 @@ def _setup_datasets(dataset_name, root, data_select, year, language): data[item] = iter(io.open(_path[item], encoding="utf8")) return tuple(RawTextIterableDataset(dataset_name, - NUM_LINES[dataset_name][item], data[item]) for item in data_select) + NUM_LINES[dataset_name][item], data[item]) for item in split) -def WikiText2(root='.data', data_select=('train', 'valid', 'test')): +def WikiText2(root='.data', split=('train', 'valid', 'test')): """ Defines WikiText2 datasets. Create language modeling dataset: WikiText2 @@ -66,7 +66,7 @@ def WikiText2(root='.data', data_select=('train', 'valid', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tupel for the returned datasets. Default: ('train', 'valid, 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'valid, 'test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -76,14 +76,14 @@ def WikiText2(root='.data', data_select=('train', 'valid', 'test')): Examples: >>> from torchtext.experimental.raw.datasets import WikiText2 >>> train_dataset, valid_dataset, test_dataset = WikiText2() - >>> valid_dataset, = WikiText2(data_select='valid') + >>> valid_dataset, = WikiText2(split='valid') """ - return _setup_datasets("WikiText2", root, data_select, None, None) + return _setup_datasets("WikiText2", root, split, None, None) -def WikiText103(root='.data', data_select=('train', 'valid', 'test')): +def WikiText103(root='.data', split=('train', 'valid', 'test')): """ Defines WikiText103 datasets. Create language modeling dataset: WikiText103 @@ -91,7 +91,7 @@ def WikiText103(root='.data', data_select=('train', 'valid', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: the returned datasets. Default: ('train', 'valid','test') + split: the returned datasets. Default: ('train', 'valid','test') By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test'). If 'train' is not in the tuple, an vocab object should be provided which will @@ -100,13 +100,13 @@ def WikiText103(root='.data', data_select=('train', 'valid', 'test')): Examples: >>> from torchtext.experimental.datasets.raw import WikiText103 >>> train_dataset, valid_dataset, test_dataset = WikiText103() - >>> valid_dataset, = WikiText103(data_select='valid') + >>> valid_dataset, = WikiText103(split='valid') """ - return _setup_datasets("WikiText103", root, data_select, None, None) + return _setup_datasets("WikiText103", root, split, None, None) -def PennTreebank(root='.data', data_select=('train', 'valid', 'test')): +def PennTreebank(root='.data', split=('train', 'valid', 'test')): """ Defines PennTreebank datasets. Create language modeling dataset: PennTreebank @@ -114,7 +114,7 @@ def PennTreebank(root='.data', data_select=('train', 'valid', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test','valid')) By default, all the three datasets ('train', 'valid', 'test') are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -125,21 +125,21 @@ def PennTreebank(root='.data', data_select=('train', 'valid', 'test')): Examples: >>> from torchtext.experimental.datasets.raw import PennTreebank >>> train_dataset, valid_dataset, test_dataset = PennTreebank() - >>> valid_dataset, = PennTreebank(data_select='valid') + >>> valid_dataset, = PennTreebank(split='valid') """ - return _setup_datasets("PennTreebank", root, data_select, None, None) + return _setup_datasets("PennTreebank", root, split, None, None) -def WMTNewsCrawl(root='.data', data_select=('train'), year=2010, language='en'): +def WMTNewsCrawl(root='.data', split=('train'), year=2010, language='en'): """ Defines WMT News Crawl. Create language modeling dataset: WMTNewsCrawl Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. + split: a string or tuple for the returned datasets. (Default: 'train') year: the year of the dataset (Default: 2010) language: the language of the dataset (Default: 'en') @@ -147,7 +147,7 @@ def WMTNewsCrawl(root='.data', data_select=('train'), year=2010, language='en'): Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. """ - return _setup_datasets("WMTNewsCrawl", root, data_select, year, language) + return _setup_datasets("WMTNewsCrawl", root, split, year, language) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py index d21dbdbc55..3bc4d83461 100644 --- a/torchtext/experimental/datasets/raw/question_answer.py +++ b/torchtext/experimental/datasets/raw/question_answer.py @@ -29,15 +29,15 @@ def _create_data_from_json(data_path): yield (_context, _question, _answers, _answer_start) -def _setup_datasets(dataset_name, root, data_select): - data_select = check_default_set(data_select, ('train', 'dev')) +def _setup_datasets(dataset_name, root, split): + split = check_default_set(split, ('train', 'dev')) extracted_files = {key: download_from_url(URLS[dataset_name][key], root=root, - hash_value=MD5[dataset_name][key], hash_type='md5') for key in data_select} + hash_value=MD5[dataset_name][key], hash_type='md5') for key in split} return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_json(extracted_files[item])) for item in data_select) + _create_data_from_json(extracted_files[item])) for item in split) -def SQuAD1(root='.data', data_select=('train', 'dev')): +def SQuAD1(root='.data', split=('train', 'dev')): """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD1.0. The iterator yields a tuple of (raw context, raw question, a list of raw answer, a list of answer positions in the raw context). @@ -48,7 +48,7 @@ def SQuAD1(root='.data', data_select=('train', 'dev')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets (Default: ('train', 'dev')) + split: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, for example ('train', 'dev') or just a string 'train'. @@ -58,10 +58,10 @@ def SQuAD1(root='.data', data_select=('train', 'dev')): >>> print(idx, (context, question, answer, ans_pos)) """ - return _setup_datasets("SQuAD1", root, data_select) + return _setup_datasets("SQuAD1", root, split) -def SQuAD2(root='.data', data_select=('train', 'dev')): +def SQuAD2(root='.data', split=('train', 'dev')): """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD2.0. The iterator yields a tuple of (raw context, raw question, a list of raw answer, a list of answer positions in the raw context). @@ -72,7 +72,7 @@ def SQuAD2(root='.data', data_select=('train', 'dev')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets (Default: ('train', 'dev')) + split: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, for example ('train', 'dev') or just a string 'train'. @@ -82,7 +82,7 @@ def SQuAD2(root='.data', data_select=('train', 'dev')): >>> print(idx, (context, question, answer, ans_pos)) """ - return _setup_datasets("SQuAD2", root, data_select) + return _setup_datasets("SQuAD2", root, split) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/sequence_tagging.py b/torchtext/experimental/datasets/raw/sequence_tagging.py index c1a67261f1..b3f221a385 100644 --- a/torchtext/experimental/datasets/raw/sequence_tagging.py +++ b/torchtext/experimental/datasets/raw/sequence_tagging.py @@ -39,8 +39,8 @@ def _construct_filepath(paths, file_suffix): return None -def _setup_datasets(dataset_name, separator, root, data_select): - data_select = check_default_set(data_select, target_select=('train', 'valid', 'test')) +def _setup_datasets(dataset_name, separator, root, split): + split = check_default_set(split, target_select=('train', 'valid', 'test')) extracted_files = [] if isinstance(URLS[dataset_name], dict): for name, item in URLS[dataset_name].items(): @@ -61,17 +61,17 @@ def _setup_datasets(dataset_name, separator, root, data_select): } return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], _create_data_from_iob(data_filenames[item], separator)) - if data_filenames[item] is not None else None for item in data_select) + if data_filenames[item] is not None else None for item in split) -def UDPOS(root=".data", data_select=('train', 'valid', 'test')): +def UDPOS(root=".data", split=('train', 'valid', 'test')): """ Universal Dependencies English Web Treebank Separately returns the training and test dataset Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets (Default: ('train', 'valid', 'test')) + split: a string or tuple for the returned datasets (Default: ('train', 'valid', 'test')) By default, all the datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'valid', 'test') or just a string 'train'. @@ -80,17 +80,17 @@ def UDPOS(root=".data", data_select=('train', 'valid', 'test')): >>> from torchtext.experimental.datasets.raw import UDPOS >>> train_dataset, valid_dataset, test_dataset = UDPOS() """ - return _setup_datasets("UDPOS", "\t", root, data_select) + return _setup_datasets("UDPOS", "\t", root, split) -def CoNLL2000Chunking(root=".data", data_select=('train', 'test')): +def CoNLL2000Chunking(root=".data", split=('train', 'test')): """ CoNLL 2000 Chunking Dataset Separately returns the training and test dataset Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets (Default: ('train', 'test')) + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -98,7 +98,7 @@ def CoNLL2000Chunking(root=".data", data_select=('train', 'test')): >>> from torchtext.experimental.datasets.raw import CoNLL2000Chunking >>> train_dataset, test_dataset = CoNLL2000Chunking() """ - return _setup_datasets("CoNLL2000Chunking", " ", root, data_select) + return _setup_datasets("CoNLL2000Chunking", " ", root, split) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py index 694e4d5d29..4a1706714c 100644 --- a/torchtext/experimental/datasets/raw/text_classification.py +++ b/torchtext/experimental/datasets/raw/text_classification.py @@ -33,8 +33,8 @@ def _create_data_from_csv(data_path): yield int(row[0]), ' '.join(row[1:]) -def _setup_datasets(dataset_name, root, data_select): - data_select = check_default_set(data_select, target_select=('train', 'test')) +def _setup_datasets(dataset_name, root, split): + split = check_default_set(split, target_select=('train', 'test')) if dataset_name == 'AG_NEWS': extracted_files = [download_from_url(URLS[dataset_name][item], root=root, hash_value=MD5['AG_NEWS'][item], @@ -51,10 +51,10 @@ def _setup_datasets(dataset_name, root, data_select): if fname.endswith('test.csv'): cvs_path['test'] = fname return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_csv(cvs_path[item])) for item in data_select) + _create_data_from_csv(cvs_path[item])) for item in split) -def AG_NEWS(root='.data', data_select=('train', 'test')): +def AG_NEWS(root='.data', split=('train', 'test')): """ Defines AG_NEWS datasets. Create supervised learning dataset: AG_NEWS @@ -63,7 +63,7 @@ def AG_NEWS(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -71,10 +71,10 @@ def AG_NEWS(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.AG_NEWS() """ - return _setup_datasets("AG_NEWS", root, data_select) + return _setup_datasets("AG_NEWS", root, split) -def SogouNews(root='.data', data_select=('train', 'test')): +def SogouNews(root='.data', split=('train', 'test')): """ Defines SogouNews datasets. Create supervised learning dataset: SogouNews @@ -83,7 +83,7 @@ def SogouNews(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -91,10 +91,10 @@ def SogouNews(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.SogouNews() """ - return _setup_datasets("SogouNews", root, data_select) + return _setup_datasets("SogouNews", root, split) -def DBpedia(root='.data', data_select=('train', 'test')): +def DBpedia(root='.data', split=('train', 'test')): """ Defines DBpedia datasets. Create supervised learning dataset: DBpedia @@ -103,7 +103,7 @@ def DBpedia(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -111,10 +111,10 @@ def DBpedia(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.DBpedia() """ - return _setup_datasets("DBpedia", root, data_select) + return _setup_datasets("DBpedia", root, split) -def YelpReviewPolarity(root='.data', data_select=('train', 'test')): +def YelpReviewPolarity(root='.data', split=('train', 'test')): """ Defines YelpReviewPolarity datasets. Create supervised learning dataset: YelpReviewPolarity @@ -123,7 +123,7 @@ def YelpReviewPolarity(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -131,10 +131,10 @@ def YelpReviewPolarity(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.YelpReviewPolarity() """ - return _setup_datasets("YelpReviewPolarity", root, data_select) + return _setup_datasets("YelpReviewPolarity", root, split) -def YelpReviewFull(root='.data', data_select=('train', 'test')): +def YelpReviewFull(root='.data', split=('train', 'test')): """ Defines YelpReviewFull datasets. Create supervised learning dataset: YelpReviewFull @@ -143,7 +143,7 @@ def YelpReviewFull(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -151,10 +151,10 @@ def YelpReviewFull(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.YelpReviewFull() """ - return _setup_datasets("YelpReviewFull", root, data_select) + return _setup_datasets("YelpReviewFull", root, split) -def YahooAnswers(root='.data', data_select=('train', 'test')): +def YahooAnswers(root='.data', split=('train', 'test')): """ Defines YahooAnswers datasets. Create supervised learning dataset: YahooAnswers @@ -163,7 +163,7 @@ def YahooAnswers(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -171,10 +171,10 @@ def YahooAnswers(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.YahooAnswers() """ - return _setup_datasets("YahooAnswers", root, data_select) + return _setup_datasets("YahooAnswers", root, split) -def AmazonReviewPolarity(root='.data', data_select=('train', 'test')): +def AmazonReviewPolarity(root='.data', split=('train', 'test')): """ Defines AmazonReviewPolarity datasets. Create supervised learning dataset: AmazonReviewPolarity @@ -183,7 +183,7 @@ def AmazonReviewPolarity(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -191,10 +191,10 @@ def AmazonReviewPolarity(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewPolarity() """ - return _setup_datasets("AmazonReviewPolarity", root, data_select) + return _setup_datasets("AmazonReviewPolarity", root, split) -def AmazonReviewFull(root='.data', data_select=('train', 'test')): +def AmazonReviewFull(root='.data', split=('train', 'test')): """ Defines AmazonReviewFull datasets. Create supervised learning dataset: AmazonReviewFull @@ -203,7 +203,7 @@ def AmazonReviewFull(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. @@ -211,7 +211,7 @@ def AmazonReviewFull(root='.data', data_select=('train', 'test')): >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewFull() """ - return _setup_datasets("AmazonReviewFull", root, data_select) + return _setup_datasets("AmazonReviewFull", root, split) def generate_imdb_data(key, extracted_files): @@ -224,7 +224,7 @@ def generate_imdb_data(key, extracted_files): yield label, f.read() -def IMDB(root='.data', data_select=('train', 'test')): +def IMDB(root='.data', split=('train', 'test')): """ Defines raw IMDB datasets. Create supervised learning dataset: IMDB @@ -233,20 +233,20 @@ def IMDB(root='.data', data_select=('train', 'test')): Args: root: Directory where the datasets are saved. Default: ".data" - data_select: a string or tuple for the returned datasets. Default: ('train', 'test') + split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. Examples: >>> train, test = torchtext.experimental.datasets.raw.IMDB() """ - data_select = check_default_set(data_select, target_select=('train', 'test')) + split = check_default_set(split, target_select=('train', 'test')) dataset_tar = download_from_url(URLS['IMDB'], root=root, hash_value=MD5['IMDB'], hash_type='md5') extracted_files = extract_archive(dataset_tar) return tuple(RawTextIterableDataset("IMDB", NUM_LINES["IMDB"][item], generate_imdb_data(item, - extracted_files)) for item in data_select) + extracted_files)) for item in split) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py index 25960bead8..d4ca29a028 100644 --- a/torchtext/experimental/datasets/raw/translation.py +++ b/torchtext/experimental/datasets/raw/translation.py @@ -116,8 +116,8 @@ def _construct_filepaths(paths, src_filename, tgt_filename): def _setup_datasets(dataset_name, train_filenames, valid_filenames, test_filenames, - data_select, root): - data_select = check_default_set(data_select, ('train', 'valid', 'test')) + split, root): + split = check_default_set(split, ('train', 'valid', 'test')) if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ and not isinstance(test_filenames, tuple): raise ValueError("All filenames must be tuples") @@ -175,7 +175,7 @@ def _setup_datasets(dataset_name, "Files are not found for data type {}".format(key)) datasets = [] - for key in data_select: + for key in split: src_data_iter = _read_text_iterator(data_filenames[key][0]) tgt_data_iter = _read_text_iterator(data_filenames[key][1]) @@ -192,7 +192,7 @@ def _iter(src_data_iter, tgt_data_iter): def Multi30k(train_filenames=("train.de", "train.en"), valid_filenames=("val.de", "val.en"), test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), - data_select=('train', 'valid', 'test'), root='.data'): + split=('train', 'valid', 'test'), root='.data'): """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple The available dataset include: @@ -253,7 +253,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), Default: ('val.de', 'val.en') test_filenames: the source and target filenames for test. Default: ('test2016.de', 'test2016.en') - data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -264,7 +264,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), >>> from torchtext.experimental.datasets.raw import Multi30k >>> train_dataset, valid_dataset, test_dataset = Multi30k() """ - return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, data_select, root) + return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, split, root) def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), @@ -272,7 +272,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), 'IWSLT16.TED.tst2013.de-en.en'), test_filenames=('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en'), - data_select=('train', 'valid', 'test'), root='.data'): + split=('train', 'valid', 'test'), root='.data'): """ Define translation datasets: IWSLT Separately returns train/valid/test datasets The available datasets include: @@ -419,7 +419,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') test_filenames: the source and target filenames for test. Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') - data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -430,7 +430,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), >>> from torchtext.experimental.datasets.raw import IWSLT >>> train_dataset, valid_dataset, test_dataset = IWSLT() """ - return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, data_select, root) + return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, split, root) def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', @@ -439,7 +439,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', 'newstest2013.tok.bpe.32000.en'), test_filenames=('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en'), - data_select=('train', 'valid', 'test'), root='.data'): + split=('train', 'valid', 'test'), root='.data'): """ Define translation datasets: WMT14 Separately returns train/valid/test datasets The available datasets include: @@ -501,7 +501,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') test_filenames: the source and target filenames for test. Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') - data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -512,7 +512,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', >>> from torchtext.experimental.datasets.raw import WMT14 >>> train_dataset, valid_dataset, test_dataset = WMT14() """ - return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, data_select, root) + return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, split, root) DATASETS = { diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index 26b52ab206..2ff9ee873b 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -26,15 +26,15 @@ def build_vocab(data): return vocabs -def _setup_datasets(dataset_name, root, vocabs, data_select): - data_select = check_default_set(data_select, ('train', 'valid', 'test')) - raw_iter_tuple = raw.DATASETS[dataset_name](root=root, data_select=data_select) +def _setup_datasets(dataset_name, root, vocabs, split): + split = check_default_set(split, ('train', 'valid', 'test')) + raw_iter_tuple = raw.DATASETS[dataset_name](root=root, split=split) raw_data = {} - for name, raw_iter in zip(data_select, raw_iter_tuple): + for name, raw_iter in zip(split, raw_iter_tuple): raw_data[name] = list(raw_iter) if vocabs is None: - if "train" not in data_select: + if "train" not in split: raise TypeError("Must pass a vocab if train is not selected.") logger_.info('Building Vocab based on train data') vocabs = build_vocab(raw_data["train"]) @@ -58,8 +58,8 @@ def _setup_datasets(dataset_name, root, vocabs, data_select): totensor(dtype=torch.long)) for idx in range(len(vocabs)) ] - logger_.info('Building datasets for {}'.format(data_select)) - return tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in data_select) + logger_.info('Building datasets for {}'.format(split)) + return tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in split) class SequenceTaggingDataset(torch.utils.data.Dataset): @@ -108,7 +108,7 @@ def get_vocabs(self): return self.vocabs -def UDPOS(root=".data", vocabs=None, data_select=("train", "valid", "test")): +def UDPOS(root=".data", vocabs=None, split=("train", "valid", "test")): """ Universal Dependencies English Web Treebank Separately returns the training, validation, and test dataset @@ -118,7 +118,7 @@ def UDPOS(root=".data", vocabs=None, data_select=("train", "valid", "test")): vocabs: A list of voabularies for each columns in the dataset. Must be in an instance of List Default: None - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'valid', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -131,10 +131,10 @@ def UDPOS(root=".data", vocabs=None, data_select=("train", "valid", "test")): >>> train_dataset, valid_dataset, test_dataset = UDPOS() """ - return _setup_datasets("UDPOS", root, vocabs, data_select) + return _setup_datasets("UDPOS", root, vocabs, split) -def CoNLL2000Chunking(root=".data", vocabs=None, data_select=("train", "test")): +def CoNLL2000Chunking(root=".data", vocabs=None, split=("train", "test")): """ CoNLL 2000 Chunking Dataset Separately returns the training and test dataset @@ -144,7 +144,7 @@ def CoNLL2000Chunking(root=".data", vocabs=None, data_select=("train", "test")): vocabs: A list of voabularies for each columns in the dataset. Must be in an instance of List Default: None - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -157,7 +157,7 @@ def CoNLL2000Chunking(root=".data", vocabs=None, data_select=("train", "test")): >>> train_dataset, test_dataset = CoNLL2000Chunking() """ - return _setup_datasets("CoNLL2000Chunking", root, vocabs, data_select) + return _setup_datasets("CoNLL2000Chunking", root, vocabs, split) DATASETS = {"UDPOS": UDPOS, "CoNLL2000Chunking": CoNLL2000Chunking} diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index 0646e8d63a..f968cc518b 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -69,18 +69,18 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, data_select): +def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, split): text_transform = [] if tokenizer is None: tokenizer = get_tokenizer("basic_english") text_transform = sequential_transforms(tokenizer, ngrams_func(ngrams)) - data_select = check_default_set(data_select, ('train', 'test')) - raw_datasets = raw.DATASETS[dataset_name](root=root, data_select=data_select) + split = check_default_set(split, ('train', 'test')) + raw_datasets = raw.DATASETS[dataset_name](root=root, split=split) # Materialize raw text iterable dataset - raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(data_select, raw_datasets)} + raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} if vocab is None: - if "train" not in data_select: + if "train" not in split: raise TypeError("Must pass a vocab if train is not selected.") logger_.info('Building Vocab based on train data') vocab = build_vocab(raw_data["train"], text_transform) @@ -92,16 +92,16 @@ def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, data_select): label_transform = sequential_transforms(lambda x: 1 if x == 'pos' else 0, totensor(dtype=torch.long)) else: label_transform = sequential_transforms(totensor(dtype=torch.long)) - logger_.info('Building datasets for {}'.format(data_select)) + logger_.info('Building datasets for {}'.format(split)) return tuple( TextClassificationDataset( raw_data[item], vocab, (label_transform, text_transform) ) - for item in data_select + for item in split ) -def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines AG_NEWS datasets. The labels includes: - 1 : World @@ -123,7 +123,7 @@ def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('tr The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -137,14 +137,14 @@ def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('tr >>> train, test = AG_NEWS(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = AG_NEWS(tokenizer=tokenizer) - >>> train, = AG_NEWS(tokenizer=tokenizer, data_select='train') + >>> train, = AG_NEWS(tokenizer=tokenizer, split='train') """ - return _setup_datasets("AG_NEWS", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("AG_NEWS", root, ngrams, vocab, tokenizer, split) -def SogouNews(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def SogouNews(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines SogouNews datasets. The labels includes: - 1 : Sports @@ -167,7 +167,7 @@ def SogouNews(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=(' The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -181,14 +181,14 @@ def SogouNews(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=(' >>> train, test = SogouNews(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = SogouNews(tokenizer=tokenizer) - >>> train, = SogouNews(tokenizer=tokenizer, data_select='train') + >>> train, = SogouNews(tokenizer=tokenizer, split='train') """ - return _setup_datasets("SogouNews", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("SogouNews", root, ngrams, vocab, tokenizer, split) -def DBpedia(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def DBpedia(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines DBpedia datasets. The labels includes: - 1 : Company @@ -220,7 +220,7 @@ def DBpedia(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('tr The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -234,14 +234,14 @@ def DBpedia(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('tr >>> train, test = DBpedia(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = DBpedia(tokenizer=tokenizer) - >>> train, = DBpedia(tokenizer=tokenizer, data_select='train') + >>> train, = DBpedia(tokenizer=tokenizer, split='train') """ - return _setup_datasets("DBpedia", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("DBpedia", root, ngrams, vocab, tokenizer, split) -def YelpReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def YelpReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines YelpReviewPolarity datasets. The labels includes: - 1 : Negative polarity. @@ -261,7 +261,7 @@ def YelpReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, data_ The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -275,14 +275,14 @@ def YelpReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, data_ >>> train, test = YelpReviewPolarity(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = YelpReviewPolarity(tokenizer=tokenizer) - >>> train, = YelpReviewPolarity(tokenizer=tokenizer, data_select='train') + >>> train, = YelpReviewPolarity(tokenizer=tokenizer, split='train') """ - return _setup_datasets("YelpReviewPolarity", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("YelpReviewPolarity", root, ngrams, vocab, tokenizer, split) -def YelpReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def YelpReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines YelpReviewFull datasets. The labels includes: 1 - 5 : rating classes (5 is highly recommended). @@ -301,7 +301,7 @@ def YelpReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_sele The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -315,14 +315,14 @@ def YelpReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_sele >>> train, test = YelpReviewFull(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = YelpReviewFull(tokenizer=tokenizer) - >>> train, = YelpReviewFull(tokenizer=tokenizer, data_select='train') + >>> train, = YelpReviewFull(tokenizer=tokenizer, split='train') """ - return _setup_datasets("YelpReviewFull", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("YelpReviewFull", root, ngrams, vocab, tokenizer, split) -def YahooAnswers(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def YahooAnswers(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines YahooAnswers datasets. The labels includes: - 1 : Society & Culture @@ -350,7 +350,7 @@ def YahooAnswers(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -364,14 +364,14 @@ def YahooAnswers(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select >>> train, test = YahooAnswers(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = YahooAnswers(tokenizer=tokenizer) - >>> train, = YahooAnswers(tokenizer=tokenizer, data_select='train') + >>> train, = YahooAnswers(tokenizer=tokenizer, split='train') """ - return _setup_datasets("YahooAnswers", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("YahooAnswers", root, ngrams, vocab, tokenizer, split) -def AmazonReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def AmazonReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines AmazonReviewPolarity datasets. The labels includes: - 1 : Negative polarity @@ -391,7 +391,7 @@ def AmazonReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, dat The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -405,14 +405,14 @@ def AmazonReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, dat >>> train, test = AmazonReviewPolarity(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = AmazonReviewPolarity(tokenizer=tokenizer) - >>> train, = AmazonReviewPolarity(tokenizer=tokenizer, data_select='train') + >>> train, = AmazonReviewPolarity(tokenizer=tokenizer, split='train') """ - return _setup_datasets("AmazonReviewPolarity", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("AmazonReviewPolarity", root, ngrams, vocab, tokenizer, split) -def AmazonReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def AmazonReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines AmazonReviewFull datasets. The labels includes: 1 - 5 : rating classes (5 is highly recommended) @@ -431,7 +431,7 @@ def AmazonReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_se The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -445,14 +445,14 @@ def AmazonReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, data_se >>> train, test = AmazonReviewFull(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = AmazonReviewFull(tokenizer=tokenizer) - >>> train, = AmazonReviewFull(tokenizer=tokenizer, data_select='train') + >>> train, = AmazonReviewFull(tokenizer=tokenizer, split='train') """ - return _setup_datasets("AmazonReviewFull", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("AmazonReviewFull", root, ngrams, vocab, tokenizer, split) -def IMDB(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train', 'test')): +def IMDB(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): """ Defines IMDB datasets. The labels includes: - 0 : Negative @@ -473,7 +473,7 @@ def IMDB(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train The default one is basic_english tokenizer in fastText. spacy tokenizer is supported as well. A custom tokenizer is callable function with input of a string and output of a token list. - data_select: a string or tuple for the returned datasets + split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, all the three datasets (train, test, valid) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -487,11 +487,11 @@ def IMDB(root='.data', ngrams=1, vocab=None, tokenizer=None, data_select=('train >>> train, test = IMDB(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = IMDB(tokenizer=tokenizer) - >>> train, = IMDB(tokenizer=tokenizer, data_select='train') + >>> train, = IMDB(tokenizer=tokenizer, split='train') """ - return _setup_datasets("IMDB", root, ngrams, vocab, tokenizer, data_select) + return _setup_datasets("IMDB", root, ngrams, vocab, tokenizer, split) DATASETS = { diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index c38d17401d..1429b509ef 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -18,8 +18,8 @@ def apply_transforms(data): def _setup_datasets(dataset_name, train_filenames, valid_filenames, test_filenames, - data_select, root, vocab, tokenizer): - data_select = check_default_set(data_select, ('train', 'valid', 'test')) + split, root, vocab, tokenizer): + split = check_default_set(split, ('train', 'valid', 'test')) src_vocab, tgt_vocab = vocab if tokenizer is None: src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') @@ -37,13 +37,13 @@ def _setup_datasets(dataset_name, raw_datasets = raw.DATASETS[dataset_name](train_filenames=train_filenames, valid_filenames=valid_filenames, test_filenames=test_filenames, - data_select=data_select, root=root) - raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(data_select, raw_datasets)} + split=split, root=root) + raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} src_text_vocab_transform = sequential_transforms(src_tokenizer) tgt_text_vocab_transform = sequential_transforms(tgt_tokenizer) if src_vocab is None: - if 'train' not in data_select: + if 'train' not in split: raise TypeError("Must pass a vocab if train is not selected.") logger_.info('Building src Vocab based on train data') src_vocab = build_vocab(raw_data["train"], @@ -55,7 +55,7 @@ def _setup_datasets(dataset_name, logger_.info('src Vocab has %d entries', len(src_vocab)) if tgt_vocab is None: - if 'train' not in data_select: + if 'train' not in split: raise TypeError("Must pass a vocab if train is not selected.") logger_.info('Building tgt Vocab based on train data') tgt_vocab = build_vocab(raw_data["train"], @@ -66,9 +66,9 @@ def _setup_datasets(dataset_name, raise TypeError("Passed tgt vocabulary is not of type Vocab") logger_.info('tgt Vocab has %d entries', len(tgt_vocab)) - logger_.info('Building datasets for {}'.format(data_select)) + logger_.info('Building datasets for {}'.format(split)) datasets = [] - for key in data_select: + for key in split: src_text_transform = sequential_transforms(src_text_vocab_transform, vocab_func(src_vocab), totensor(dtype=torch.long)) @@ -135,7 +135,7 @@ def get_vocab(self): def Multi30k(train_filenames=("train.de", "train.en"), valid_filenames=("val.de", "val.en"), test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), - data_select=('train', 'valid', 'test'), + split=('train', 'valid', 'test'), root='.data', vocab=(None, None), tokenizer=None): @@ -150,7 +150,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), Default: ('val.de', 'val.en') test_filenames: the source and target filenames for test. Default: ('test2016.de', 'test2016.en') - data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -228,7 +228,7 @@ def Multi30k(train_filenames=("train.de", "train.en"), """ return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, - data_select, root, vocab, tokenizer) + split, root, vocab, tokenizer) def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), @@ -236,7 +236,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), 'IWSLT16.TED.tst2013.de-en.en'), test_filenames=('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en'), - data_select=('train', 'valid', 'test'), + split=('train', 'valid', 'test'), root='.data', vocab=(None, None), tokenizer=None): @@ -252,7 +252,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') test_filenames: the source and target filenames for test. Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') - data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -417,7 +417,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), """ return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, - data_select, root, vocab, tokenizer) + split, root, vocab, tokenizer) def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', @@ -426,7 +426,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', 'newstest2013.tok.bpe.32000.en'), test_filenames=('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en'), - data_select=('train', 'valid', 'test'), + split=('train', 'valid', 'test'), root='.data', vocab=(None, None), tokenizer=None): @@ -493,7 +493,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') test_filenames: the source and target filenames for test. Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') - data_select: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. If 'train' is not in the tuple or string, a vocab @@ -520,7 +520,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', """ return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, - data_select, root, vocab, tokenizer) + split, root, vocab, tokenizer) DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} From ce0cb155c0839e1d97cfae0a00bf86a5b6afd51f Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 42/68] Add offset arg in the raw text dataset (#1145) Reviewed By: zhangguanheng66 Differential Revision: D26368996 fbshipit-source-id: 52741015139c302b7b0ddf8c8f50ab45a609fd2f --- test/data/test_builtin_datasets.py | 15 ++++-- torchtext/experimental/datasets/raw/common.py | 22 ++------- .../datasets/raw/language_modeling.py | 24 +++++---- .../datasets/raw/question_answer.py | 14 +++--- .../datasets/raw/sequence_tagging.py | 14 +++--- .../datasets/raw/text_classification.py | 49 +++++++++++-------- .../experimental/datasets/raw/translation.py | 19 ++++--- 7 files changed, 85 insertions(+), 72 deletions(-) diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index d7a02995d7..95f2894634 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -138,11 +138,18 @@ def test_text_classification(self): self._helper_test_func(len(test_iter), 7600, next(iter(test_iter))[1][:25], 'Fears for T N pension aft') del train_iter, test_iter - def test_num_lines_of_setup_iter_dataset(self): - train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() - train_iter.setup_iter(start=10, num_lines=100) + def test_num_lines_of_dataset(self): + train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS(offset=10) _data = [item for item in train_iter] - self.assertEqual(len(_data), 100) + self.assertEqual(len(_data), 119990) + + def test_offset_dataset(self): + train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS(split=('train', 'test'), + offset=10) + container = [text[:20] for idx, (label, text) in enumerate(train_iter) if idx < 5] + self.assertEqual(container, ['Oil and Economy Clou', 'No Need for OPEC to ', + 'Non-OPEC Nations Sho', 'Google IPO Auction O', + 'Dollar Falls Broadly']) def test_imdb(self): from torchtext.experimental.datasets import IMDB diff --git a/torchtext/experimental/datasets/raw/common.py b/torchtext/experimental/datasets/raw/common.py index 06415830c3..1267b703ff 100644 --- a/torchtext/experimental/datasets/raw/common.py +++ b/torchtext/experimental/datasets/raw/common.py @@ -14,29 +14,17 @@ class RawTextIterableDataset(torch.utils.data.IterableDataset): """Defines an abstraction for raw text iterable datasets. """ - def __init__(self, name, full_num_lines, iterator): + def __init__(self, name, full_num_lines, iterator, offset=0): """Initiate text-classification dataset. """ super(RawTextIterableDataset, self).__init__() self.name = name self.full_num_lines = full_num_lines self._iterator = iterator - self.has_setup = False - self.start = 0 - self.num_lines = None - - def setup_iter(self, start=0, num_lines=None): - self.start = start - self.num_lines = num_lines - if num_lines and self.start + self.num_lines > self.full_num_lines: - raise ValueError("Requested start {} and num_lines {} exceeds available number of lines {}".format( - self.start, self.num_lines, self.full_num_lines)) - self.has_setup = True + self.start = offset + self.num_lines = full_num_lines - offset def __iter__(self): - if not self.has_setup: - self.setup_iter() - for i, item in enumerate(self._iterator): if i < self.start: continue @@ -45,9 +33,7 @@ def __iter__(self): yield item def __len__(self): - if self.has_setup: - return self.num_lines - return self.full_num_lines + return self.num_lines def get_iterator(self): return self._iterator diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py index 9edb6e735c..c9bf90f216 100644 --- a/torchtext/experimental/datasets/raw/language_modeling.py +++ b/torchtext/experimental/datasets/raw/language_modeling.py @@ -17,7 +17,7 @@ } -def _setup_datasets(dataset_name, root, split, year, language): +def _setup_datasets(dataset_name, root, split, year, language, offset): split = check_default_set(split, ('train', 'test', 'valid')) if isinstance(split, str): split = [split] @@ -55,10 +55,10 @@ def _setup_datasets(dataset_name, root, split, year, language): data[item] = iter(io.open(_path[item], encoding="utf8")) return tuple(RawTextIterableDataset(dataset_name, - NUM_LINES[dataset_name][item], data[item]) for item in split) + NUM_LINES[dataset_name][item], data[item], offset=offset) for item in split) -def WikiText2(root='.data', split=('train', 'valid', 'test')): +def WikiText2(root='.data', split=('train', 'valid', 'test'), offset=0): """ Defines WikiText2 datasets. Create language modeling dataset: WikiText2 @@ -72,6 +72,7 @@ def WikiText2(root='.data', split=('train', 'valid', 'test')): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.raw.datasets import WikiText2 @@ -80,10 +81,10 @@ def WikiText2(root='.data', split=('train', 'valid', 'test')): """ - return _setup_datasets("WikiText2", root, split, None, None) + return _setup_datasets("WikiText2", root, split, None, None, offset) -def WikiText103(root='.data', split=('train', 'valid', 'test')): +def WikiText103(root='.data', split=('train', 'valid', 'test'), offset=0): """ Defines WikiText103 datasets. Create language modeling dataset: WikiText103 @@ -96,6 +97,7 @@ def WikiText103(root='.data', split=('train', 'valid', 'test')): could also choose any one or two of them, for example ('train', 'test'). If 'train' is not in the tuple, an vocab object should be provided which will be used to process valid and/or test data. + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.datasets.raw import WikiText103 @@ -103,10 +105,10 @@ def WikiText103(root='.data', split=('train', 'valid', 'test')): >>> valid_dataset, = WikiText103(split='valid') """ - return _setup_datasets("WikiText103", root, split, None, None) + return _setup_datasets("WikiText103", root, split, None, None, offset) -def PennTreebank(root='.data', split=('train', 'valid', 'test')): +def PennTreebank(root='.data', split=('train', 'valid', 'test'), offset=0): """ Defines PennTreebank datasets. Create language modeling dataset: PennTreebank @@ -121,6 +123,7 @@ def PennTreebank(root='.data', split=('train', 'valid', 'test')): just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.datasets.raw import PennTreebank @@ -129,10 +132,10 @@ def PennTreebank(root='.data', split=('train', 'valid', 'test')): """ - return _setup_datasets("PennTreebank", root, split, None, None) + return _setup_datasets("PennTreebank", root, split, None, None, offset) -def WMTNewsCrawl(root='.data', split=('train'), year=2010, language='en'): +def WMTNewsCrawl(root='.data', split=('train'), year=2010, language='en', offset=0): """ Defines WMT News Crawl. Create language modeling dataset: WMTNewsCrawl @@ -143,11 +146,12 @@ def WMTNewsCrawl(root='.data', split=('train'), year=2010, language='en'): (Default: 'train') year: the year of the dataset (Default: 2010) language: the language of the dataset (Default: 'en') + offset: the number of the starting line. Default: 0 Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. """ - return _setup_datasets("WMTNewsCrawl", root, split, year, language) + return _setup_datasets("WMTNewsCrawl", root, split, year, language, offset) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py index 3bc4d83461..937e58af24 100644 --- a/torchtext/experimental/datasets/raw/question_answer.py +++ b/torchtext/experimental/datasets/raw/question_answer.py @@ -29,15 +29,15 @@ def _create_data_from_json(data_path): yield (_context, _question, _answers, _answer_start) -def _setup_datasets(dataset_name, root, split): +def _setup_datasets(dataset_name, root, split, offset): split = check_default_set(split, ('train', 'dev')) extracted_files = {key: download_from_url(URLS[dataset_name][key], root=root, hash_value=MD5[dataset_name][key], hash_type='md5') for key in split} return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_json(extracted_files[item])) for item in split) + _create_data_from_json(extracted_files[item]), offset=offset) for item in split) -def SQuAD1(root='.data', split=('train', 'dev')): +def SQuAD1(root='.data', split=('train', 'dev'), offset=0): """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD1.0. The iterator yields a tuple of (raw context, raw question, a list of raw answer, a list of answer positions in the raw context). @@ -51,6 +51,7 @@ def SQuAD1(root='.data', split=('train', 'dev')): split: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, for example ('train', 'dev') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train_dataset, dev_dataset = torchtext.experimental.datasets.raw.SQuAD1() @@ -58,10 +59,10 @@ def SQuAD1(root='.data', split=('train', 'dev')): >>> print(idx, (context, question, answer, ans_pos)) """ - return _setup_datasets("SQuAD1", root, split) + return _setup_datasets("SQuAD1", root, split, offset) -def SQuAD2(root='.data', split=('train', 'dev')): +def SQuAD2(root='.data', split=('train', 'dev'), offset=0): """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD2.0. The iterator yields a tuple of (raw context, raw question, a list of raw answer, a list of answer positions in the raw context). @@ -75,6 +76,7 @@ def SQuAD2(root='.data', split=('train', 'dev')): split: a string or tuple for the returned datasets (Default: ('train', 'dev')) By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, for example ('train', 'dev') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train_dataset, dev_dataset = torchtext.experimental.datasets.raw.SQuAD2() @@ -82,7 +84,7 @@ def SQuAD2(root='.data', split=('train', 'dev')): >>> print(idx, (context, question, answer, ans_pos)) """ - return _setup_datasets("SQuAD2", root, split) + return _setup_datasets("SQuAD2", root, split, offset) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/sequence_tagging.py b/torchtext/experimental/datasets/raw/sequence_tagging.py index b3f221a385..2c59946d69 100644 --- a/torchtext/experimental/datasets/raw/sequence_tagging.py +++ b/torchtext/experimental/datasets/raw/sequence_tagging.py @@ -39,7 +39,7 @@ def _construct_filepath(paths, file_suffix): return None -def _setup_datasets(dataset_name, separator, root, split): +def _setup_datasets(dataset_name, separator, root, split, offset): split = check_default_set(split, target_select=('train', 'valid', 'test')) extracted_files = [] if isinstance(URLS[dataset_name], dict): @@ -60,11 +60,11 @@ def _setup_datasets(dataset_name, separator, root, split): "test": _construct_filepath(extracted_files, "test.txt") } return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_iob(data_filenames[item], separator)) + _create_data_from_iob(data_filenames[item], separator), offset=offset) if data_filenames[item] is not None else None for item in split) -def UDPOS(root=".data", split=('train', 'valid', 'test')): +def UDPOS(root=".data", split=('train', 'valid', 'test'), offset=0): """ Universal Dependencies English Web Treebank Separately returns the training and test dataset @@ -75,15 +75,16 @@ def UDPOS(root=".data", split=('train', 'valid', 'test')): By default, all the datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'valid', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.datasets.raw import UDPOS >>> train_dataset, valid_dataset, test_dataset = UDPOS() """ - return _setup_datasets("UDPOS", "\t", root, split) + return _setup_datasets("UDPOS", "\t", root, split, offset) -def CoNLL2000Chunking(root=".data", split=('train', 'test')): +def CoNLL2000Chunking(root=".data", split=('train', 'test'), offset=0): """ CoNLL 2000 Chunking Dataset Separately returns the training and test dataset @@ -93,12 +94,13 @@ def CoNLL2000Chunking(root=".data", split=('train', 'test')): split: a string or tuple for the returned datasets (Default: ('train', 'test')) By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.datasets.raw import CoNLL2000Chunking >>> train_dataset, test_dataset = CoNLL2000Chunking() """ - return _setup_datasets("CoNLL2000Chunking", " ", root, split) + return _setup_datasets("CoNLL2000Chunking", " ", root, split, offset) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py index 4a1706714c..a4fa4dfa19 100644 --- a/torchtext/experimental/datasets/raw/text_classification.py +++ b/torchtext/experimental/datasets/raw/text_classification.py @@ -33,7 +33,7 @@ def _create_data_from_csv(data_path): yield int(row[0]), ' '.join(row[1:]) -def _setup_datasets(dataset_name, root, split): +def _setup_datasets(dataset_name, root, split, offset): split = check_default_set(split, target_select=('train', 'test')) if dataset_name == 'AG_NEWS': extracted_files = [download_from_url(URLS[dataset_name][item], root=root, @@ -51,10 +51,10 @@ def _setup_datasets(dataset_name, root, split): if fname.endswith('test.csv'): cvs_path['test'] = fname return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_csv(cvs_path[item])) for item in split) + _create_data_from_csv(cvs_path[item]), offset=offset) for item in split) -def AG_NEWS(root='.data', split=('train', 'test')): +def AG_NEWS(root='.data', split=('train', 'test'), offset=0): """ Defines AG_NEWS datasets. Create supervised learning dataset: AG_NEWS @@ -66,15 +66,16 @@ def AG_NEWS(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.AG_NEWS() """ - return _setup_datasets("AG_NEWS", root, split) + return _setup_datasets("AG_NEWS", root, split, offset) -def SogouNews(root='.data', split=('train', 'test')): +def SogouNews(root='.data', split=('train', 'test'), offset=0): """ Defines SogouNews datasets. Create supervised learning dataset: SogouNews @@ -86,15 +87,16 @@ def SogouNews(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.SogouNews() """ - return _setup_datasets("SogouNews", root, split) + return _setup_datasets("SogouNews", root, split, offset) -def DBpedia(root='.data', split=('train', 'test')): +def DBpedia(root='.data', split=('train', 'test'), offset=0): """ Defines DBpedia datasets. Create supervised learning dataset: DBpedia @@ -106,15 +108,16 @@ def DBpedia(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.DBpedia() """ - return _setup_datasets("DBpedia", root, split) + return _setup_datasets("DBpedia", root, split, offset) -def YelpReviewPolarity(root='.data', split=('train', 'test')): +def YelpReviewPolarity(root='.data', split=('train', 'test'), offset=0): """ Defines YelpReviewPolarity datasets. Create supervised learning dataset: YelpReviewPolarity @@ -126,15 +129,16 @@ def YelpReviewPolarity(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.YelpReviewPolarity() """ - return _setup_datasets("YelpReviewPolarity", root, split) + return _setup_datasets("YelpReviewPolarity", root, split, offset) -def YelpReviewFull(root='.data', split=('train', 'test')): +def YelpReviewFull(root='.data', split=('train', 'test'), offset=0): """ Defines YelpReviewFull datasets. Create supervised learning dataset: YelpReviewFull @@ -146,15 +150,16 @@ def YelpReviewFull(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.YelpReviewFull() """ - return _setup_datasets("YelpReviewFull", root, split) + return _setup_datasets("YelpReviewFull", root, split, offset) -def YahooAnswers(root='.data', split=('train', 'test')): +def YahooAnswers(root='.data', split=('train', 'test'), offset=0): """ Defines YahooAnswers datasets. Create supervised learning dataset: YahooAnswers @@ -166,15 +171,16 @@ def YahooAnswers(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.YahooAnswers() """ - return _setup_datasets("YahooAnswers", root, split) + return _setup_datasets("YahooAnswers", root, split, offset) -def AmazonReviewPolarity(root='.data', split=('train', 'test')): +def AmazonReviewPolarity(root='.data', split=('train', 'test'), offset=0): """ Defines AmazonReviewPolarity datasets. Create supervised learning dataset: AmazonReviewPolarity @@ -186,15 +192,16 @@ def AmazonReviewPolarity(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewPolarity() """ - return _setup_datasets("AmazonReviewPolarity", root, split) + return _setup_datasets("AmazonReviewPolarity", root, split, offset) -def AmazonReviewFull(root='.data', split=('train', 'test')): +def AmazonReviewFull(root='.data', split=('train', 'test'), offset=0): """ Defines AmazonReviewFull datasets. Create supervised learning dataset: AmazonReviewFull @@ -206,12 +213,13 @@ def AmazonReviewFull(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewFull() """ - return _setup_datasets("AmazonReviewFull", root, split) + return _setup_datasets("AmazonReviewFull", root, split, offset) def generate_imdb_data(key, extracted_files): @@ -224,7 +232,7 @@ def generate_imdb_data(key, extracted_files): yield label, f.read() -def IMDB(root='.data', split=('train', 'test')): +def IMDB(root='.data', split=('train', 'test'), offset=0): """ Defines raw IMDB datasets. Create supervised learning dataset: IMDB @@ -236,6 +244,7 @@ def IMDB(root='.data', split=('train', 'test')): split: a string or tuple for the returned datasets. Default: ('train', 'test') By default, both datasets (train, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or just a string 'train'. + offset: the number of the starting line. Default: 0 Examples: >>> train, test = torchtext.experimental.datasets.raw.IMDB() @@ -246,7 +255,7 @@ def IMDB(root='.data', split=('train', 'test')): extracted_files = extract_archive(dataset_tar) return tuple(RawTextIterableDataset("IMDB", NUM_LINES["IMDB"][item], generate_imdb_data(item, - extracted_files)) for item in split) + extracted_files), offset=offset) for item in split) DATASETS = { diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py index d4ca29a028..9cc10706c3 100644 --- a/torchtext/experimental/datasets/raw/translation.py +++ b/torchtext/experimental/datasets/raw/translation.py @@ -116,7 +116,7 @@ def _construct_filepaths(paths, src_filename, tgt_filename): def _setup_datasets(dataset_name, train_filenames, valid_filenames, test_filenames, - split, root): + split, root, offset): split = check_default_set(split, ('train', 'valid', 'test')) if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ and not isinstance(test_filenames, tuple): @@ -184,7 +184,7 @@ def _iter(src_data_iter, tgt_data_iter): yield item datasets.append( - RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][key], _iter(src_data_iter, tgt_data_iter))) + RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][key], _iter(src_data_iter, tgt_data_iter), offset=offset)) return tuple(datasets) @@ -192,7 +192,7 @@ def _iter(src_data_iter, tgt_data_iter): def Multi30k(train_filenames=("train.de", "train.en"), valid_filenames=("val.de", "val.en"), test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), - split=('train', 'valid', 'test'), root='.data'): + split=('train', 'valid', 'test'), root='.data', offset=0): """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple The available dataset include: @@ -259,12 +259,13 @@ def Multi30k(train_filenames=("train.de", "train.en"), just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.datasets.raw import Multi30k >>> train_dataset, valid_dataset, test_dataset = Multi30k() """ - return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, split, root) + return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, split, root, offset) def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), @@ -272,7 +273,7 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), 'IWSLT16.TED.tst2013.de-en.en'), test_filenames=('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en'), - split=('train', 'valid', 'test'), root='.data'): + split=('train', 'valid', 'test'), root='.data', offset=0): """ Define translation datasets: IWSLT Separately returns train/valid/test datasets The available datasets include: @@ -425,12 +426,13 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.datasets.raw import IWSLT >>> train_dataset, valid_dataset, test_dataset = IWSLT() """ - return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, split, root) + return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, split, root, offset) def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', @@ -439,7 +441,7 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', 'newstest2013.tok.bpe.32000.en'), test_filenames=('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en'), - split=('train', 'valid', 'test'), root='.data'): + split=('train', 'valid', 'test'), root='.data', offset=0): """ Define translation datasets: WMT14 Separately returns train/valid/test datasets The available datasets include: @@ -507,12 +509,13 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', just a string 'train'. If 'train' is not in the tuple or string, a vocab object should be provided which will be used to process valid and/or test data. root: Directory where the datasets are saved. Default: ".data" + offset: the number of the starting line. Default: 0 Examples: >>> from torchtext.experimental.datasets.raw import WMT14 >>> train_dataset, valid_dataset, test_dataset = WMT14() """ - return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, split, root) + return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, split, root, offset) DATASETS = { From 125684c36ea75810eb435dbaf0e82702e44176d4 Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 43/68] switch to_ivalue to __prepare_scriptable__ (#1080) Reviewed By: zhangguanheng66 Differential Revision: D26368995 fbshipit-source-id: 0352c04e422c835350bd42df35d4054d543fee36 --- .../benchmark_basic_english_normalize.py | 2 +- benchmark/benchmark_experimental_vectors.py | 2 +- benchmark/benchmark_experimental_vocab.py | 6 +-- benchmark/benchmark_pytext_vocab.py | 2 +- examples/data_pipeline/pipelines.py | 21 ++++----- examples/data_pipeline/transforms.py | 14 ------ test/data/test_functional.py | 20 +++++--- test/experimental/test_transforms.py | 10 ++-- test/experimental/test_vectors.py | 12 +++-- test/experimental/test_vocab.py | 12 +++-- test/experimental/test_with_asset.py | 10 ++-- torchtext/experimental/transforms.py | 46 ++++--------------- torchtext/experimental/vectors.py | 2 +- torchtext/experimental/vocab.py | 4 +- 14 files changed, 70 insertions(+), 93 deletions(-) diff --git a/benchmark/benchmark_basic_english_normalize.py b/benchmark/benchmark_basic_english_normalize.py index d719e748a5..fa395b1299 100644 --- a/benchmark/benchmark_basic_english_normalize.py +++ b/benchmark/benchmark_basic_english_normalize.py @@ -15,7 +15,7 @@ def _run_benchmark_lookup(train, tokenizer): existing_basic_english_tokenizer = get_tokenizer("basic_english") experimental_basic_english_normalize = basic_english_normalize() - experimental_jit_basic_english_normalize = torch.jit.script(experimental_basic_english_normalize.to_ivalue()) + experimental_jit_basic_english_normalize = torch.jit.script(experimental_basic_english_normalize) # existing eager lookup train, _ = AG_NEWS() diff --git a/benchmark/benchmark_experimental_vectors.py b/benchmark/benchmark_experimental_vectors.py index 42fc008370..f644c14e62 100644 --- a/benchmark/benchmark_experimental_vectors.py +++ b/benchmark/benchmark_experimental_vectors.py @@ -42,7 +42,7 @@ def _run_benchmark_lookup(tokens, vector): # experimental FastText jit lookup print("FastText Experimental - Jit Mode") - jit_fast_text_experimental = torch.jit.script(fast_text_experimental.to_ivalue()) + jit_fast_text_experimental = torch.jit.script(fast_text_experimental) _run_benchmark_lookup(tokens, jit_fast_text_experimental) diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 4183c27f6a..f815bf3648 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -67,7 +67,7 @@ def benchmark_experimental_vocab_construction(vocab_file_path, is_raw_text=True, print("Loading from raw text file with basic_english_normalize tokenizer") for _ in range(num_iters): tokenizer = basic_english_normalize() - jited_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + jited_tokenizer = torch.jit.script(tokenizer) build_vocab_from_text_file(f, jited_tokenizer, num_cpus=1) print("Construction time:", time.monotonic() - t0) else: @@ -140,7 +140,7 @@ def token_iterator(file_path): t0 = time.monotonic() v_experimental = VocabExperimental(ordered_dict) print("Construction time:", time.monotonic() - t0) - jit_v_experimental = torch.jit.script(v_experimental.to_ivalue()) + jit_v_experimental = torch.jit.script(v_experimental) # existing Vocab eager lookup print("Vocab - Eager Mode") @@ -154,7 +154,7 @@ def token_iterator(file_path): _run_benchmark_lookup([tokens], v_experimental) _run_benchmark_lookup(tokens_lists, v_experimental) - jit_v_experimental = torch.jit.script(v_experimental.to_ivalue()) + jit_v_experimental = torch.jit.script(v_experimental) # experimental Vocab jit lookup print("Vocab Experimental - Jit Mode") _run_benchmark_lookup(tokens, jit_v_experimental) diff --git a/benchmark/benchmark_pytext_vocab.py b/benchmark/benchmark_pytext_vocab.py index 2e686dd5dc..6dbe200fd4 100644 --- a/benchmark/benchmark_pytext_vocab.py +++ b/benchmark/benchmark_pytext_vocab.py @@ -150,7 +150,7 @@ def benchmark_experimental_vocab(): t0 = time.monotonic() experimental_script_vocab = ExperimentalScriptVocabulary(ordered_dict, unk_token="") print("Construction time:", time.monotonic() - t0) - jit_experimental_script_vocab = torch.jit.script(experimental_script_vocab.to_ivalue()) + jit_experimental_script_vocab = torch.jit.script(experimental_script_vocab) # pytext Vocab eager lookup print("Pytext Vocabulary - Eager Mode") diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index 4e2db98021..d8c6f71f7d 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -32,11 +32,10 @@ def build_sp_pipeline(spm_file): vocab = PretrainedSPVocab(load_sp_model(spm_file)) # Insert token in vocab to match a pretrained vocab - vocab.insert_token('', 1) pipeline = TextSequentialTransforms(tokenizer, vocab) - jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + jit_pipeline = torch.jit.script(pipeline) print('jit sentencepiece pipeline success!') - return pipeline, pipeline.to_ivalue(), jit_pipeline + return pipeline, pipeline, jit_pipeline def build_legacy_torchtext_vocab_pipeline(vocab_file): @@ -59,9 +58,9 @@ def build_experimental_torchtext_pipeline(hf_vocab_file): with open(hf_vocab_file, 'r') as f: vocab = load_vocab_from_file(f) pipeline = TextSequentialTransforms(tokenizer, vocab) - jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + jit_pipeline = torch.jit.script(pipeline) print('jit experimental torchtext pipeline success!') - return pipeline, pipeline.to_ivalue(), jit_pipeline + return pipeline, pipeline, jit_pipeline def build_legacy_batch_torchtext_vocab_pipeline(vocab_file): @@ -104,9 +103,9 @@ def build_legacy_pytext_script_vocab_pipeline(vocab_file): vocab_list.insert(0, "") pipeline = TextSequentialTransforms(tokenizer, PyTextScriptVocabTransform(ScriptVocabulary(vocab_list))) - jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + jit_pipeline = torch.jit.script(pipeline) print('jit legacy PyText pipeline success!') - return pipeline, pipeline.to_ivalue(), jit_pipeline + return pipeline, pipeline, jit_pipeline def build_experimental_pytext_script_pipeline(vocab_file): @@ -125,9 +124,9 @@ def build_experimental_pytext_script_pipeline(vocab_file): # Insert token in vocab to match a pretrained vocab pipeline = TextSequentialTransforms(tokenizer, PyTextScriptVocabTransform(script_vocab(ordered_dict))) - jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + jit_pipeline = torch.jit.script(pipeline) print('jit legacy PyText pipeline success!') - return pipeline, pipeline.to_ivalue(), jit_pipeline + return pipeline, pipeline, jit_pipeline def build_legacy_fasttext_vector_pipeline(): @@ -143,10 +142,10 @@ def build_experimental_fasttext_vector_pipeline(): vector = FastTextExperimental() pipeline = TextSequentialTransforms(tokenizer, vector) - jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + jit_pipeline = torch.jit.script(pipeline) print('jit legacy fasttext pipeline success!') - return pipeline, pipeline.to_ivalue(), jit_pipeline + return pipeline, pipeline, jit_pipeline def run_benchmark_lookup(text_classification_dataset, pipeline): diff --git a/examples/data_pipeline/transforms.py b/examples/data_pipeline/transforms.py index 7a6d9214e5..2bcb8ff34c 100644 --- a/examples/data_pipeline/transforms.py +++ b/examples/data_pipeline/transforms.py @@ -24,14 +24,6 @@ def forward(self, tokens: List[str]) -> List[int]: def insert_token(self, token: str, index: int) -> None: self.vocab.insert_token(token, index) - def to_ivalue(self): - if hasattr(self.vocab, 'to_ivalue'): - sp_model = self.sp_model - new_module = PretrainedSPVocab(sp_model) - new_module.vocab = self.vocab.to_ivalue() - return new_module - return self - class PyTextVocabTransform(nn.Module): r"""PyTextVocabTransform transform @@ -57,12 +49,6 @@ def __init__(self, vocab): def forward(self, tokens: List[str]) -> List[int]: return self.vocab.lookup_indices_1d(tokens) - def to_ivalue(self): - if hasattr(self.vocab, 'to_ivalue'): - vocab = self.vocab.to_ivalue() - return PyTextScriptVocabTransform(vocab) - return self - class ToLongTensor(nn.Module): r"""Convert a list of integers to long tensor diff --git a/test/data/test_functional.py b/test/data/test_functional.py index 509a0e9fc3..199c022786 100644 --- a/test/data/test_functional.py +++ b/test/data/test_functional.py @@ -94,14 +94,16 @@ def test_BasicEnglishNormalize(self): basic_eng_norm = basic_english_normalize() experimental_eager_tokens = basic_eng_norm(test_sample) - jit_basic_eng_norm = torch.jit.script(basic_eng_norm.to_ivalue()) + jit_basic_eng_norm = torch.jit.script(basic_eng_norm) experimental_jit_tokens = jit_basic_eng_norm(test_sample) basic_english_tokenizer = data.get_tokenizer("basic_english") eager_tokens = basic_english_tokenizer(test_sample) assert not basic_eng_norm.is_jitable - assert basic_eng_norm.to_ivalue().is_jitable + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + assert basic_eng_norm.__prepare_scriptable__().is_jitable self.assertEqual(experimental_jit_tokens, ref_results) self.assertEqual(eager_tokens, ref_results) @@ -121,7 +123,9 @@ def test_basicEnglishNormalize_load_and_save(self): with self.subTest('torchscript'): save_path = os.path.join(self.test_dir, 'ben_torchscrip.pt') - ben = basic_english_normalize().to_ivalue() + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + ben = basic_english_normalize().__prepare_scriptable__() torch.save(ben, save_path) loaded_ben = torch.load(save_path) self.assertEqual(loaded_ben(test_sample), ref_results) @@ -149,11 +153,13 @@ def test_RegexTokenizer(self): r_tokenizer = regex_tokenizer(patterns_list) eager_tokens = r_tokenizer(test_sample) - jit_r_tokenizer = torch.jit.script(r_tokenizer.to_ivalue()) + jit_r_tokenizer = torch.jit.script(r_tokenizer) jit_tokens = jit_r_tokenizer(test_sample) assert not r_tokenizer.is_jitable - assert r_tokenizer.to_ivalue().is_jitable + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + assert r_tokenizer.__prepare_scriptable__().is_jitable self.assertEqual(eager_tokens, ref_results) self.assertEqual(jit_tokens, ref_results) @@ -186,7 +192,9 @@ def test_load_and_save(self): with self.subTest('torchscript'): save_path = os.path.join(self.test_dir, 'regex_torchscript.pt') - tokenizer = regex_tokenizer(patterns_list).to_ivalue() + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + tokenizer = regex_tokenizer(patterns_list).__prepare_scriptable__() torch.save(tokenizer, save_path) loaded_tokenizer = torch.load(save_path) results = loaded_tokenizer(test_sample) diff --git a/test/experimental/test_transforms.py b/test/experimental/test_transforms.py index 1994c3c396..d3cc651ddc 100644 --- a/test/experimental/test_transforms.py +++ b/test/experimental/test_transforms.py @@ -16,7 +16,7 @@ class TestTransforms(TorchtextTestCase): def test_sentencepiece_processor(self): model_path = get_asset_path('spm_example.model') spm_transform = sentencepiece_processor(model_path) - jit_spm_transform = torch.jit.script(spm_transform.to_ivalue()) + jit_spm_transform = torch.jit.script(spm_transform) test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' ref_results = [15340, 4286, 981, 1207, 1681, 17, 84, 684, 8896, 5366, 144, 3689, 9, 5602, 12114, 6, 560, 649, 5602, 12114] @@ -28,7 +28,7 @@ def test_sentencepiece_processor(self): def test_sentencepiece_tokenizer(self): model_path = get_asset_path('spm_example.model') spm_tokenizer = sentencepiece_tokenizer(model_path) - jit_spm_tokenizer = torch.jit.script(spm_tokenizer.to_ivalue()) + jit_spm_tokenizer = torch.jit.script(spm_tokenizer) test_sample = 'SentencePiece is an unsupervised text tokenizer and detokenizer' ref_results = ['\u2581Sent', 'ence', 'P', 'ie', 'ce', '\u2581is', '\u2581an', '\u2581un', 'super', 'vis', 'ed', '\u2581text', @@ -48,7 +48,7 @@ def test_vector_transform(self): data_path = os.path.join(dir_name, asset_name) shutil.copy(asset_path, data_path) vector_transform = VectorTransform(FastText(root=dir_name, validate_file=False)) - jit_vector_transform = torch.jit.script(vector_transform.to_ivalue()) + jit_vector_transform = torch.jit.script(vector_transform) # The first 3 entries in each vector. expected_fasttext_simple_en = torch.tensor([[-0.065334, -0.093031, -0.017571], [-0.32423, -0.098845, -0.0073467]]) @@ -74,7 +74,9 @@ def test_sentencepiece_load_and_save(self): with self.subTest('torchscript'): save_path = os.path.join(self.test_dir, 'spm_torchscript.pt') - spm = sentencepiece_tokenizer((model_path)).to_ivalue() + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + spm = sentencepiece_tokenizer((model_path)).__prepare_scriptable__() torch.save(spm, save_path) loaded_spm = torch.load(save_path) self.assertEqual(expected, loaded_spm(input)) diff --git a/test/experimental/test_vectors.py b/test/experimental/test_vectors.py index ff5293b402..0cb32ffe1d 100644 --- a/test/experimental/test_vectors.py +++ b/test/experimental/test_vectors.py @@ -54,10 +54,12 @@ def test_vectors_jit(self): tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) vectors_obj = build_vectors(tokens, vecs, unk_tensor=unk_tensor) - jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + jit_vectors_obj = torch.jit.script(vectors_obj) assert not vectors_obj.is_jitable - assert vectors_obj.to_ivalue().is_jitable + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + assert vectors_obj.__prepare_scriptable__().is_jitable self.assertEqual(vectors_obj['a'], jit_vectors_obj['a']) self.assertEqual(vectors_obj['b'], jit_vectors_obj['b']) @@ -71,7 +73,7 @@ def test_vectors_forward(self): tokens = ['a', 'b'] vecs = torch.stack((tensorA, tensorB), 0) vectors_obj = build_vectors(tokens, vecs, unk_tensor=unk_tensor) - jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + jit_vectors_obj = torch.jit.script(vectors_obj) tokens_to_lookup = ['a', 'b', 'c'] expected_vectors = torch.stack((tensorA, tensorB, unk_tensor), 0) @@ -148,7 +150,9 @@ def test_vectors_load_and_save(self): with self.subTest('torchscript'): vector_path = os.path.join(self.test_dir, 'vectors_torchscript.pt') - torch.save(vectors_obj.to_ivalue(), vector_path) + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + torch.save(vectors_obj.__prepare_scriptable__(), vector_path) loaded_vectors_obj = torch.load(vector_path) self.assertEqual(loaded_vectors_obj['a'], tensorA) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 662aa6667a..879c03e72d 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -104,13 +104,15 @@ def test_vocab_jit(self): c = OrderedDict(sorted_by_freq_tuples) v = vocab(c, min_freq=3) - jit_v = torch.jit.script(v.to_ivalue()) + jit_v = torch.jit.script(v) expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} assert not v.is_jitable - assert v.to_ivalue().is_jitable + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + assert v.__prepare_scriptable__().is_jitable self.assertEqual(jit_v.get_itos(), expected_itos) self.assertEqual(dict(jit_v.get_stoi()), expected_stoi) @@ -121,7 +123,7 @@ def test_vocab_forward(self): c = OrderedDict(sorted_by_freq_tuples) v = vocab(c) - jit_v = torch.jit.script(v.to_ivalue()) + jit_v = torch.jit.script(v) tokens = ['b', 'a', 'c'] expected_indices = [2, 1, 3] @@ -208,7 +210,9 @@ def test_vocab_load_and_save(self): with self.subTest('torchscript'): vocab_path = os.path.join(self.test_dir, 'vocab_torchscript.pt') - torch.save(v.to_ivalue(), vocab_path) + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + torch.save(v.__prepare_scriptable__(), vocab_path) loaded_v = torch.load(vocab_path) self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) diff --git a/test/experimental/test_with_asset.py b/test/experimental/test_with_asset.py index 50c01935a9..f900fb6752 100644 --- a/test/experimental/test_with_asset.py +++ b/test/experimental/test_with_asset.py @@ -82,7 +82,7 @@ def test_vocab_transform(self): vocab_transform = VocabTransform(load_vocab_from_file(f)) self.assertEqual(vocab_transform(['of', 'that', 'new']), [7, 18, 24]) - jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) + jit_vocab_transform = torch.jit.script(vocab_transform) self.assertEqual(jit_vocab_transform(['of', 'that', 'new', 'that']), [7, 18, 24, 18]) @@ -128,7 +128,7 @@ def test_glove(self): data_path = os.path.join(dir_name, asset_name) shutil.copy(asset_path, data_path) vectors_obj = GloVe(root=dir_name, validate_file=False) - jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + jit_vectors_obj = torch.jit.script(vectors_obj) # The first 3 entries in each vector. expected_glove = { @@ -191,7 +191,7 @@ def test_vocab_from_raw_text_file(self): asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: tokenizer = basic_english_normalize() - jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + jit_tokenizer = torch.jit.script(tokenizer) v = build_vocab_from_text_file(f, jit_tokenizer, unk_token='') expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', @@ -243,7 +243,7 @@ def test_text_sequential_transform(self): asset_path = get_asset_path(asset_name) with open(asset_path, 'r') as f: pipeline = TextSequentialTransforms(basic_english_normalize(), load_vocab_from_file(f)) - jit_pipeline = torch.jit.script(pipeline.to_ivalue()) + jit_pipeline = torch.jit.script(pipeline) self.assertEqual(pipeline('of that new'), [7, 18, 24]) self.assertEqual(jit_pipeline('of that new'), [7, 18, 24]) @@ -270,7 +270,7 @@ def test_fast_text(self): data_path = os.path.join(dir_name, asset_name) shutil.copy(asset_path, data_path) vectors_obj = FastText(root=dir_name, validate_file=False) - jit_vectors_obj = torch.jit.script(vectors_obj.to_ivalue()) + jit_vectors_obj = torch.jit.script(vectors_obj) # The first 3 entries in each vector. expected_fasttext_simple_en = { diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 1f62ea7032..3b542aeb45 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -2,7 +2,6 @@ import torch.nn as nn from typing import List from torchtext._torchtext import RegexTokenizer as RegexTokenizerPybind -from collections import OrderedDict from torch import Tensor from torchtext._torchtext import SentencePiece as SentencePiecePybind import io @@ -50,7 +49,7 @@ def basic_english_normalize(): >>> from torchtext.experimental.transforms import basic_english_normalize >>> test_sample = 'Basic English Normalization for a Line of Text' >>> basic_eng_norm = basic_english_normalize() - >>> jit_basic_eng_norm = torch.jit.script(basic_eng_norm.to_ivalue()) + >>> jit_basic_eng_norm = torch.jit.script(basic_eng_norm) >>> tokens = jit_basic_eng_norm(test_sample) """ @@ -124,10 +123,9 @@ def forward(self, line: str) -> List[str]: return self.regex_tokenizer.forward(line) - def to_ivalue(self): + def __prepare_scriptable__(self): r"""Return a JITable BasicEnglishNormalize. """ - regex_tokenizer = torch.classes.torchtext.RegexTokenizer(self.regex_tokenizer.patterns_, self.regex_tokenizer.replacements_, True) return BasicEnglishNormalize(regex_tokenizer) @@ -159,10 +157,9 @@ def forward(self, line: str) -> List[str]: return self.regex_tokenizer.forward(line) - def to_ivalue(self): + def __prepare_scriptable__(self): r"""Return a JITable RegexTokenizer. """ - regex_tokenizer = torch.classes.torchtext.RegexTokenizer(self.regex_tokenizer.patterns_, self.regex_tokenizer.replacements_, False) return RegexTokenizer(regex_tokenizer) @@ -177,7 +174,7 @@ class TextSequentialTransforms(nn.Sequential): >>> txt_pipeline = TextSequentialTransforms(tokenizer) >>> txt_pipeline('here is an example') ['here', 'is', 'an', 'example'] - >>> jit_txt_pipeline = torch.jit.script(txt_pipeline.to_ivalue()) + >>> jit_txt_pipeline = torch.jit.script(txt_pipeline) """ def forward(self, input: str): @@ -185,17 +182,6 @@ def forward(self, input: str): input = module(input) return input - def to_ivalue(self): - r"""Return a JITable TextSequentialTransforms. - """ - - module_list = [] - for _idx, _module in enumerate(self): - if hasattr(_module, 'to_ivalue'): - _module = _module.to_ivalue() - module_list.append((str(_idx), _module)) - return TextSequentialTransforms(OrderedDict(module_list)) - PRETRAINED_SP_MODEL = { 'text_unigram_15000': 'https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_15000.model', @@ -263,7 +249,7 @@ def sentencepiece_tokenizer(sp_model): >>> import torch >>> from torchtext.experimental.transforms import sentencepiece_tokenizer >>> spm_tokenizer = sentencepiece_tokenizer('m_user.model') - >>> jit_spm_tokenizer = torch.jit.script(spm_tokenizer.to_ivalue()) + >>> jit_spm_tokenizer = torch.jit.script(spm_tokenizer) """ spm = load_sp_model(sp_model) @@ -308,7 +294,7 @@ def decode(self, tokens: List[str]) -> str: return self.sp_model.DecodePieces(tokens) - def to_ivalue(self): + def __prepare_scriptable__(self): torchbind_spm = torch.classes.torchtext.SentencePiece(self.sp_model._return_content()) return SentencePieceTokenizer(torchbind_spm) @@ -323,7 +309,7 @@ def sentencepiece_processor(sp_model): >>> import torch >>> from torchtext.experimental.transforms import sentencepiece_processor >>> spm_processor = sentencepiece_processor('m_user.model') - >>> jit_spm_processor = torch.jit.script(spm_processor.to_ivalue()) + >>> jit_spm_processor = torch.jit.script(spm_processor) """ spm = load_sp_model(sp_model) @@ -366,7 +352,7 @@ def decode(self, ids: List[int]) -> str: return self.sp_model.DecodeIds(ids) - def to_ivalue(self): + def __prepare_scriptable__(self): torchbind_spm = torch.classes.torchtext.SentencePiece(self.sp_model._return_content()) return SentencePieceProcessor(torchbind_spm) @@ -382,7 +368,7 @@ class VocabTransform(nn.Module): >>> from torchtext.experimental.vocab import vocab_from_file_object >>> f = open('vocab.txt', 'r') >>> vocab_transform = VocabTransform(vocab_from_file_object(f)) - >>> jit_vocab_transform = torch.jit.script(vocab_transform.to_ivalue()) + >>> jit_vocab_transform = torch.jit.script(vocab_transform) """ def __init__(self, vocab): @@ -402,12 +388,6 @@ def forward(self, tokens: List[str]) -> List[int]: return self.vocab.lookup_indices(tokens) - def to_ivalue(self): - if hasattr(self.vocab, 'to_ivalue'): - vocab = self.vocab.to_ivalue() - return VocabTransform(vocab) - return self - class VectorTransform(nn.Module): r"""Vector transform @@ -419,7 +399,7 @@ class VectorTransform(nn.Module): >>> import torch >>> from torchtext.experimental.vectors import FastText >>> vector_transform = VectorTransform(FastText()) - >>> jit_vector_transform = torch.jit.script(vector_transform.to_ivalue()) + >>> jit_vector_transform = torch.jit.script(vector_transform) """ def __init__(self, vector): @@ -438,9 +418,3 @@ def forward(self, tokens: List[str]) -> Tensor: """ return self.vector.lookup_vectors(tokens) - - def to_ivalue(self): - if hasattr(self.vector, 'to_ivalue'): - vector = self.vector.to_ivalue() - return VectorTransform(vector) - return self diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index 72bae2351b..e7779d9ad4 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -285,7 +285,7 @@ def lookup_vectors(self, tokens: List[str]) -> Tensor: return self.vectors.lookup_vectors(tokens) - def to_ivalue(self): + def __prepare_scriptable__(self): r"""Return a JITable Vectors. """ stoi = self.vectors.get_stoi() diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 6883326938..606965daa9 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -43,7 +43,7 @@ def build_vocab_from_text_file(file_object, jited_tokenizer, min_freq=1, unk_tok >>> f = open('vocab.txt', 'r') >>> tokenizer = basic_english_normalize() >>> tokenizer = basic_english_normalize() - >>> jit_tokenizer = torch.jit.script(tokenizer.to_ivalue()) + >>> jit_tokenizer = torch.jit.script(tokenizer) >>> v = build_vocab_from_text_file(f, jit_tokenizer) """ vocab_obj = _build_vocab_from_text_file(file_object.name, unk_token, min_freq, num_cpus, jited_tokenizer) @@ -264,7 +264,7 @@ def get_itos(self) -> List[str]: """ return self.vocab.get_itos() - def to_ivalue(self): + def __prepare_scriptable__(self): r"""Return a JITable Vocab. """ cpp_vocab = torch.classes.torchtext.Vocab(self.vocab.itos_, self.vocab.unk_token_) From c34c150e2f77721f136cb2d2f95c488baa4bc46c Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 44/68] Pass an embedding layer to the constructor of the BertModel class (#1135) Reviewed By: zhangguanheng66 Differential Revision: D26369001 fbshipit-source-id: f5a67a2a812d568073505ec4d181f6e418eb4a3f --- examples/BERT/model.py | 20 +++++++++++--------- examples/BERT/ns_task.py | 5 +++-- examples/BERT/qa_task.py | 5 +++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/examples/BERT/model.py b/examples/BERT/model.py index 316841c751..484117e19c 100644 --- a/examples/BERT/model.py +++ b/examples/BERT/model.py @@ -43,7 +43,8 @@ def __init__(self, ntoken, ninp, dropout=0.5): self.norm = LayerNorm(ninp) self.dropout = Dropout(dropout) - def forward(self, src, token_type_input): + def forward(self, seq_inputs): + src, token_type_input = seq_inputs src = self.embed(src) + self.pos_embed(src) \ + self.tok_type_embed(src, token_type_input) return self.dropout(self.norm(src)) @@ -99,16 +100,16 @@ def forward(self, src, src_mask=None, src_key_padding_mask=None): class BertModel(nn.Module): """Contain a transformer encoder.""" - def __init__(self, ntoken, ninp, nhead, nhid, nlayers, dropout=0.5): + def __init__(self, ntoken, ninp, nhead, nhid, nlayers, embed_layer, dropout=0.5): super(BertModel, self).__init__() self.model_type = 'Transformer' - self.bert_embed = BertEmbedding(ntoken, ninp) + self.bert_embed = embed_layer encoder_layers = TransformerEncoderLayer(ninp, nhead, nhid, dropout) self.transformer_encoder = TransformerEncoder(encoder_layers, nlayers) self.ninp = ninp - def forward(self, src, token_type_input): - src = self.bert_embed(src, token_type_input) + def forward(self, seq_inputs): + src = self.bert_embed(seq_inputs) output = self.transformer_encoder(src) return output @@ -118,7 +119,8 @@ class MLMTask(nn.Module): def __init__(self, ntoken, ninp, nhead, nhid, nlayers, dropout=0.5): super(MLMTask, self).__init__() - self.bert_model = BertModel(ntoken, ninp, nhead, nhid, nlayers, dropout=0.5) + embed_layer = BertEmbedding(ntoken, ninp) + self.bert_model = BertModel(ntoken, ninp, nhead, nhid, nlayers, embed_layer, dropout=0.5) self.mlm_span = Linear(ninp, ninp) self.activation = F.gelu self.norm_layer = LayerNorm(ninp, eps=1e-12) @@ -126,7 +128,7 @@ def __init__(self, ntoken, ninp, nhead, nhid, nlayers, dropout=0.5): def forward(self, src, token_type_input=None): src = src.transpose(0, 1) # Wrap up by nn.DataParallel - output = self.bert_model(src, token_type_input) + output = self.bert_model((src, token_type_input)) output = self.mlm_span(output) output = self.activation(output) output = self.norm_layer(output) @@ -147,7 +149,7 @@ def __init__(self, bert_model): def forward(self, src, token_type_input): src = src.transpose(0, 1) # Wrap up by nn.DataParallel - output = self.bert_model(src, token_type_input) + output = self.bert_model((src, token_type_input)) # Send the first <'cls'> seq to a classifier output = self.activation(self.linear_layer(output[0])) output = self.ns_span(output) @@ -164,7 +166,7 @@ def __init__(self, bert_model): self.qa_span = Linear(bert_model.ninp, 2) def forward(self, src, token_type_input): - output = self.bert_model(src, token_type_input) + output = self.bert_model((src, token_type_input)) # transpose output (S, N, E) to (N, S, E) output = output.transpose(0, 1) output = self.activation(output) diff --git a/examples/BERT/ns_task.py b/examples/BERT/ns_task.py index 06786a82dc..3084686ebb 100644 --- a/examples/BERT/ns_task.py +++ b/examples/BERT/ns_task.py @@ -5,7 +5,7 @@ import torch.nn as nn from torch.nn.parallel import DistributedDataParallel as DDP from torch.utils.data import DataLoader -from model import NextSentenceTask, BertModel +from model import NextSentenceTask, BertModel, BertEmbedding from utils import run_demo, run_ddp, wrap_up @@ -149,7 +149,8 @@ def run_main(args, rank=None): if args.checkpoint != 'None': model = torch.load(args.checkpoint) else: - pretrained_bert = BertModel(len(vocab), args.emsize, args.nhead, args.nhid, args.nlayers, args.dropout) + embed_layer = BertEmbedding(len(vocab), args.emsize) + pretrained_bert = BertModel(len(vocab), args.emsize, args.nhead, args.nhid, args.nlayers, embed_layer, args.dropout) pretrained_bert.load_state_dict(torch.load(args.bert_model)) model = NextSentenceTask(pretrained_bert) diff --git a/examples/BERT/qa_task.py b/examples/BERT/qa_task.py index 72595c101d..b2239bc612 100644 --- a/examples/BERT/qa_task.py +++ b/examples/BERT/qa_task.py @@ -9,7 +9,7 @@ from model import QuestionAnswerTask from metrics import compute_qa_exact, compute_qa_f1 from utils import print_loss_log -from model import BertModel +from model import BertModel, BertEmbedding def process_raw_data(data): @@ -174,7 +174,8 @@ def train(): train_dataset = process_raw_data(train_dataset) dev_dataset = process_raw_data(dev_dataset) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - pretrained_bert = BertModel(len(vocab), args.emsize, args.nhead, args.nhid, args.nlayers, args.dropout) + embed_layer = BertEmbedding(len(vocab), args.emsize) + pretrained_bert = BertModel(len(vocab), args.emsize, args.nhead, args.nhid, args.nlayers, embed_layer, args.dropout) pretrained_bert.load_state_dict(torch.load(args.bert_model)) model = QuestionAnswerTask(pretrained_bert).to(device) criterion = nn.CrossEntropyLoss() From 6a69d55da15a74639539d49eca23310040114eb7 Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 45/68] add __next__ method to RawTextIterableDataset (#1141) Reviewed By: zhangguanheng66 Differential Revision: D26368997 fbshipit-source-id: f5ef78f5f4a224db497f47f774eaddedd0498b4b --- test/data/test_builtin_datasets.py | 51 ++++++++++++------- torchtext/experimental/datasets/raw/common.py | 4 ++ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 95f2894634..67d168d02a 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -58,9 +58,9 @@ def test_wikitext2(self): # Add test for the subset of the standard datasets train_iter, valid_iter, test_iter = torchtext.experimental.datasets.raw.WikiText2(split=('train', 'valid', 'test')) - self._helper_test_func(len(train_iter), 36718, next(iter(train_iter)), ' \n') - self._helper_test_func(len(valid_iter), 3760, next(iter(valid_iter)), ' \n') - self._helper_test_func(len(test_iter), 4358, next(iter(test_iter)), ' \n') + self._helper_test_func(len(train_iter), 36718, next(train_iter), ' \n') + self._helper_test_func(len(valid_iter), 3760, next(valid_iter), ' \n') + self._helper_test_func(len(test_iter), 4358, next(test_iter), ' \n') del train_iter, valid_iter, test_iter train_dataset, test_dataset = WikiText2(split=('train', 'test')) train_data = torch.cat(tuple(filter(lambda t: t.numel() > 0, train_dataset))) @@ -113,8 +113,8 @@ def test_penntreebank(self): self._helper_test_func(len(test_data), 82114, test_data[30:35], [397, 93, 4, 16, 7]) train_iter, test_iter = torchtext.experimental.datasets.raw.PennTreebank(split=('train', 'test')) - self._helper_test_func(len(train_iter), 42068, next(iter(train_iter))[:15], ' aer banknote b') - self._helper_test_func(len(test_iter), 3761, next(iter(test_iter))[:25], " no it was n't black mond") + self._helper_test_func(len(train_iter), 42068, next(train_iter)[:15], ' aer banknote b') + self._helper_test_func(len(test_iter), 3761, next(test_iter)[:25], " no it was n't black mond") del train_iter, test_iter def test_text_classification(self): @@ -134,8 +134,8 @@ def test_text_classification(self): self._helper_test_func(len(train_dataset), 120000, train_dataset[-1][1][:10], [2155, 223, 2405, 30, 3010, 2204, 54, 3603, 4930, 2405]) train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() - self._helper_test_func(len(train_iter), 120000, next(iter(train_iter))[1][:25], 'Wall St. Bears Claw Back ') - self._helper_test_func(len(test_iter), 7600, next(iter(test_iter))[1][:25], 'Fears for T N pension aft') + self._helper_test_func(len(train_iter), 120000, next(train_iter)[1][:25], 'Wall St. Bears Claw Back ') + self._helper_test_func(len(test_iter), 7600, next(test_iter)[1][:25], 'Fears for T N pension aft') del train_iter, test_iter def test_num_lines_of_dataset(self): @@ -151,6 +151,19 @@ def test_offset_dataset(self): 'Non-OPEC Nations Sho', 'Google IPO Auction O', 'Dollar Falls Broadly']) + def test_next_method_dataset(self): + train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() + for_count = 0 + next_count = 0 + for line in train_iter: + for_count += 1 + try: + next(train_iter) + next_count += 1 + except: + break + self.assertEqual((for_count, next_count), (60000, 60000)) + def test_imdb(self): from torchtext.experimental.datasets import IMDB from torchtext.vocab import Vocab @@ -171,8 +184,8 @@ def test_imdb(self): self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], [13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]) train_iter, test_iter = torchtext.experimental.datasets.raw.IMDB() - self._helper_test_func(len(train_iter), 25000, next(iter(train_iter))[1][:25], 'I rented I AM CURIOUS-YEL') - self._helper_test_func(len(test_iter), 25000, next(iter(test_iter))[1][:25], 'I love sci-fi and am will') + self._helper_test_func(len(train_iter), 25000, next(train_iter)[1][:25], 'I rented I AM CURIOUS-YEL') + self._helper_test_func(len(test_iter), 25000, next(test_iter)[1][:25], 'I love sci-fi and am will') del train_iter, test_iter def test_iwslt(self): @@ -248,10 +261,10 @@ def test_multi30k(self): # Add test for the subset of the standard datasets train_iter, valid_iter = torchtext.experimental.datasets.raw.Multi30k(split=('train', 'valid')) - self._helper_test_func(len(train_iter), 29000, ' '.join(next(iter(train_iter))), + self._helper_test_func(len(train_iter), 29000, ' '.join(next(train_iter)), ' '.join(['Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n', 'Two young, White males are outside near many bushes.\n'])) - self._helper_test_func(len(valid_iter), 1014, ' '.join(next(iter(valid_iter))), + self._helper_test_func(len(valid_iter), 1014, ' '.join(next(valid_iter)), ' '.join(['Eine Gruppe von Männern lädt Baumwolle auf einen Lastwagen\n', 'A group of men are loading cotton onto a truck\n'])) del train_iter, valid_iter @@ -323,9 +336,9 @@ def test_udpos_sequence_tagging(self): ([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585], [6, 20, 8, 10, 8, 8, 24, 13, 8, 15])) train_iter, valid_iter = torchtext.experimental.datasets.raw.UDPOS(split=('train', 'valid')) - self._helper_test_func(len(train_iter), 12543, ' '.join(next(iter(train_iter))[0][:5]), + self._helper_test_func(len(train_iter), 12543, ' '.join(next(train_iter)[0][:5]), ' '.join(['Al', '-', 'Zaman', ':', 'American'])) - self._helper_test_func(len(valid_iter), 2002, ' '.join(next(iter(valid_iter))[0][:5]), + self._helper_test_func(len(valid_iter), 2002, ' '.join(next(valid_iter)[0][:5]), ' '.join(['From', 'the', 'AP', 'comes', 'this'])) del train_iter, valid_iter @@ -376,9 +389,9 @@ def test_conll_sequence_tagging(self): [18, 17, 12, 19, 10, 6, 3, 3, 4, 4], [3, 5, 7, 7, 3, 2, 6, 6, 3, 2])) train_iter, test_iter = torchtext.experimental.datasets.raw.CoNLL2000Chunking() - self._helper_test_func(len(train_iter), 8936, ' '.join(next(iter(train_iter))[0][:5]), + self._helper_test_func(len(train_iter), 8936, ' '.join(next(train_iter)[0][:5]), ' '.join(['Confidence', 'in', 'the', 'pound', 'is'])) - self._helper_test_func(len(test_iter), 2012, ' '.join(next(iter(test_iter))[0][:5]), + self._helper_test_func(len(test_iter), 2012, ' '.join(next(test_iter)[0][:5]), ' '.join(['Rockwell', 'International', 'Corp.', "'s", 'Tulsa'])) del train_iter, test_iter @@ -405,9 +418,9 @@ def test_squad1(self): self._helper_test_func(len(train_dataset), 87599, (question[:5], ans_pos[0]), ([7, 24, 86, 52, 2], [72, 72])) train_iter, dev_iter = torchtext.experimental.datasets.raw.SQuAD1() - self._helper_test_func(len(train_iter), 87599, next(iter(train_iter))[0][:50], + self._helper_test_func(len(train_iter), 87599, next(train_iter)[0][:50], 'Architecturally, the school has a Catholic charact') - self._helper_test_func(len(dev_iter), 10570, next(iter(dev_iter))[0][:50], + self._helper_test_func(len(dev_iter), 10570, next(dev_iter)[0][:50], 'Super Bowl 50 was an American football game to det') del train_iter, dev_iter @@ -434,8 +447,8 @@ def test_squad2(self): self._helper_test_func(len(train_dataset), 130319, (question[:5], ans_pos[0]), ([84, 50, 1421, 12, 5439], [9, 9])) train_iter, dev_iter = torchtext.experimental.datasets.raw.SQuAD2() - self._helper_test_func(len(train_iter), 130319, next(iter(train_iter))[0][:50], + self._helper_test_func(len(train_iter), 130319, next(train_iter)[0][:50], 'Beyoncé Giselle Knowles-Carter (/biːˈjɒnseɪ/ bee-Y') - self._helper_test_func(len(dev_iter), 11873, next(iter(dev_iter))[0][:50], + self._helper_test_func(len(dev_iter), 11873, next(dev_iter)[0][:50], 'The Normans (Norman: Nourmands; French: Normands; ') del train_iter, dev_iter diff --git a/torchtext/experimental/datasets/raw/common.py b/torchtext/experimental/datasets/raw/common.py index 1267b703ff..e53786ae54 100644 --- a/torchtext/experimental/datasets/raw/common.py +++ b/torchtext/experimental/datasets/raw/common.py @@ -32,6 +32,10 @@ def __iter__(self): break yield item + def __next__(self): + item = next(self._iterator) + return item + def __len__(self): return self.num_lines From 3c0ed6adccde0577b5c5531baa8447a2d9e0275d Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Mon, 15 Feb 2021 06:01:42 -0800 Subject: [PATCH 46/68] Add func to count the total number of parameters in a model (#1134) Reviewed By: zhangguanheng66 Differential Revision: D26369000 fbshipit-source-id: c687c0f0c2697dbd9c17a79a1291a2e279bbd1b8 --- docs/source/index.rst | 1 + docs/source/models_utils.rst | 13 +++++++++++++ test/models/__init__.py | 0 test/models/test_utils.py | 9 +++++++++ torchtext/experimental/__init__.py | 3 ++- torchtext/experimental/models/__init__.py | 3 +++ torchtext/experimental/models/utils.py | 22 ++++++++++++++++++++++ 7 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 docs/source/models_utils.rst create mode 100644 test/models/__init__.py create mode 100644 test/models/test_utils.py create mode 100644 torchtext/experimental/models/__init__.py create mode 100644 torchtext/experimental/models/utils.py diff --git a/docs/source/index.rst b/docs/source/index.rst index 2072db4adf..4e812ee286 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -44,6 +44,7 @@ popular datasets for natural language. experimental_transforms experimental_vectors experimental_vocab + models_utils examples .. automodule:: torchtext diff --git a/docs/source/models_utils.rst b/docs/source/models_utils.rst new file mode 100644 index 0000000000..1bcb2f73e7 --- /dev/null +++ b/docs/source/models_utils.rst @@ -0,0 +1,13 @@ +.. role:: hidden + :class: hidden-section + +torchtext.experimental.models.utils +=================================== + +.. automodule:: torchtext.experimental.models.utils +.. currentmodule:: torchtext.experimental.models.utils + +:hidden:`count_model_param` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: count_model_param diff --git a/test/models/__init__.py b/test/models/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/models/test_utils.py b/test/models/test_utils.py new file mode 100644 index 0000000000..162ec932c4 --- /dev/null +++ b/test/models/test_utils.py @@ -0,0 +1,9 @@ +import torch +from torchtext.experimental.models.utils import count_model_param +from ..common.torchtext_test_case import TorchtextTestCase + + +class TestModelsUtils(TorchtextTestCase): + def test_count_model_parameters_func(self): + model = torch.nn.Embedding(100, 200) + self.assertEqual(count_model_param(model, unit=10**3), 20.0) diff --git a/torchtext/experimental/__init__.py b/torchtext/experimental/__init__.py index 196d0dd84b..18eba857a5 100644 --- a/torchtext/experimental/__init__.py +++ b/torchtext/experimental/__init__.py @@ -1,4 +1,5 @@ from . import datasets from . import transforms +from . import models -__all__ = ['datasets', 'transforms'] +__all__ = ['datasets', 'transforms', 'models'] diff --git a/torchtext/experimental/models/__init__.py b/torchtext/experimental/models/__init__.py new file mode 100644 index 0000000000..2065636d77 --- /dev/null +++ b/torchtext/experimental/models/__init__.py @@ -0,0 +1,3 @@ +from .utils import count_model_param + +__all__ = ["count_model_param"] diff --git a/torchtext/experimental/models/utils.py b/torchtext/experimental/models/utils.py new file mode 100644 index 0000000000..b24ddd0404 --- /dev/null +++ b/torchtext/experimental/models/utils.py @@ -0,0 +1,22 @@ +import torch + + +def count_model_param(nn_model, unit=10**6): + r""" + Count the parameters in a model + + Args: + model: the model (torch.nn.Module) + unit: the unit of the returned value. Default: 10**6 or M. + + Examples: + >>> import torch + >>> import torchtext + >>> from torchtext.experimental.models.utils import count_model_param + >>> model = torch.nn.Embedding(100, 200) + >>> count_model_param(model, unit=10**3) + >>> 20. + """ + model_parameters = filter(lambda p: p.requires_grad, nn_model.parameters()) + params = sum([torch.prod(torch.tensor(p.size())) for p in model_parameters]) + return params.item() / unit From 68958f8ba4d7c022fa8242fe5ab9712c79f4cb6f Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Wed, 17 Feb 2021 11:35:20 -0800 Subject: [PATCH 47/68] Retire the legacy code in torchtext library and fix the dependency of the downstream libraries Summary: This diff is doing: 1) move the legacy code in torchtext to the legacy folder; 2) for the downstream libraries in fbcode, if they are using the legacy code, add "legacy" to the path. Reviewed By: cpuhrsch Differential Revision: D23718437 fbshipit-source-id: 1660868aaa95ac6555ad6793dda5ce02a9acdc08 --- test/data/test_batch.py | 2 +- test/data/test_builtin_datasets.py | 11 +- test/data/test_dataset.py | 2 +- test/data/test_subword.py | 4 +- test/data/test_utils.py | 15 +- test/legacy/__init__.py | 0 test/{ => legacy}/babi.py | 2 +- test/{ => legacy}/data.py | 2 +- test/legacy/data/__init__.py | 0 test/legacy/data/test_batch.py | 43 + test/{ => legacy}/data/test_field.py | 4 +- test/{ => legacy}/data/test_pipeline.py | 4 +- test/legacy/data/test_subword.py | 25 + test/{ => legacy}/imdb.py | 4 +- test/{ => legacy}/language_modeling.py | 4 +- test/{ => legacy}/nli.py | 8 +- test/{ => legacy}/sequence_tagging.py | 4 +- test/{ => legacy}/sst.py | 4 +- test/{ => legacy}/translation.py | 8 +- test/{ => legacy}/trec.py | 4 +- test/test_build.py | 20 +- torchtext/__init__.py | 4 +- torchtext/data/__init__.py | 6 +- torchtext/data/batch.py | 102 +-- torchtext/data/dataset.py | 357 +-------- torchtext/data/example.py | 107 +-- torchtext/data/field.py | 728 +---------------- torchtext/data/iterator.py | 292 +------ torchtext/data/pipeline.py | 87 +-- torchtext/datasets/__init__.py | 42 - torchtext/legacy/__init__.py | 6 + torchtext/legacy/data/__init__.py | 14 + torchtext/legacy/data/batch.py | 101 +++ torchtext/legacy/data/dataset.py | 361 +++++++++ torchtext/legacy/data/example.py | 99 +++ torchtext/legacy/data/field.py | 735 ++++++++++++++++++ torchtext/legacy/data/iterator.py | 297 +++++++ torchtext/legacy/data/pipeline.py | 85 ++ torchtext/legacy/datasets/__init__.py | 42 + torchtext/{ => legacy}/datasets/babi.py | 0 torchtext/{ => legacy}/datasets/imdb.py | 6 +- .../datasets/language_modeling.py | 16 +- torchtext/{ => legacy}/datasets/nli.py | 8 +- .../{ => legacy}/datasets/sequence_tagging.py | 3 +- torchtext/{ => legacy}/datasets/sst.py | 6 +- .../datasets/text_classification.py | 0 .../{ => legacy}/datasets/translation.py | 16 +- torchtext/{ => legacy}/datasets/trec.py | 6 +- .../datasets/unsupervised_learning.py | 0 tox.ini | 2 +- 50 files changed, 1971 insertions(+), 1727 deletions(-) create mode 100644 test/legacy/__init__.py rename test/{ => legacy}/babi.py (98%) rename test/{ => legacy}/data.py (95%) create mode 100644 test/legacy/data/__init__.py create mode 100644 test/legacy/data/test_batch.py rename test/{ => legacy}/data/test_field.py (99%) rename test/{ => legacy}/data/test_pipeline.py (95%) create mode 100644 test/legacy/data/test_subword.py rename test/{ => legacy}/imdb.py (93%) rename test/{ => legacy}/language_modeling.py (92%) rename test/{ => legacy}/nli.py (97%) rename test/{ => legacy}/sequence_tagging.py (97%) rename test/{ => legacy}/sst.py (96%) rename test/{ => legacy}/translation.py (94%) rename test/{ => legacy}/trec.py (94%) create mode 100644 torchtext/legacy/__init__.py create mode 100644 torchtext/legacy/data/__init__.py create mode 100644 torchtext/legacy/data/batch.py create mode 100644 torchtext/legacy/data/dataset.py create mode 100644 torchtext/legacy/data/example.py create mode 100644 torchtext/legacy/data/field.py create mode 100644 torchtext/legacy/data/iterator.py create mode 100644 torchtext/legacy/data/pipeline.py create mode 100644 torchtext/legacy/datasets/__init__.py rename torchtext/{ => legacy}/datasets/babi.py (100%) rename torchtext/{ => legacy}/datasets/imdb.py (98%) rename torchtext/{ => legacy}/datasets/language_modeling.py (98%) rename torchtext/{ => legacy}/datasets/nli.py (97%) rename torchtext/{ => legacy}/datasets/sequence_tagging.py (96%) rename torchtext/{ => legacy}/datasets/sst.py (98%) rename torchtext/{ => legacy}/datasets/text_classification.py (100%) rename torchtext/{ => legacy}/datasets/translation.py (97%) rename torchtext/{ => legacy}/datasets/trec.py (98%) rename torchtext/{ => legacy}/datasets/unsupervised_learning.py (100%) diff --git a/test/data/test_batch.py b/test/data/test_batch.py index d24b2cce33..acf369a6e3 100644 --- a/test/data/test_batch.py +++ b/test/data/test_batch.py @@ -1,5 +1,5 @@ import torch -import torchtext.data as data +from torchtext.legacy import data from ..common.torchtext_test_case import TorchtextTestCase diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 67d168d02a..b955a57c18 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -1,7 +1,7 @@ #!/user/bin/env python3 # Note that all the tests in this module require dataset (either network access or cached) import os -import torchtext.data as data +from torchtext.legacy import data import torch import torchtext from ..common.torchtext_test_case import TorchtextTestCase @@ -18,7 +18,12 @@ def _helper_test_func(self, length, target_length, results, target_results): self.assertEqual(results, target_results) def test_wikitext2_legacy(self): - from torchtext.datasets import WikiText2 + from torchtext.legacy.datasets import WikiText2 + # smoke test to ensure wikitext2 works properly + + # NOTE + # test_wikitext2 and test_wikitext2_legacy have some cache incompatibility. + # Keeping one's cache make the other fail. So we need to clean up the cache dir cachedir = os.path.join(self.project_root, ".data", "wikitext-2") conditional_remove(cachedir) @@ -74,7 +79,7 @@ def test_wikitext2(self): conditional_remove(cachefile) def test_penntreebank_legacy(self): - from torchtext.datasets import PennTreebank + from torchtext.legacy.datasets import PennTreebank # smoke test to ensure penn treebank works properly TEXT = data.Field(lower=True, batch_first=True) ds = PennTreebank diff --git a/test/data/test_dataset.py b/test/data/test_dataset.py index 849e6a770a..98662eef7c 100644 --- a/test/data/test_dataset.py +++ b/test/data/test_dataset.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -import torchtext.data as data +import torchtext.legacy.data as data import os import sys import tempfile diff --git a/test/data/test_subword.py b/test/data/test_subword.py index 5122fd6997..83aec7df0f 100644 --- a/test/data/test_subword.py +++ b/test/data/test_subword.py @@ -2,8 +2,8 @@ # Note that all the tests in this module require dataset (either network access or cached) import unittest -from torchtext import data -from torchtext.datasets import TREC +from torchtext.legacy import data +from torchtext.legacy.datasets import TREC class TestSubword(unittest.TestCase): diff --git a/test/data/test_utils.py b/test/data/test_utils.py index 7772f851c2..20e881349e 100644 --- a/test/data/test_utils.py +++ b/test/data/test_utils.py @@ -1,6 +1,5 @@ import io - -import torchtext.data as data +from torchtext.data import get_tokenizer from torchtext.utils import unicode_csv_reader from torchtext.experimental.functional import ngrams_func from ..common.torchtext_test_case import TorchtextTestCase @@ -12,29 +11,29 @@ class TestUtils(TorchtextTestCase): def test_get_tokenizer_split(self): # Test the default case with str.split - assert data.get_tokenizer(str.split) == str.split - assert data.get_tokenizer(str.split)(self.TEST_STR) == str.split(self.TEST_STR) + assert get_tokenizer(str.split) == str.split + assert get_tokenizer(str.split)(self.TEST_STR) == str.split(self.TEST_STR) def test_get_tokenizer_toktokt(self): # Test Toktok option. Test strings taken from NLTK doctests. # Note that internally, MosesTokenizer converts to unicode if applicable - toktok_tokenizer = data.get_tokenizer("toktok") + toktok_tokenizer = get_tokenizer("toktok") assert toktok_tokenizer(self.TEST_STR) == [ "A", "string", ",", "particularly", "one", "with", "slightly", "complex", "punctuation", "."] # Test that errors are raised for invalid input arguments. with self.assertRaises(ValueError): - data.get_tokenizer(1) + get_tokenizer(1) with self.assertRaises(ValueError): - data.get_tokenizer("some other string") + get_tokenizer("some other string") def test_text_nomalize_function(self): # Test text_nomalize function in torchtext.datasets.text_classification ref_lines = [] test_lines = [] - tokenizer = data.get_tokenizer("basic_english") + tokenizer = get_tokenizer("basic_english") data_path = get_asset_path('text_normalization_ag_news_test.csv') with io.open(data_path, encoding="utf8") as f: reader = unicode_csv_reader(f) diff --git a/test/legacy/__init__.py b/test/legacy/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/babi.py b/test/legacy/babi.py similarity index 98% rename from test/babi.py rename to test/legacy/babi.py index 00282826cf..cef3ff965d 100644 --- a/test/babi.py +++ b/test/legacy/babi.py @@ -1,4 +1,4 @@ -from torchtext import datasets +from torchtext.legacy import datasets # en-valid TRAIN_NUM = [0] + [900] * 16 + [904, 905, 900, 904] diff --git a/test/data.py b/test/legacy/data.py similarity index 95% rename from test/data.py rename to test/legacy/data.py index b582c0a5f0..98071a2fca 100644 --- a/test/data.py +++ b/test/legacy/data.py @@ -1,4 +1,4 @@ -from torchtext import data +from torchtext.legacy import data TEXT = data.Field() diff --git a/test/legacy/data/__init__.py b/test/legacy/data/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/legacy/data/test_batch.py b/test/legacy/data/test_batch.py new file mode 100644 index 0000000000..ca90adf47b --- /dev/null +++ b/test/legacy/data/test_batch.py @@ -0,0 +1,43 @@ +import torch +import torchtext.legacy.data as data + +from ...common.torchtext_test_case import TorchtextTestCase + + +class TestDataset(TorchtextTestCase): + def test_batch_with_missing_field(self): + # smoke test to see if batches with missing attributes are shown properly + with open(self.test_missing_field_dataset_path, "wt") as f: + f.write("text,label\n1,0") + + dst = data.TabularDataset(path=self.test_missing_field_dataset_path, + format="csv", skip_header=True, + fields=[("text", data.Field(use_vocab=False, + sequential=False)), + ("label", None)]) + itr = data.Iterator(dst, batch_size=64) + str(next(itr.__iter__())) + + def test_batch_iter(self): + self.write_test_numerical_features_dataset() + FLOAT = data.Field(use_vocab=False, sequential=False, + dtype=torch.float) + INT = data.Field(use_vocab=False, sequential=False, is_target=True) + TEXT = data.Field(sequential=False) + + dst = data.TabularDataset(path=self.test_numerical_features_dataset_path, + format="tsv", skip_header=False, + fields=[("float", FLOAT), + ("int", INT), + ("text", TEXT)]) + TEXT.build_vocab(dst) + itr = data.Iterator(dst, batch_size=2, device=-1, shuffle=False) + fld_order = [k for k, v in dst.fields.items() if + v is not None and not v.is_target] + batch = next(iter(itr)) + (x1, x2), y = batch + x = (x1, x2)[fld_order.index("float")] + self.assertEquals(y.data[0], 1) + self.assertEquals(y.data[1], 12) + self.assertAlmostEqual(x.data[0], 0.1, places=4) + self.assertAlmostEqual(x.data[1], 0.5, places=4) diff --git a/test/data/test_field.py b/test/legacy/data/test_field.py similarity index 99% rename from test/data/test_field.py rename to test/legacy/data/test_field.py index aa76c38567..b66f5870e4 100644 --- a/test/data/test_field.py +++ b/test/legacy/data/test_field.py @@ -3,10 +3,10 @@ import os import torch -import torchtext.data as data +import torchtext.legacy.data as data import pytest -from ..common.torchtext_test_case import TorchtextTestCase, verify_numericalized_example +from ...common.torchtext_test_case import TorchtextTestCase, verify_numericalized_example class TestField(TorchtextTestCase): diff --git a/test/data/test_pipeline.py b/test/legacy/data/test_pipeline.py similarity index 95% rename from test/data/test_pipeline.py rename to test/legacy/data/test_pipeline.py index c1eda9a757..7a39c081fa 100644 --- a/test/data/test_pipeline.py +++ b/test/legacy/data/test_pipeline.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -import torchtext.data as data +import torchtext.legacy.data as data -from ..common.torchtext_test_case import TorchtextTestCase +from ...common.torchtext_test_case import TorchtextTestCase class TestPipeline(TorchtextTestCase): diff --git a/test/legacy/data/test_subword.py b/test/legacy/data/test_subword.py new file mode 100644 index 0000000000..83aec7df0f --- /dev/null +++ b/test/legacy/data/test_subword.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# Note that all the tests in this module require dataset (either network access or cached) +import unittest + +from torchtext.legacy import data +from torchtext.legacy.datasets import TREC + + +class TestSubword(unittest.TestCase): + def test_subword_trec(self): + TEXT = data.SubwordField() + LABEL = data.Field(sequential=False) + RAW = data.Field(sequential=False, use_vocab=False) + raw, _ = TREC.splits(RAW, LABEL) + cooked, _ = TREC.splits(TEXT, LABEL) + LABEL.build_vocab(cooked) + TEXT.build_vocab(cooked, max_size=100) + TEXT.segment(cooked) + print(cooked[0].text) + batch = next(iter(data.Iterator(cooked, 1, shuffle=False))) + self.assertEqual(TEXT.reverse(batch.text.data)[0], raw[0].text) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/imdb.py b/test/legacy/imdb.py similarity index 93% rename from test/imdb.py rename to test/legacy/imdb.py index 88b94f6345..eec869cc83 100644 --- a/test/imdb.py +++ b/test/legacy/imdb.py @@ -1,5 +1,5 @@ -from torchtext import data -from torchtext import datasets +from torchtext.legacy import data +from torchtext.legacy import datasets from torchtext.vocab import GloVe diff --git a/test/language_modeling.py b/test/legacy/language_modeling.py similarity index 92% rename from test/language_modeling.py rename to test/legacy/language_modeling.py index cd9c6e3340..fc41b57c5a 100644 --- a/test/language_modeling.py +++ b/test/legacy/language_modeling.py @@ -1,5 +1,5 @@ -from torchtext import data -from torchtext import datasets +from torchtext.legacy import data +from torchtext.legacy import datasets from torchtext.vocab import GloVe # Approach 1: diff --git a/test/nli.py b/test/legacy/nli.py similarity index 97% rename from test/nli.py rename to test/legacy/nli.py index 8bc8723af9..860064f929 100644 --- a/test/nli.py +++ b/test/legacy/nli.py @@ -1,9 +1,9 @@ import torch -from .common.torchtext_test_case import TorchtextTestCase +from ..common.torchtext_test_case import TorchtextTestCase -from torchtext.datasets import SNLI, MultiNLI, XNLI -from torchtext.datasets.nli import ParsedTextField, ShiftReduceField -from torchtext.data import Field, LabelField, Iterator +from torchtext.legacy.datasets import SNLI, MultiNLI, XNLI +from torchtext.legacy.datasets.nli import ParsedTextField, ShiftReduceField +from torchtext.legacy.data import Field, LabelField, Iterator import shutil diff --git a/test/sequence_tagging.py b/test/legacy/sequence_tagging.py similarity index 97% rename from test/sequence_tagging.py rename to test/legacy/sequence_tagging.py index ccf1e49d4f..76f65448e8 100644 --- a/test/sequence_tagging.py +++ b/test/legacy/sequence_tagging.py @@ -1,5 +1,5 @@ -from torchtext import data -from torchtext import datasets +from torchtext.legacy import data +from torchtext.legacy import datasets from torchtext.vocab import GloVe # Define the fields associated with the sequences. diff --git a/test/sst.py b/test/legacy/sst.py similarity index 96% rename from test/sst.py rename to test/legacy/sst.py index 507b61a962..6ba50fbbee 100644 --- a/test/sst.py +++ b/test/legacy/sst.py @@ -1,5 +1,5 @@ -from torchtext import data -from torchtext import datasets +from torchtext.legacy import data +from torchtext.legacy import datasets from torchtext.vocab import Vectors, GloVe, CharNGram, FastText diff --git a/test/translation.py b/test/legacy/translation.py similarity index 94% rename from test/translation.py rename to test/legacy/translation.py index 89a6f9017f..9a0e9a7f2f 100644 --- a/test/translation.py +++ b/test/legacy/translation.py @@ -1,11 +1,11 @@ -from torchtext import data -from torchtext import datasets +from torchtext.legacy import data +from torchtext.legacy import datasets import re import spacy -spacy_de = spacy.load('de_core_news_sm') -spacy_en = spacy.load('en_core_web_sm') +spacy_de = spacy.load('de') +spacy_en = spacy.load('en') url = re.compile('(.*)') diff --git a/test/trec.py b/test/legacy/trec.py similarity index 94% rename from test/trec.py rename to test/legacy/trec.py index ddd20d23a0..43a0c00a08 100644 --- a/test/trec.py +++ b/test/legacy/trec.py @@ -1,5 +1,5 @@ -from torchtext import data -from torchtext import datasets +from torchtext.legacy import data +from torchtext.legacy import datasets from torchtext.vocab import GloVe, CharNGram diff --git a/test/test_build.py b/test/test_build.py index 2e29392562..37d47a6937 100644 --- a/test/test_build.py +++ b/test/test_build.py @@ -11,9 +11,9 @@ class TestNestedField(TorchtextTestCase): def test_build_vocab(self): - nesting_field = torchtext.data.Field(tokenize=list, init_token="", eos_token="") + nesting_field = torchtext.legacy.data.Field(tokenize=list, init_token="", eos_token="") - field = torchtext.data.NestedField( + field = torchtext.legacy.data.NestedField( nesting_field, init_token='', eos_token='', include_lengths=True, pad_first=True) @@ -33,15 +33,15 @@ class TestDataset(TorchtextTestCase): def test_csv_file_no_header_one_col_multiple_fields(self): self.write_test_ppid_dataset(data_format="csv") - question_field = torchtext.data.Field(sequential=True) - spacy_tok_question_field = torchtext.data.Field(sequential=True, tokenize="spacy") - label_field = torchtext.data.Field(sequential=False) + question_field = torchtext.legacy.data.Field(sequential=True) + spacy_tok_question_field = torchtext.legacy.data.Field(sequential=True, tokenize="spacy") + label_field = torchtext.legacy.data.Field(sequential=False) # Field name/value as nested tuples fields = [("ids", None), (("q1", "q1_spacy"), (question_field, spacy_tok_question_field)), (("q2", "q2_spacy"), (question_field, spacy_tok_question_field)), ("label", label_field)] - dataset = torchtext.data.TabularDataset( + dataset = torchtext.legacy.data.TabularDataset( path=self.test_ppid_dataset_path, format="csv", fields=fields) expected_examples = [ (["When", "do", "you", "use", "シ", "instead", "of", "し?"], @@ -70,15 +70,15 @@ def test_csv_file_no_header_one_col_multiple_fields(self): def test_json_dataset_one_key_multiple_fields(self): self.write_test_ppid_dataset(data_format="json") - question_field = torchtext.data.Field(sequential=True) - spacy_tok_question_field = torchtext.data.Field(sequential=True, tokenize="spacy") - label_field = torchtext.data.Field(sequential=False) + question_field = torchtext.legacy.data.Field(sequential=True) + spacy_tok_question_field = torchtext.legacy.data.Field(sequential=True, tokenize="spacy") + label_field = torchtext.legacy.data.Field(sequential=False) fields = {"question1": [("q1", question_field), ("q1_spacy", spacy_tok_question_field)], "question2": [("q2", question_field), ("q2_spacy", spacy_tok_question_field)], "label": ("label", label_field)} - dataset = torchtext.data.TabularDataset( + dataset = torchtext.legacy.data.TabularDataset( path=self.test_ppid_dataset_path, format="json", fields=fields) expected_examples = [ (["When", "do", "you", "use", "シ", "instead", "of", "し?"], diff --git a/torchtext/__init__.py b/torchtext/__init__.py index e7c08bb239..a7477706ef 100644 --- a/torchtext/__init__.py +++ b/torchtext/__init__.py @@ -4,6 +4,7 @@ from . import utils from . import vocab from . import experimental +from . import legacy try: @@ -16,7 +17,8 @@ 'datasets', 'utils', 'vocab', - 'experimental'] + 'experimental', + 'legacy'] def _init_extension(): diff --git a/torchtext/data/__init__.py b/torchtext/data/__init__.py index 20ca10a7a3..9d3483f65b 100644 --- a/torchtext/data/__init__.py +++ b/torchtext/data/__init__.py @@ -2,8 +2,7 @@ from .dataset import Dataset, TabularDataset from .example import Example from .field import RawField, Field, ReversibleField, SubwordField, NestedField, LabelField -from .iterator import (batch, BucketIterator, Iterator, BPTTIterator, - pool) +from .iterator import BucketIterator, Iterator, BPTTIterator from .metrics import bleu_score from .pipeline import Pipeline from .utils import get_tokenizer, interleave_keys @@ -18,8 +17,7 @@ "Example", "RawField", "Field", "ReversibleField", "SubwordField", "NestedField", "LabelField", - "batch", "BucketIterator", "Iterator", "BPTTIterator", - "pool", + "BucketIterator", "Iterator", "BPTTIterator", "bleu_score", "Pipeline", "get_tokenizer", "interleave_keys", diff --git a/torchtext/data/batch.py b/torchtext/data/batch.py index 5a74ce60de..0cdae1ec86 100644 --- a/torchtext/data/batch.py +++ b/torchtext/data/batch.py @@ -1,103 +1,9 @@ -import torch import warnings class Batch(object): - """Defines a batch of examples along with its Fields. - - Attributes: - batch_size: Number of examples in the batch. - dataset: A reference to the dataset object the examples come from - (which itself contains the dataset's Field objects). - train: Deprecated: this attribute is left for backwards compatibility, - however it is UNUSED as of the merger with pytorch 0.4. - input_fields: The names of the fields that are used as input for the model - target_fields: The names of the fields that are used as targets during - model training - - Also stores the Variable for each column in the batch as an attribute. - """ - def __init__(self, data=None, dataset=None, device=None): - """Create a Batch from a list of examples.""" - warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) - if data is not None: - self.batch_size = len(data) - self.dataset = dataset - self.fields = dataset.fields.keys() # copy field names - self.input_fields = [k for k, v in dataset.fields.items() if - v is not None and not v.is_target] - self.target_fields = [k for k, v in dataset.fields.items() if - v is not None and v.is_target] - - for (name, field) in dataset.fields.items(): - if field is not None: - batch = [getattr(x, name) for x in data] - setattr(self, name, field.process(batch, device=device)) - - @classmethod - def fromvars(cls, dataset, batch_size, train=None, **kwargs): - """Create a Batch directly from a number of Variables.""" - batch = cls() - batch.batch_size = batch_size - batch.dataset = dataset - batch.fields = dataset.fields.keys() - for k, v in kwargs.items(): - setattr(batch, k, v) - return batch - - def __repr__(self): - return str(self) - - def __str__(self): - if not self.__dict__: - return 'Empty {} instance'.format(torch.typename(self)) - - fields_to_index = filter(lambda field: field is not None, self.fields) - var_strs = '\n'.join(['\t[.' + name + ']' + ":" + _short_str(getattr(self, name)) - for name in fields_to_index if hasattr(self, name)]) - - data_str = (' from {}'.format(self.dataset.name.upper()) - if hasattr(self.dataset, 'name') - and isinstance(self.dataset.name, str) else '') - - strt = '[{} of size {}{}]\n{}'.format(torch.typename(self), - self.batch_size, data_str, var_strs) - return '\n' + strt - - def __len__(self): - return self.batch_size - - def _get_field_values(self, fields): - if len(fields) == 0: - return None - elif len(fields) == 1: - return getattr(self, fields[0]) - else: - return tuple(getattr(self, f) for f in fields) - - def __iter__(self): - yield self._get_field_values(self.input_fields) - yield self._get_field_values(self.target_fields) - - -def _short_str(tensor): - # unwrap variable to tensor - if not torch.is_tensor(tensor): - # (1) unpack variable - if hasattr(tensor, 'data'): - tensor = getattr(tensor, 'data') - # (2) handle include_lengths - elif isinstance(tensor, tuple): - return str(tuple(_short_str(t) for t in tensor)) - # (3) fallback to default str - else: - return str(tensor) - - # copied from torch _tensor_str - size_str = 'x'.join(str(size) for size in tensor.size()) - device_str = '' if not tensor.is_cuda else \ - ' (GPU {})'.format(tensor.get_device()) - strt = '[{} of size {}{}]'.format(torch.typename(tensor), - size_str, device_str) - return strt + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning diff --git a/torchtext/data/dataset.py b/torchtext/data/dataset.py index eecfc49d9c..5ee7176d73 100644 --- a/torchtext/data/dataset.py +++ b/torchtext/data/dataset.py @@ -1,359 +1,18 @@ -import io -import os -import zipfile -import tarfile -import gzip -import shutil -from functools import partial - import torch.utils.data -from .utils import RandomShuffler -from .example import Example -from ..utils import download_from_url, unicode_csv_reader - class Dataset(torch.utils.data.Dataset): - """Defines a dataset composed of Examples along with its Fields. - - Attributes: - sort_key (callable): A key to use for sorting dataset examples for batching - together examples with similar lengths to minimize padding. - examples (list(Example)): The examples in this dataset. - fields (dict[str, Field]): Contains the name of each column or field, together - with the corresponding Field object. Two fields with the same Field object - will have a shared vocabulary. - """ - sort_key = None - def __init__(self, examples, fields, filter_pred=None): - """Create a dataset from a list of Examples and Fields. - - Args: - examples: List of Examples. - fields (List(tuple(str, Field))): The Fields to use in this tuple. The - string is a field name, and the Field is the associated field. - filter_pred (callable or None): Use only examples for which - filter_pred(example) is True, or use all examples if None. - Default is None. - """ - if filter_pred is not None: - make_list = isinstance(examples, list) - examples = filter(filter_pred, examples) - if make_list: - examples = list(examples) - self.examples = examples - self.fields = dict(fields) - # Unpack field tuples - for n, f in list(self.fields.items()): - if isinstance(n, tuple): - self.fields.update(zip(n, f)) - del self.fields[n] - - @classmethod - def splits(cls, path=None, root='.data', train=None, validation=None, - test=None, **kwargs): - """Create Dataset objects for multiple splits of a dataset. - - Args: - path (str): Common prefix of the splits' file paths, or None to use - the result of cls.download(root). - root (str): Root dataset storage directory. Default is '.data'. - train (str): Suffix to add to path for the train set, or None for no - train set. Default is None. - validation (str): Suffix to add to path for the validation set, or None - for no validation set. Default is None. - test (str): Suffix to add to path for the test set, or None for no test - set. Default is None. - Remaining keyword arguments: Passed to the constructor of the - Dataset (sub)class being used. - - Returns: - Tuple[Dataset]: Datasets for train, validation, and - test splits in that order, if provided. - """ - if path is None: - path = cls.download(root) - train_data = None if train is None else cls( - os.path.join(path, train), **kwargs) - val_data = None if validation is None else cls( - os.path.join(path, validation), **kwargs) - test_data = None if test is None else cls( - os.path.join(path, test), **kwargs) - return tuple(d for d in (train_data, val_data, test_data) - if d is not None) - - def split(self, split_ratio=0.7, stratified=False, strata_field='label', - random_state=None): - """Create train-test(-valid?) splits from the instance's examples. - - Args: - split_ratio (float or List of floats): a number [0, 1] denoting the amount - of data to be used for the training split (rest is used for test), - or a list of numbers denoting the relative sizes of train, test and valid - splits respectively. If the relative size for valid is missing, only the - train-test split is returned. Default is 0.7 (for the train set). - stratified (bool): whether the sampling should be stratified. - Default is False. - strata_field (str): name of the examples Field stratified over. - Default is 'label' for the conventional label field. - random_state (tuple): the random seed used for shuffling. - A return value of `random.getstate()`. - - Returns: - Tuple[Dataset]: Datasets for train, validation, and - test splits in that order, if the splits are provided. - """ - train_ratio, test_ratio, val_ratio = check_split_ratio(split_ratio) - - # For the permutations - rnd = RandomShuffler(random_state) - if not stratified: - train_data, test_data, val_data = rationed_split(self.examples, train_ratio, - test_ratio, val_ratio, rnd) - else: - if strata_field not in self.fields: - raise ValueError("Invalid field name for strata_field {}" - .format(strata_field)) - strata = stratify(self.examples, strata_field) - train_data, test_data, val_data = [], [], [] - for group in strata: - # Stratify each group and add together the indices. - group_train, group_test, group_val = rationed_split(group, train_ratio, - test_ratio, val_ratio, - rnd) - train_data += group_train - test_data += group_test - val_data += group_val - - splits = tuple(Dataset(d, self.fields) - for d in (train_data, val_data, test_data) if d) - - # In case the parent sort key isn't none - if self.sort_key: - for subset in splits: - subset.sort_key = self.sort_key - return splits - - def __getitem__(self, i): - return self.examples[i] - - def __len__(self): - try: - return len(self.examples) - except TypeError: - return 2**32 - - def __iter__(self): - for x in self.examples: - yield x - - def __getattr__(self, attr): - if attr in self.fields: - for x in self.examples: - yield getattr(x, attr) - - @classmethod - def download(cls, root, check=None): - """Download and unzip an online archive (.zip, .gz, or .tgz). - - Args: - root (str): Folder to download data to. - check (str or None): Folder whose existence indicates - that the dataset has already been downloaded, or - None to check the existence of root/{cls.name}. - - Returns: - str: Path to extracted dataset. - """ - path = os.path.join(root, cls.name) - check = path if check is None else check - if not os.path.isdir(check): - for url in cls.urls: - if isinstance(url, tuple): - url, filename = url - else: - filename = os.path.basename(url) - zpath = os.path.join(path, filename) - if not os.path.isfile(zpath): - if not os.path.exists(os.path.dirname(zpath)): - os.makedirs(os.path.dirname(zpath)) - print('downloading {}'.format(filename)) - download_from_url(url, zpath) - zroot, ext = os.path.splitext(zpath) - _, ext_inner = os.path.splitext(zroot) - if ext == '.zip': - with zipfile.ZipFile(zpath, 'r') as zfile: - print('extracting') - zfile.extractall(path) - # tarfile cannot handle bare .gz files - elif ext == '.tgz' or ext == '.gz' and ext_inner == '.tar': - with tarfile.open(zpath, 'r:gz') as tar: - dirs = [member for member in tar.getmembers()] - tar.extractall(path=path, members=dirs) - elif ext == '.gz': - with gzip.open(zpath, 'rb') as gz: - with open(zroot, 'wb') as uncompressed: - shutil.copyfileobj(gz, uncompressed) - - return os.path.join(path, cls.dirname) - - def filter_examples(self, field_names): - """Remove unknown words from dataset examples with respect to given field. - - Args: - field_names (list(str)): Within example only the parts with field names in - field_names will have their unknown words deleted. - """ - for i, example in enumerate(self.examples): - for field_name in field_names: - vocab = set(self.fields[field_name].vocab.stoi) - text = getattr(example, field_name) - example_part = [word for word in text if word in vocab] - setattr(example, field_name, example_part) - self.examples[i] = example + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class TabularDataset(Dataset): - """Defines a Dataset of columns stored in CSV, TSV, or JSON format.""" - def __init__(self, path, format, fields, skip_header=False, csv_reader_params={}, **kwargs): - """Create a TabularDataset given a path, file format, and field list. - - Args: - path (str): Path to the data file. - format (str): The format of the data file. One of "CSV", "TSV", or - "JSON" (case-insensitive). - fields (list(tuple(str, Field)) or dict[str: tuple(str, Field)]: - If using a list, the format must be CSV or TSV, and the values of the list - should be tuples of (name, field). - The fields should be in the same order as the columns in the CSV or TSV - file, while tuples of (name, None) represent columns that will be ignored. - - If using a dict, the keys should be a subset of the JSON keys or CSV/TSV - columns, and the values should be tuples of (name, field). - Keys not present in the input dictionary are ignored. - This allows the user to rename columns from their JSON/CSV/TSV key names - and also enables selecting a subset of columns to load. - skip_header (bool): Whether to skip the first line of the input file. - csv_reader_params(dict): Parameters to pass to the csv reader. - Only relevant when format is csv or tsv. - See - https://docs.python.org/3/library/csv.html#csv.reader - for more details. - """ - format = format.lower() - make_example = { - 'json': Example.fromJSON, 'dict': Example.fromdict, - 'tsv': Example.fromCSV, 'csv': Example.fromCSV}[format] - - with io.open(os.path.expanduser(path), encoding="utf8") as f: - if format == 'csv': - reader = unicode_csv_reader(f, **csv_reader_params) - elif format == 'tsv': - reader = unicode_csv_reader(f, delimiter='\t', **csv_reader_params) - else: - reader = f - - if format in ['csv', 'tsv'] and isinstance(fields, dict): - if skip_header: - raise ValueError('When using a dict to specify fields with a {} file,' - 'skip_header must be False and' - 'the file must have a header.'.format(format)) - header = next(reader) - field_to_index = {f: header.index(f) for f in fields.keys()} - make_example = partial(make_example, field_to_index=field_to_index) - - if skip_header: - next(reader) - - examples = [make_example(line, fields) for line in reader] - - if isinstance(fields, dict): - fields, field_dict = [], fields - for field in field_dict.values(): - if isinstance(field, list): - fields.extend(field) - else: - fields.append(field) - - super(TabularDataset, self).__init__(examples, fields, **kwargs) - - -def check_split_ratio(split_ratio): - """Check that the split ratio argument is not malformed""" - valid_ratio = 0. - if isinstance(split_ratio, float): - # Only the train set relative ratio is provided - # Assert in bounds, validation size is zero - assert 0. < split_ratio < 1., ( - "Split ratio {} not between 0 and 1".format(split_ratio)) - - test_ratio = 1. - split_ratio - return (split_ratio, test_ratio, valid_ratio) - elif isinstance(split_ratio, list): - # A list of relative ratios is provided - length = len(split_ratio) - assert length == 2 or length == 3, ( - "Length of split ratio list should be 2 or 3, got {}".format(split_ratio)) - - # Normalize if necessary - ratio_sum = sum(split_ratio) - if not ratio_sum == 1.: - split_ratio = [float(ratio) / ratio_sum for ratio in split_ratio] - - if length == 2: - return tuple(split_ratio + [valid_ratio]) - return tuple(split_ratio) - else: - raise ValueError('Split ratio must be float or a list, got {}' - .format(type(split_ratio))) - - -def stratify(examples, strata_field): - # The field has to be hashable otherwise this doesn't work - # There's two iterations over the whole dataset here, which can be - # reduced to just one if a dedicated method for stratified splitting is used - unique_strata = set(getattr(example, strata_field) for example in examples) - strata_maps = {s: [] for s in unique_strata} - for example in examples: - strata_maps[getattr(example, strata_field)].append(example) - return list(strata_maps.values()) - - -def rationed_split(examples, train_ratio, test_ratio, val_ratio, rnd): - """Create a random permutation of examples, then split them by ratios - - Args: - examples: a list of data - train_ratio, test_ratio, val_ratio: split fractions. - rnd: a random shuffler - - Examples: - >>> examples = [] - >>> train_ratio, test_ratio, val_ratio = 0.7, 0.2, 0.1 - >>> rnd = torchtext.data.dataset.RandomShuffler(None) - >>> train_examples, test_examples, valid_examples = \ - torchtext.data.dataset.rationed_split(examples, train_ratio, - test_ratio, val_ratio, - rnd) - """ - N = len(examples) - randperm = rnd(range(N)) - train_len = int(round(train_ratio * N)) - - # Due to possible rounding problems - if not val_ratio: - test_len = N - train_len - else: - test_len = int(round(test_ratio * N)) - - indices = (randperm[:train_len], # Train - randperm[train_len:train_len + test_len], # Test - randperm[train_len + test_len:]) # Validation - - # There's a possibly empty list for the validation set - data = tuple([examples[i] for i in index] for index in indices) - - return data + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning diff --git a/torchtext/data/example.py b/torchtext/data/example.py index 8d95a389d0..e7d11f445d 100644 --- a/torchtext/data/example.py +++ b/torchtext/data/example.py @@ -1,105 +1,38 @@ -import json -from functools import reduce import warnings class Example(object): - """Defines a single training or test example. - - Stores each column of the example as an attribute. - """ @classmethod def fromJSON(cls, data, fields): - warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) - ex = cls() - obj = json.loads(data) - - for key, vals in fields.items(): - if vals is not None: - if not isinstance(vals, list): - vals = [vals] - - for val in vals: - # for processing the key likes 'foo.bar' - name, field = val - ks = key.split('.') - - def reducer(obj, key): - if isinstance(obj, list): - results = [] - for data in obj: - if key not in data: - # key error - raise ValueError("Specified key {} was not found in " - "the input data".format(key)) - else: - results.append(data[key]) - return results - else: - # key error - if key not in obj: - raise ValueError("Specified key {} was not found in " - "the input data".format(key)) - else: - return obj[key] - - v = reduce(reducer, ks, obj) - setattr(ex, name, field.preprocess(v)) - return ex + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning @classmethod def fromdict(cls, data, fields): - warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) - ex = cls() - for key, vals in fields.items(): - if key not in data: - raise ValueError("Specified key {} was not found in " - "the input data".format(key)) - if vals is not None: - if not isinstance(vals, list): - vals = [vals] - for val in vals: - name, field = val - setattr(ex, name, field.preprocess(data[key])) - return ex + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning @classmethod def fromCSV(cls, data, fields, field_to_index=None): - warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) - if field_to_index is None: - return cls.fromlist(data, fields) - else: - assert(isinstance(fields, dict)) - data_dict = {f: data[idx] for f, idx in field_to_index.items()} - return cls.fromdict(data_dict, fields) + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning @classmethod def fromlist(cls, data, fields): - warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) - ex = cls() - for (name, field), val in zip(fields, data): - if field is not None: - if isinstance(val, str): - val = val.rstrip('\n') - # Handle field tuples - if isinstance(name, tuple): - for n, f in zip(name, field): - setattr(ex, n, f.preprocess(val)) - else: - setattr(ex, name, field.preprocess(val)) - return ex + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning @classmethod def fromtree(cls, data, fields, subtrees=False): - warnings.warn('Example class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.', UserWarning) - try: - from nltk.tree import Tree - except ImportError: - print("Please install NLTK. " - "See the docs at http://nltk.org for more information.") - raise - tree = Tree.fromstring(data) - if subtrees: - return [cls.fromlist( - [' '.join(t.leaves()), t.label()], fields) for t in tree.subtrees()] - return cls.fromlist([' '.join(tree.leaves()), tree.label()], fields) + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning diff --git a/torchtext/data/field.py b/torchtext/data/field.py index 95be1b85f2..09830605a7 100644 --- a/torchtext/data/field.py +++ b/torchtext/data/field.py @@ -1,145 +1,17 @@ # coding: utf8 -from collections import Counter, OrderedDict -from itertools import chain import torch -from tqdm import tqdm import warnings -from .dataset import Dataset -from .pipeline import Pipeline -from .utils import get_tokenizer, dtype_to_attr, is_tokenizer_serializable -from ..vocab import Vocab, SubwordVocab class RawField(object): - """ Defines a general datatype. - - Every dataset consists of one or more types of data. For instance, a text - classification dataset contains sentences and their classes, while a - machine translation dataset contains paired examples of text in two - languages. Each of these types of data is represented by a RawField object. - A RawField object does not assume any property of the data type and - it holds parameters relating to how a datatype should be processed. - - Attributes: - preprocessing: The Pipeline that will be applied to examples - using this field before creating an example. - Default: None. - postprocessing: A Pipeline that will be applied to a list of examples - using this field before assigning to a batch. - Function signature: (batch(list)) -> object - Default: None. - is_target: Whether this field is a target variable. - Affects iteration over batches. Default: False - """ - def __init__(self, preprocessing=None, postprocessing=None, is_target=False): - warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) - self.preprocessing = preprocessing - self.postprocessing = postprocessing - self.is_target = is_target - - def preprocess(self, x): - """ Preprocess an example if the `preprocessing` Pipeline is provided. """ - if self.preprocessing is not None: - return self.preprocessing(x) - else: - return x - - def process(self, batch, *args, **kwargs): - """ Process a list of examples to create a batch. - - Postprocess the batch with user-provided Pipeline. - - Args: - batch (list(object)): A list of object from a batch of examples. - Returns: - object: Processed object given the input and custom - postprocessing Pipeline. - """ - if self.postprocessing is not None: - batch = self.postprocessing(batch) - return batch + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class Field(RawField): - """Defines a datatype together with instructions for converting to Tensor. - - Field class models common text processing datatypes that can be represented - by tensors. It holds a Vocab object that defines the set of possible values - for elements of the field and their corresponding numerical representations. - The Field object also holds other parameters relating to how a datatype - should be numericalized, such as a tokenization method and the kind of - Tensor that should be produced. - - If a Field is shared between two columns in a dataset (e.g., question and - answer in a QA dataset), then they will have a shared vocabulary. - - Attributes: - sequential: Whether the datatype represents sequential data. If False, - no tokenization is applied. Default: True. - use_vocab: Whether to use a Vocab object. If False, the data in this - field should already be numerical. Default: True. - init_token: A token that will be prepended to every example using this - field, or None for no initial token. Default: None. - eos_token: A token that will be appended to every example using this - field, or None for no end-of-sentence token. Default: None. - fix_length: A fixed length that all examples using this field will be - padded to, or None for flexible sequence lengths. Default: None. - dtype: The torch.dtype class that represents a batch of examples - of this kind of data. Default: torch.long. - preprocessing: The Pipeline that will be applied to examples - using this field after tokenizing but before numericalizing. Many - Datasets replace this attribute with a custom preprocessor. - Default: None. - postprocessing: A Pipeline that will be applied to examples using - this field after numericalizing but before the numbers are turned - into a Tensor. The pipeline function takes the batch as a list, and - the field's Vocab. - Default: None. - lower: Whether to lowercase the text in this field. Default: False. - tokenize: The function used to tokenize strings using this field into - sequential examples. If "spacy", the SpaCy tokenizer is - used. If a non-serializable function is passed as an argument, - the field will not be able to be serialized. Default: string.split. - tokenizer_language: The language of the tokenizer to be constructed. - Various languages currently supported only in SpaCy. - include_lengths: Whether to return a tuple of a padded minibatch and - a list containing the lengths of each examples, or just a padded - minibatch. Default: False. - batch_first: Whether to produce tensors with the batch dimension first. - Default: False. - pad_token: The string token used as padding. Default: "". - unk_token: The string token used to represent OOV words. Default: "". - pad_first: Do the padding of the sequence at the beginning. Default: False. - truncate_first: Do the truncating of the sequence at the beginning. Default: False - stop_words: Tokens to discard during the preprocessing step. Default: None - is_target: Whether this field is a target variable. - Affects iteration over batches. Default: False - """ - - vocab_cls = Vocab - # Dictionary mapping PyTorch tensor dtypes to the appropriate Python - # numeric type. - dtypes = { - torch.float32: float, - torch.float: float, - torch.float64: float, - torch.double: float, - torch.float16: float, - torch.half: float, - - torch.uint8: int, - torch.int8: int, - torch.int16: int, - torch.short: int, - torch.int32: int, - torch.int: int, - torch.int64: int, - torch.long: int, - } - - ignore = ['dtype', 'tokenize'] - def __init__(self, sequential=True, use_vocab=True, init_token=None, eos_token=None, fix_length=None, dtype=torch.long, preprocessing=None, postprocessing=None, lower=False, @@ -147,595 +19,43 @@ def __init__(self, sequential=True, use_vocab=True, init_token=None, batch_first=False, pad_token="", unk_token="", pad_first=False, truncate_first=False, stop_words=None, is_target=False): - warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) - self.sequential = sequential - self.use_vocab = use_vocab - self.init_token = init_token - self.eos_token = eos_token - self.unk_token = unk_token - self.fix_length = fix_length - self.dtype = dtype - self.preprocessing = preprocessing - self.postprocessing = postprocessing - self.lower = lower - # store params to construct tokenizer for serialization - # in case the tokenizer isn't picklable (e.g. spacy) - self.tokenizer_args = (tokenize, tokenizer_language) - self.tokenize = get_tokenizer(tokenize, tokenizer_language) - self.include_lengths = include_lengths - self.batch_first = batch_first - self.pad_token = pad_token if self.sequential else None - self.pad_first = pad_first - self.truncate_first = truncate_first - try: - self.stop_words = set(stop_words) if stop_words is not None else None - except TypeError: - raise ValueError("Stop words must be convertible to a set") - self.is_target = is_target - - def __getstate__(self): - str_type = dtype_to_attr(self.dtype) - if is_tokenizer_serializable(*self.tokenizer_args): - tokenize = self.tokenize - else: - # signal to restore in `__setstate__` - tokenize = None - attrs = {k: v for k, v in self.__dict__.items() if k not in self.ignore} - attrs['dtype'] = str_type - attrs['tokenize'] = tokenize - - return attrs - - def __setstate__(self, state): - state['dtype'] = getattr(torch, state['dtype']) - if not state['tokenize']: - state['tokenize'] = get_tokenizer(*state['tokenizer_args']) - self.__dict__.update(state) - - def __hash__(self): - # we don't expect this to be called often - return 42 - - def __eq__(self, other): - if not isinstance(other, RawField): - return False - - return self.__dict__ == other.__dict__ - - def preprocess(self, x): - """Load a single example using this field, tokenizing if necessary. - - If `sequential=True`, the input will be tokenized. Then the input - will be optionally lowercased and passed to the user-provided - `preprocessing` Pipeline.""" - if self.sequential and isinstance(x, str): - x = self.tokenize(x.rstrip('\n')) - if self.lower: - x = Pipeline(str.lower)(x) - if self.sequential and self.use_vocab and self.stop_words is not None: - x = [w for w in x if w not in self.stop_words] - if self.preprocessing is not None: - return self.preprocessing(x) - else: - return x - - def process(self, batch, device=None): - """ Process a list of examples to create a torch.Tensor. - - Pad, numericalize, and postprocess a batch and create a tensor. - - Args: - batch (list(object)): A list of object from a batch of examples. - Returns: - torch.autograd.Variable: Processed object given the input - and custom postprocessing Pipeline. - """ - padded = self.pad(batch) - tensor = self.numericalize(padded, device=device) - return tensor - - def pad(self, minibatch): - """Pad a batch of examples using this field. - - Pads to self.fix_length if provided, otherwise pads to the length of - the longest example in the batch. Prepends self.init_token and appends - self.eos_token if those attributes are not None. Returns a tuple of the - padded list and a list containing lengths of each example if - `self.include_lengths` is `True` and `self.sequential` is `True`, else just - returns the padded list. If `self.sequential` is `False`, no padding is applied. - """ - minibatch = list(minibatch) - if not self.sequential: - return minibatch - if self.fix_length is None: - max_len = max(len(x) for x in minibatch) - else: - max_len = self.fix_length + ( - self.init_token, self.eos_token).count(None) - 2 - padded, lengths = [], [] - for x in minibatch: - if self.pad_first: - padded.append( - [self.pad_token] * max(0, max_len - len(x)) - + ([] if self.init_token is None else [self.init_token]) - + list(x[-max_len:] if self.truncate_first else x[:max_len]) - + ([] if self.eos_token is None else [self.eos_token])) - else: - padded.append( - ([] if self.init_token is None else [self.init_token]) - + list(x[-max_len:] if self.truncate_first else x[:max_len]) - + ([] if self.eos_token is None else [self.eos_token]) - + [self.pad_token] * max(0, max_len - len(x))) - lengths.append(len(padded[-1]) - max(0, max_len - len(x))) - if self.include_lengths: - return (padded, lengths) - return padded - - def build_vocab(self, *args, **kwargs): - """Construct the Vocab object for this field from one or more datasets. - - Args: - Positional arguments: Dataset objects or other iterable data - sources from which to construct the Vocab object that - represents the set of possible values for this field. If - a Dataset object is provided, all columns corresponding - to this field are used; individual columns can also be - provided directly. - Remaining keyword arguments: Passed to the constructor of Vocab. - """ - counter = Counter() - sources = [] - for arg in args: - if isinstance(arg, Dataset): - sources += [getattr(arg, name) for name, field in - arg.fields.items() if field is self] - else: - sources.append(arg) - for data in sources: - for x in data: - if not self.sequential: - x = [x] - try: - counter.update(x) - except TypeError: - counter.update(chain.from_iterable(x)) - specials = list(OrderedDict.fromkeys( - tok for tok in [self.unk_token, self.pad_token, self.init_token, - self.eos_token] + kwargs.pop('specials', []) - if tok is not None)) - self.vocab = self.vocab_cls(counter, specials=specials, **kwargs) - - def numericalize(self, arr, device=None): - """Turn a batch of examples that use this field into a Variable. - - If the field has include_lengths=True, a tensor of lengths will be - included in the return value. - - Args: - arr (List[List[str]], or tuple of (List[List[str]], List[int])): - List of tokenized and padded examples, or tuple of List of - tokenized and padded examples and List of lengths of each - example if self.include_lengths is True. - device (str or torch.device): A string or instance of `torch.device` - specifying which device the Variables are going to be created on. - If left as default, the tensors will be created on cpu. Default: None. - """ - if self.include_lengths and not isinstance(arr, tuple): - raise ValueError("Field has include_lengths set to True, but " - "input data is not a tuple of " - "(data batch, batch lengths).") - if isinstance(arr, tuple): - arr, lengths = arr - lengths = torch.tensor(lengths, dtype=self.dtype, device=device) - - if self.use_vocab: - if self.sequential: - arr = [[self.vocab.stoi[x] for x in ex] for ex in arr] - else: - arr = [self.vocab.stoi[x] for x in arr] - - if self.postprocessing is not None: - arr = self.postprocessing(arr, self.vocab) - else: - if self.dtype not in self.dtypes: - raise ValueError( - "Specified Field dtype {} can not be used with " - "use_vocab=False because we do not know how to numericalize it. " - "Please raise an issue at " - "https://github.com/pytorch/text/issues".format(self.dtype)) - numericalization_func = self.dtypes[self.dtype] - # It doesn't make sense to explicitly coerce to a numeric type if - # the data is sequential, since it's unclear how to coerce padding tokens - # to a numeric type. - if not self.sequential: - arr = [numericalization_func(x) if isinstance(x, str) - else x for x in arr] - if self.postprocessing is not None: - arr = self.postprocessing(arr, None) - - var = torch.tensor(arr, dtype=self.dtype, device=device) - - if self.sequential and not self.batch_first: - var.t_() - if self.sequential: - var = var.contiguous() - - if self.include_lengths: - return var, lengths - return var + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class ReversibleField(Field): def __init__(self, **kwargs): - warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) - if kwargs.get('tokenize') is list: - self.use_revtok = False - else: - self.use_revtok = True - if kwargs.get('tokenize') is None: - kwargs['tokenize'] = 'revtok' - if 'unk_token' not in kwargs: - kwargs['unk_token'] = ' UNK ' - super(ReversibleField, self).__init__(**kwargs) - - def reverse(self, batch): - if self.use_revtok: - try: - import revtok - except ImportError: - print("Please install revtok.") - raise - if not self.batch_first: - batch = batch.t() - with torch.cuda.device_of(batch): - batch = batch.tolist() - batch = [[self.vocab.itos[ind] for ind in ex] for ex in batch] # denumericalize - - def trim(s, t): - sentence = [] - for w in s: - if w == t: - break - sentence.append(w) - return sentence - - batch = [trim(ex, self.eos_token) for ex in batch] # trim past frst eos - - def filter_special(tok): - return tok not in (self.init_token, self.pad_token) - - batch = [filter(filter_special, ex) for ex in batch] - if self.use_revtok: - return [revtok.detokenize(ex) for ex in batch] - return [''.join(ex) for ex in batch] + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class SubwordField(ReversibleField): - vocab_cls = SubwordVocab - def __init__(self, **kwargs): - warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) - kwargs['tokenize'] = 'subword' - if 'unk_token' not in kwargs: - kwargs['unk_token'] = '�' - super(SubwordField, self).__init__(**kwargs) - - def segment(self, *args): - """Segment one or more datasets with this subword field. - - Args: - Positional arguments: Dataset objects or other indexable - mutable sequences to segment. If a Dataset object is provided, - all columns corresponding to this field are used; individual - columns can also be provided directly. - """ - sources = [] - for arg in args: - if isinstance(arg, Dataset): - sources += [getattr(arg, name) for name, field in - arg.fields.items() if field is self] - else: - sources.append(arg) - for data in sources: - for x in tqdm(data, 'segmenting'): - x[:] = self.vocab.segment(x) + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class NestedField(Field): - """A nested field. - - A nested field holds another field (called *nesting field*), accepts an untokenized - string or a list string tokens and groups and treats them as one field as described - by the nesting field. Every token will be preprocessed, padded, etc. in the manner - specified by the nesting field. Note that this means a nested field always has - ``sequential=True``. The two fields' vocabularies will be shared. Their - numericalization results will be stacked into a single tensor. And NestedField will - share the same include_lengths with nesting_field, so one shouldn't specify the - include_lengths in the nesting_field. This field is - primarily used to implement character embeddings. See ``tests/data/test_field.py`` - for examples on how to use this field. - - Args: - nesting_field (Field): A field contained in this nested field. - use_vocab (bool): Whether to use a Vocab object. If False, the data in this - field should already be numerical. Default: ``True``. - init_token (str): A token that will be prepended to every example using this - field, or None for no initial token. Default: ``None``. - eos_token (str): A token that will be appended to every example using this - field, or None for no end-of-sentence token. Default: ``None``. - fix_length (int): A fixed length that all examples using this field will be - padded to, or ``None`` for flexible sequence lengths. Default: ``None``. - dtype: The torch.dtype class that represents a batch of examples - of this kind of data. Default: ``torch.long``. - preprocessing (Pipeline): The Pipeline that will be applied to examples - using this field after tokenizing but before numericalizing. Many - Datasets replace this attribute with a custom preprocessor. - Default: ``None``. - postprocessing (Pipeline): A Pipeline that will be applied to examples using - this field after numericalizing but before the numbers are turned - into a Tensor. The pipeline function takes the batch as a list, and - the field's Vocab. Default: ``None``. - include_lengths: Whether to return a tuple of a padded minibatch and - a list containing the lengths of each examples, or just a padded - minibatch. Default: False. - tokenize: The function used to tokenize strings using this field into - sequential examples. If "spacy", the SpaCy tokenizer is - used. If a non-serializable function is passed as an argument, - the field will not be able to be serialized. Default: string.split. - tokenizer_language: The language of the tokenizer to be constructed. - Various languages currently supported only in SpaCy. - pad_token (str): The string token used as padding. If ``nesting_field`` is - sequential, this will be set to its ``pad_token``. Default: ``""``. - pad_first (bool): Do the padding of the sequence at the beginning. Default: - ``False``. - """ - def __init__(self, nesting_field, use_vocab=True, init_token=None, eos_token=None, fix_length=None, dtype=torch.long, preprocessing=None, postprocessing=None, tokenize=None, tokenizer_language='en', include_lengths=False, pad_token='', pad_first=False, truncate_first=False): - warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) - if isinstance(nesting_field, NestedField): - raise ValueError('nesting field must not be another NestedField') - if nesting_field.include_lengths: - raise ValueError('nesting field cannot have include_lengths=True') - - if nesting_field.sequential: - pad_token = nesting_field.pad_token - super(NestedField, self).__init__( - use_vocab=use_vocab, - init_token=init_token, - eos_token=eos_token, - fix_length=fix_length, - dtype=dtype, - preprocessing=preprocessing, - postprocessing=postprocessing, - lower=nesting_field.lower, - tokenize=tokenize, - tokenizer_language=tokenizer_language, - batch_first=True, - pad_token=pad_token, - unk_token=nesting_field.unk_token, - pad_first=pad_first, - truncate_first=truncate_first, - include_lengths=include_lengths - ) - self.nesting_field = nesting_field - # in case the user forget to do that - self.nesting_field.batch_first = True - - def preprocess(self, xs): - """Preprocess a single example. - - Firstly, tokenization and the supplied preprocessing pipeline is applied. Since - this field is always sequential, the result is a list. Then, each element of - the list is preprocessed using ``self.nesting_field.preprocess`` and the resulting - list is returned. - - Args: - xs (list or str): The input to preprocess. - - Returns: - list: The preprocessed list. - """ - return [self.nesting_field.preprocess(x) - for x in super(NestedField, self).preprocess(xs)] - - def pad(self, minibatch): - """Pad a batch of examples using this field. - - If ``self.nesting_field.sequential`` is ``False``, each example in the batch must - be a list of string tokens, and pads them as if by a ``Field`` with - ``sequential=True``. Otherwise, each example must be a list of list of tokens. - Using ``self.nesting_field``, pads the list of tokens to - ``self.nesting_field.fix_length`` if provided, or otherwise to the length of the - longest list of tokens in the batch. Next, using this field, pads the result by - filling short examples with ``self.nesting_field.pad_token``. - - Example: - >>> import pprint - >>> pp = pprint.PrettyPrinter(indent=4) - >>> - >>> nesting_field = Field(pad_token='', init_token='', eos_token='') - >>> field = NestedField(nesting_field, init_token='', eos_token='') - >>> minibatch = [ - ... [list('john'), list('loves'), list('mary')], - ... [list('mary'), list('cries')], - ... ] - >>> padded = field.pad(minibatch) - >>> pp.pprint(padded) - [ [ ['', '', '', '', '', '', ''], - ['', 'j', 'o', 'h', 'n', '', ''], - ['', 'l', 'o', 'v', 'e', 's', ''], - ['', 'm', 'a', 'r', 'y', '', ''], - ['', '', '', '', '', '', '']], - [ ['', '', '', '', '', '', ''], - ['', 'm', 'a', 'r', 'y', '', ''], - ['', 'c', 'r', 'i', 'e', 's', ''], - ['', '', '', '', '', '', ''], - ['', '', '', '', '', '', '']]] - - Args: - minibatch (list): Each element is a list of string if - ``self.nesting_field.sequential`` is ``False``, a list of list of string - otherwise. - - Returns: - list: The padded minibatch. or (padded, sentence_lens, word_lengths) - """ - minibatch = list(minibatch) - if not self.nesting_field.sequential: - return super(NestedField, self).pad(minibatch) - - # Save values of attributes to be monkeypatched - old_pad_token = self.pad_token - old_init_token = self.init_token - old_eos_token = self.eos_token - old_fix_len = self.nesting_field.fix_length - # Monkeypatch the attributes - if self.nesting_field.fix_length is None: - max_len = max(len(xs) for ex in minibatch for xs in ex) - fix_len = max_len + 2 - (self.nesting_field.init_token, - self.nesting_field.eos_token).count(None) - self.nesting_field.fix_length = fix_len - self.pad_token = [self.pad_token] * self.nesting_field.fix_length - if self.init_token is not None: - # self.init_token = self.nesting_field.pad([[self.init_token]])[0] - self.init_token = [self.init_token] - if self.eos_token is not None: - # self.eos_token = self.nesting_field.pad([[self.eos_token]])[0] - self.eos_token = [self.eos_token] - # Do padding - old_include_lengths = self.include_lengths - self.include_lengths = True - self.nesting_field.include_lengths = True - padded, sentence_lengths = super(NestedField, self).pad(minibatch) - padded_with_lengths = [self.nesting_field.pad(ex) for ex in padded] - word_lengths = [] - final_padded = [] - max_sen_len = len(padded[0]) - for (pad, lens), sentence_len in zip(padded_with_lengths, sentence_lengths): - if sentence_len == max_sen_len: - lens = lens - pad = pad - elif self.pad_first: - lens[:(max_sen_len - sentence_len)] = ( - [0] * (max_sen_len - sentence_len)) - pad[:(max_sen_len - sentence_len)] = ( - [self.pad_token] * (max_sen_len - sentence_len)) - else: - lens[-(max_sen_len - sentence_len):] = ( - [0] * (max_sen_len - sentence_len)) - pad[-(max_sen_len - sentence_len):] = ( - [self.pad_token] * (max_sen_len - sentence_len)) - word_lengths.append(lens) - final_padded.append(pad) - padded = final_padded - - # Restore monkeypatched attributes - self.nesting_field.fix_length = old_fix_len - self.pad_token = old_pad_token - self.init_token = old_init_token - self.eos_token = old_eos_token - self.include_lengths = old_include_lengths - if self.include_lengths: - return padded, sentence_lengths, word_lengths - return padded - - def build_vocab(self, *args, **kwargs): - """Construct the Vocab object for nesting field and combine it with this field's vocab. - - Args: - Positional arguments: Dataset objects or other iterable data - sources from which to construct the Vocab object that - represents the set of possible values for the nesting field. If - a Dataset object is provided, all columns corresponding - to this field are used; individual columns can also be - provided directly. - Remaining keyword arguments: Passed to the constructor of Vocab. - """ - sources = [] - for arg in args: - if isinstance(arg, Dataset): - sources.extend( - [getattr(arg, name) for name, field in arg.fields.items() - if field is self] - ) - else: - sources.append(arg) - - flattened = [] - for source in sources: - flattened.extend(source) - old_vectors = None - old_unk_init = None - old_vectors_cache = None - if "vectors" in kwargs.keys(): - old_vectors = kwargs["vectors"] - kwargs["vectors"] = None - if "unk_init" in kwargs.keys(): - old_unk_init = kwargs["unk_init"] - kwargs["unk_init"] = None - if "vectors_cache" in kwargs.keys(): - old_vectors_cache = kwargs["vectors_cache"] - kwargs["vectors_cache"] = None - # just build vocab and does not load vector - self.nesting_field.build_vocab(*flattened, **kwargs) - super(NestedField, self).build_vocab() - self.vocab.extend(self.nesting_field.vocab) - self.vocab.freqs = self.nesting_field.vocab.freqs.copy() - if old_vectors is not None: - self.vocab.load_vectors(old_vectors, - unk_init=old_unk_init, cache=old_vectors_cache) - - self.nesting_field.vocab = self.vocab - - def numericalize(self, arrs, device=None): - """Convert a padded minibatch into a variable tensor. - - Each item in the minibatch will be numericalized independently and the resulting - tensors will be stacked at the first dimension. - - Args: - arr (List[List[str]]): List of tokenized and padded examples. - device (str or torch.device): A string or instance of `torch.device` - specifying which device the Variables are going to be created on. - If left as default, the tensors will be created on cpu. Default: None. - """ - numericalized = [] - self.nesting_field.include_lengths = False - if self.include_lengths: - arrs, sentence_lengths, word_lengths = arrs - - for arr in arrs: - numericalized_ex = self.nesting_field.numericalize( - arr, device=device) - numericalized.append(numericalized_ex) - padded_batch = torch.stack(numericalized) - - self.nesting_field.include_lengths = True - if self.include_lengths: - sentence_lengths = \ - torch.tensor(sentence_lengths, dtype=self.dtype, device=device) - word_lengths = torch.tensor(word_lengths, dtype=self.dtype, device=device) - return (padded_batch, sentence_lengths, word_lengths) - return padded_batch + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class LabelField(Field): - """A Label field. - - A label field is a shallow wrapper around a standard field designed to hold labels - for a classification task. Its only use is to set the unk_token and sequential to - `None` by default. - """ - def __init__(self, **kwargs): - # whichever value is set for sequential, unk_token, and is_target - # will be overwritten - kwargs['sequential'] = False - kwargs['unk_token'] = None - kwargs['is_target'] = True - - super(LabelField, self).__init__(**kwargs) + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py index 3dfa807138..e1ff1ab93c 100644 --- a/torchtext/data/iterator.py +++ b/torchtext/data/iterator.py @@ -1,299 +1,31 @@ -import math -import random - import logging import warnings -import torch -from .utils import RandomShuffler -from .batch import Batch -from .dataset import Dataset logger = logging.getLogger(__name__) class Iterator(object): - """Defines an iterator that loads batches of data from a Dataset. - - Attributes: - dataset: The Dataset object to load Examples from. - batch_size: Batch size. - batch_size_fn: Function of three arguments (new example to add, current - count of examples in the batch, and current effective batch size) - that returns the new effective batch size resulting from adding - that example to a batch. This is useful for dynamic batching, where - this function would add to the current effective batch size the - number of tokens in the new example. - sort_key: A key to use for sorting examples in order to batch together - examples with similar lengths and minimize padding. The sort_key - provided to the Iterator constructor overrides the sort_key - attribute of the Dataset, or defers to it if None. - train: Whether the iterator represents a train set. - repeat: Whether to repeat the iterator for multiple epochs. Default: False. - shuffle: Whether to shuffle examples between epochs. - sort: Whether to sort examples according to self.sort_key. - Note that shuffle and sort default to train and (not train). - sort_within_batch: Whether to sort (in descending order according to - self.sort_key) within each batch. If None, defaults to self.sort. - If self.sort is True and this is False, the batch is left in the - original (ascending) sorted order. - device (str or `torch.device`): A string or instance of `torch.device` - specifying which device the Variables are going to be created on. - If left as default, the tensors will be created on cpu. Default: None. - """ - def __init__(self, dataset, batch_size, sort_key=None, device=None, batch_size_fn=None, train=True, repeat=False, shuffle=None, sort=None, sort_within_batch=None): - warnings.warn('{} class will be retired soon and moved to torchtext.legacy. Please see the most recent release notes for further information.'.format(self.__class__.__name__), UserWarning) - self.batch_size, self.train, self.dataset = batch_size, train, dataset - self.batch_size_fn = batch_size_fn - self.iterations = 0 - self.repeat = repeat - self.shuffle = train if shuffle is None else shuffle - self.sort = not train if sort is None else sort - - if sort_within_batch is None: - self.sort_within_batch = self.sort - else: - self.sort_within_batch = sort_within_batch - if sort_key is None: - self.sort_key = dataset.sort_key - else: - self.sort_key = sort_key - - if isinstance(device, int): - logger.warning("The `device` argument should be set by using `torch.device`" - + " or passing a string as an argument. This behavior will be" - + " deprecated soon and currently defaults to cpu.") - device = None - - if device is None: - device = torch.device('cpu') - elif isinstance(device, str): - device = torch.device(device) - - self.device = device - self.random_shuffler = RandomShuffler() - - # For state loading/saving only - self._iterations_this_epoch = 0 - self._random_state_this_epoch = None - self._restored_from_state = False - - @classmethod - def splits(cls, datasets, batch_sizes=None, **kwargs): - """Create Iterator objects for multiple splits of a dataset. - - Args: - datasets: Tuple of Dataset objects corresponding to the splits. The - first such object should be the train set. - batch_sizes: Tuple of batch sizes to use for the different splits, - or None to use the same batch_size for all splits. - Remaining keyword arguments: Passed to the constructor of the - iterator class being used. - """ - if batch_sizes is None: - batch_sizes = [kwargs.pop('batch_size')] * len(datasets) - ret = [] - for i in range(len(datasets)): - train = i == 0 - ret.append(cls( - datasets[i], batch_size=batch_sizes[i], train=train, **kwargs)) - return tuple(ret) - - def data(self): - """Return the examples in the dataset in order, sorted, or shuffled.""" - if self.sort: - xs = sorted(self.dataset, key=self.sort_key) - elif self.shuffle: - xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))] - else: - xs = self.dataset - return xs - - def init_epoch(self): - """Set up the batch generator for a new epoch.""" - - if self._restored_from_state: - self.random_shuffler.random_state = self._random_state_this_epoch - else: - self._random_state_this_epoch = self.random_shuffler.random_state - - self.create_batches() - - if self._restored_from_state: - self._restored_from_state = False - else: - self._iterations_this_epoch = 0 - - if not self.repeat: - self.iterations = 0 - - def create_batches(self): - self.batches = batch(self.data(), self.batch_size, self.batch_size_fn) - - @property - def epoch(self): - return math.floor(self.iterations / len(self)) - - def __len__(self): - if self.batch_size_fn is not None: - raise NotImplementedError - return math.ceil(len(self.dataset) / self.batch_size) - - def __iter__(self): - while True: - self.init_epoch() - for idx, minibatch in enumerate(self.batches): - # fast-forward if loaded from state - if self._iterations_this_epoch > idx: - continue - self.iterations += 1 - self._iterations_this_epoch += 1 - if self.sort_within_batch: - # NOTE: `rnn.pack_padded_sequence` requires that a minibatch - # be sorted by decreasing order, which requires reversing - # relative to typical sort keys - if self.sort: - minibatch.reverse() - else: - minibatch.sort(key=self.sort_key, reverse=True) - yield Batch(minibatch, self.dataset, self.device) - if not self.repeat: - return - - def state_dict(self): - return { - "iterations": self.iterations, - "iterations_this_epoch": self._iterations_this_epoch, - "random_state_this_epoch": self._random_state_this_epoch} - - def load_state_dict(self, state_dict): - self.iterations = state_dict["iterations"] - self._iterations_this_epoch = state_dict["iterations_this_epoch"] - self._random_state_this_epoch = state_dict["random_state_this_epoch"] - self._restored_from_state = True + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class BPTTIterator(Iterator): - """Defines an iterator for language modeling tasks that use BPTT. - - Provides contiguous streams of examples together with targets that are - one timestep further forward, for language modeling training with - backpropagation through time (BPTT). Expects a Dataset with a single - example and a single field called 'text' and produces Batches with text and - target attributes. - - Attributes: - dataset: The Dataset object to load Examples from. - batch_size: Batch size. - bptt_len: Length of sequences for backpropagation through time. - sort_key: A key to use for sorting examples in order to batch together - examples with similar lengths and minimize padding. The sort_key - provided to the Iterator constructor overrides the sort_key - attribute of the Dataset, or defers to it if None. - train: Whether the iterator represents a train set. - repeat: Whether to repeat the iterator for multiple epochs. Default: False. - shuffle: Whether to shuffle examples between epochs. - sort: Whether to sort examples according to self.sort_key. - Note that shuffle and sort default to train and (not train). - device (str or torch.device): A string or instance of `torch.device` - specifying which device the Variables are going to be created on. - If left as default, the tensors will be created on cpu. Default: None. - """ - def __init__(self, dataset, batch_size, bptt_len, **kwargs): - self.bptt_len = bptt_len - super(BPTTIterator, self).__init__(dataset, batch_size, **kwargs) - - def __len__(self): - return math.ceil((len(self.dataset[0].text) / self.batch_size - 1) - / self.bptt_len) - - def __iter__(self): - text = self.dataset[0].text - TEXT = self.dataset.fields['text'] - TEXT.eos_token = None - text = text + ([TEXT.pad_token] * int(math.ceil(len(text) / self.batch_size) - * self.batch_size - len(text))) - data = TEXT.numericalize( - [text], device=self.device) - data = data.view(self.batch_size, -1).t().contiguous() - dataset = Dataset(examples=self.dataset.examples, fields=[ - ('text', TEXT), ('target', TEXT)]) - while True: - for i in range(0, len(self) * self.bptt_len, self.bptt_len): - self.iterations += 1 - seq_len = min(self.bptt_len, len(data) - i - 1) - batch_text = data[i:i + seq_len] - batch_target = data[i + 1:i + 1 + seq_len] - if TEXT.batch_first: - batch_text = batch_text.t().contiguous() - batch_target = batch_target.t().contiguous() - yield Batch.fromvars( - dataset, self.batch_size, - text=batch_text, - target=batch_target) - if not self.repeat: - return + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning class BucketIterator(Iterator): - """Defines an iterator that batches examples of similar lengths together. - - Minimizes amount of padding needed while producing freshly shuffled - batches for each new epoch. See pool for the bucketing procedure used. - """ - def create_batches(self): - if self.sort: - self.batches = batch(self.data(), self.batch_size, - self.batch_size_fn) - else: - self.batches = pool(self.data(), self.batch_size, - self.sort_key, self.batch_size_fn, - random_shuffler=self.random_shuffler, - shuffle=self.shuffle, - sort_within_batch=self.sort_within_batch) - - -def batch(data, batch_size, batch_size_fn=None): - """Yield elements from data in chunks of batch_size.""" - if batch_size_fn is None: - def batch_size_fn(new, count, sofar): - return count - minibatch, size_so_far = [], 0 - for ex in data: - minibatch.append(ex) - size_so_far = batch_size_fn(ex, len(minibatch), size_so_far) - if size_so_far == batch_size: - yield minibatch - minibatch, size_so_far = [], 0 - elif size_so_far > batch_size: - yield minibatch[:-1] - minibatch, size_so_far = minibatch[-1:], batch_size_fn(ex, 1, 0) - if minibatch: - yield minibatch - - -def pool(data, batch_size, key, batch_size_fn=lambda new, count, sofar: count, - random_shuffler=None, shuffle=False, sort_within_batch=False): - """Sort within buckets, then batch, then shuffle batches. - - Partitions data into chunks of size 100*batch_size, sorts examples within - each chunk using sort_key, then batch these examples and shuffle the - batches. - """ - if random_shuffler is None: - random_shuffler = random.shuffle - for p in batch(data, batch_size * 100, batch_size_fn): - p_batch = batch(sorted(p, key=key), batch_size, batch_size_fn) \ - if sort_within_batch \ - else batch(p, batch_size, batch_size_fn) - if shuffle: - for b in random_shuffler(list(p_batch)): - yield b - else: - for b in list(p_batch): - yield b + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning diff --git a/torchtext/data/pipeline.py b/torchtext/data/pipeline.py index d72ef5ef4c..78f826c82c 100644 --- a/torchtext/data/pipeline.py +++ b/torchtext/data/pipeline.py @@ -1,85 +1,6 @@ class Pipeline(object): - """Defines a pipeline for transforming sequence data. - - The input is assumed to be utf-8 encoded `str`. - - Attributes: - convert_token: The function to apply to input sequence data. - pipes: The Pipelines that will be applied to input sequence - data in order. - """ - def __init__(self, convert_token=None): - """Create a pipeline. - - Args: - convert_token: The function to apply to input sequence data. - If None, the identity function is used. Default: None - """ - if convert_token is None: - self.convert_token = Pipeline.identity - elif callable(convert_token): - self.convert_token = convert_token - else: - raise ValueError("Pipeline input convert_token {} is not None " - "or callable".format(convert_token)) - self.pipes = [self] - - def __call__(self, x, *args): - """Apply the the current Pipeline(s) to an input. - - Args: - x: The input to process with the Pipeline(s). - Positional arguments: Forwarded to the `call` function - of the Pipeline(s). - """ - for pipe in self.pipes: - x = pipe.call(x, *args) - return x - - def call(self, x, *args): - """Apply _only_ the convert_token function of the current pipeline - to the input. If the input is a list, a list with the results of - applying the `convert_token` function to all input elements is - returned. - - Args: - x: The input to apply the convert_token function to. - Positional arguments: Forwarded to the `convert_token` function - of the current Pipeline. - """ - if isinstance(x, list): - return [self.convert_token(tok, *args) for tok in x] - return self.convert_token(x, *args) - - def add_before(self, pipeline): - """Add a Pipeline to be applied before this processing pipeline. - - Args: - pipeline: The Pipeline or callable to apply before this - Pipeline. - """ - if not isinstance(pipeline, Pipeline): - pipeline = Pipeline(pipeline) - self.pipes = pipeline.pipes[:] + self.pipes[:] - return self - - def add_after(self, pipeline): - """Add a Pipeline to be applied after this processing pipeline. - - Args: - pipeline: The Pipeline or callable to apply after this - Pipeline. - """ - if not isinstance(pipeline, Pipeline): - pipeline = Pipeline(pipeline) - self.pipes = self.pipes[:] + pipeline.pipes[:] - return self - - @staticmethod - def identity(x): - """Return a copy of the input. - - This is here for serialization compatibility with pickle. - """ - return x + warnings.warn('{} class has '.format(self.__class__.__name__) + + 'been retired and moved to torchtext.legacy. Please ' + + 'import from torchtext.legacy.data if you still want it.', UserWarning) + raise ImportWarning diff --git a/torchtext/datasets/__init__.py b/torchtext/datasets/__init__.py index 5eced837a5..e69de29bb2 100644 --- a/torchtext/datasets/__init__.py +++ b/torchtext/datasets/__init__.py @@ -1,42 +0,0 @@ -from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank # NOQA -from .nli import SNLI, MultiNLI, XNLI -from .sst import SST -from .translation import TranslationDataset, Multi30k, IWSLT, WMT14 # NOQA -from .sequence_tagging import SequenceTaggingDataset, UDPOS, CoNLL2000Chunking # NOQA -from .trec import TREC -from .imdb import IMDB -from .babi import BABI20 -from .text_classification import TextClassificationDataset, \ - AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ - YelpReviewFull, YahooAnswers, \ - AmazonReviewPolarity, AmazonReviewFull -from .unsupervised_learning import EnWik9 - -__all__ = ['LanguageModelingDataset', - 'SNLI', - 'MultiNLI', - 'XNLI', - 'SST', - 'TranslationDataset', - 'Multi30k', - 'IWSLT', - 'WMT14', - 'WikiText2', - 'WikiText103', - 'PennTreebank', - 'TREC', - 'IMDB', - 'SequenceTaggingDataset', - 'UDPOS', - 'CoNLL2000Chunking', - 'BABI20', - 'TextClassificationDataset', - 'AG_NEWS', - 'SogouNews', - 'DBpedia', - 'YelpReviewPolarity', - 'YelpReviewFull', - 'YahooAnswers', - 'AmazonReviewPolarity', - 'AmazonReviewFull', - 'EnWik9'] diff --git a/torchtext/legacy/__init__.py b/torchtext/legacy/__init__.py new file mode 100644 index 0000000000..686bf47f2b --- /dev/null +++ b/torchtext/legacy/__init__.py @@ -0,0 +1,6 @@ +from . import data +from . import datasets + + +__all__ = ['data', + 'datasets'] diff --git a/torchtext/legacy/data/__init__.py b/torchtext/legacy/data/__init__.py new file mode 100644 index 0000000000..aa8150ede1 --- /dev/null +++ b/torchtext/legacy/data/__init__.py @@ -0,0 +1,14 @@ +from .batch import Batch +from .example import Example +from .field import RawField, Field, ReversibleField, SubwordField, NestedField, LabelField +from .iterator import (batch, BucketIterator, Iterator, BPTTIterator, pool) +from .pipeline import Pipeline +from .dataset import Dataset, TabularDataset + +__all__ = ["Batch", + "Example", + "RawField", "Field", "ReversibleField", "SubwordField", "NestedField", + "LabelField", + "batch", "BucketIterator", "Iterator", "BPTTIterator", "pool", + "Pipeline", + "Dataset", "TabularDataset"] diff --git a/torchtext/legacy/data/batch.py b/torchtext/legacy/data/batch.py new file mode 100644 index 0000000000..3e4250d29f --- /dev/null +++ b/torchtext/legacy/data/batch.py @@ -0,0 +1,101 @@ +import torch + + +class Batch(object): + """Defines a batch of examples along with its Fields. + + Attributes: + batch_size: Number of examples in the batch. + dataset: A reference to the dataset object the examples come from + (which itself contains the dataset's Field objects). + train: Deprecated: this attribute is left for backwards compatibility, + however it is UNUSED as of the merger with pytorch 0.4. + input_fields: The names of the fields that are used as input for the model + target_fields: The names of the fields that are used as targets during + model training + + Also stores the Variable for each column in the batch as an attribute. + """ + + def __init__(self, data=None, dataset=None, device=None): + """Create a Batch from a list of examples.""" + if data is not None: + self.batch_size = len(data) + self.dataset = dataset + self.fields = dataset.fields.keys() # copy field names + self.input_fields = [k for k, v in dataset.fields.items() if + v is not None and not v.is_target] + self.target_fields = [k for k, v in dataset.fields.items() if + v is not None and v.is_target] + + for (name, field) in dataset.fields.items(): + if field is not None: + batch = [getattr(x, name) for x in data] + setattr(self, name, field.process(batch, device=device)) + + @classmethod + def fromvars(cls, dataset, batch_size, train=None, **kwargs): + """Create a Batch directly from a number of Variables.""" + batch = cls() + batch.batch_size = batch_size + batch.dataset = dataset + batch.fields = dataset.fields.keys() + for k, v in kwargs.items(): + setattr(batch, k, v) + return batch + + def __repr__(self): + return str(self) + + def __str__(self): + if not self.__dict__: + return 'Empty {} instance'.format(torch.typename(self)) + + fields_to_index = filter(lambda field: field is not None, self.fields) + var_strs = '\n'.join(['\t[.' + name + ']' + ":" + _short_str(getattr(self, name)) + for name in fields_to_index if hasattr(self, name)]) + + data_str = (' from {}'.format(self.dataset.name.upper()) + if hasattr(self.dataset, 'name') + and isinstance(self.dataset.name, str) else '') + + strt = '[{} of size {}{}]\n{}'.format(torch.typename(self), + self.batch_size, data_str, var_strs) + return '\n' + strt + + def __len__(self): + return self.batch_size + + def _get_field_values(self, fields): + if len(fields) == 0: + return None + elif len(fields) == 1: + return getattr(self, fields[0]) + else: + return tuple(getattr(self, f) for f in fields) + + def __iter__(self): + yield self._get_field_values(self.input_fields) + yield self._get_field_values(self.target_fields) + + +def _short_str(tensor): + # unwrap variable to tensor + if not torch.is_tensor(tensor): + # (1) unpack variable + if hasattr(tensor, 'data'): + tensor = tensor.data + # (2) handle include_lengths + elif isinstance(tensor, tuple): + return str(tuple(_short_str(t) for t in tensor)) + # (3) fallback to default str + else: + return str(tensor) + + # copied from torch _tensor_str + size_str = 'x'.join(str(size) for size in tensor.size()) + device_str = '' if not tensor.is_cuda else \ + ' (GPU {})'.format(tensor.get_device()) + strt = '[{} of size {}{}]'.format(torch.typename(tensor), + size_str, device_str) + return strt diff --git a/torchtext/legacy/data/dataset.py b/torchtext/legacy/data/dataset.py new file mode 100644 index 0000000000..d4da009c81 --- /dev/null +++ b/torchtext/legacy/data/dataset.py @@ -0,0 +1,361 @@ +import io +import os +import zipfile +import tarfile +import gzip +import shutil +from functools import partial + +import torch.utils.data + +from torchtext.data.utils import RandomShuffler +from .example import Example +from torchtext.utils import download_from_url, unicode_csv_reader + + +class Dataset(torch.utils.data.Dataset): + """Defines a dataset composed of Examples along with its Fields. + + Attributes: + sort_key (callable): A key to use for sorting dataset examples for batching + together examples with similar lengths to minimize padding. + examples (list(Example)): The examples in this dataset. + fields (dict[str, Field]): Contains the name of each column or field, together + with the corresponding Field object. Two fields with the same Field object + will have a shared vocabulary. + """ + sort_key = None + + def __init__(self, examples, fields, filter_pred=None): + """Create a dataset from a list of Examples and Fields. + + Arguments: + examples: List of Examples. + fields (List(tuple(str, Field))): The Fields to use in this tuple. The + string is a field name, and the Field is the associated field. + filter_pred (callable or None): Use only examples for which + filter_pred(example) is True, or use all examples if None. + Default is None. + """ + if filter_pred is not None: + make_list = isinstance(examples, list) + examples = filter(filter_pred, examples) + if make_list: + examples = list(examples) + self.examples = examples + self.fields = dict(fields) + # Unpack field tuples + for n, f in list(self.fields.items()): + if isinstance(n, tuple): + self.fields.update(zip(n, f)) + del self.fields[n] + + @classmethod + def splits(cls, path=None, root='.data', train=None, validation=None, + test=None, **kwargs): + """Create Dataset objects for multiple splits of a dataset. + + Arguments: + path (str): Common prefix of the splits' file paths, or None to use + the result of cls.download(root). + root (str): Root dataset storage directory. Default is '.data'. + train (str): Suffix to add to path for the train set, or None for no + train set. Default is None. + validation (str): Suffix to add to path for the validation set, or None + for no validation set. Default is None. + test (str): Suffix to add to path for the test set, or None for no test + set. Default is None. + Remaining keyword arguments: Passed to the constructor of the + Dataset (sub)class being used. + + Returns: + Tuple[Dataset]: Datasets for train, validation, and + test splits in that order, if provided. + """ + if path is None: + path = cls.download(root) + train_data = None if train is None else cls( + os.path.join(path, train), **kwargs) + val_data = None if validation is None else cls( + os.path.join(path, validation), **kwargs) + test_data = None if test is None else cls( + os.path.join(path, test), **kwargs) + return tuple(d for d in (train_data, val_data, test_data) + if d is not None) + + def split(self, split_ratio=0.7, stratified=False, strata_field='label', + random_state=None): + """Create train-test(-valid?) splits from the instance's examples. + + Arguments: + split_ratio (float or List of floats): a number [0, 1] denoting the amount + of data to be used for the training split (rest is used for test), + or a list of numbers denoting the relative sizes of train, test and valid + splits respectively. If the relative size for valid is missing, only the + train-test split is returned. Default is 0.7 (for the train set). + stratified (bool): whether the sampling should be stratified. + Default is False. + strata_field (str): name of the examples Field stratified over. + Default is 'label' for the conventional label field. + random_state (tuple): the random seed used for shuffling. + A return value of `random.getstate()`. + + Returns: + Tuple[Dataset]: Datasets for train, validation, and + test splits in that order, if the splits are provided. + """ + train_ratio, test_ratio, val_ratio = check_split_ratio(split_ratio) + + # For the permutations + rnd = RandomShuffler(random_state) + if not stratified: + train_data, test_data, val_data = rationed_split(self.examples, train_ratio, + test_ratio, val_ratio, rnd) + else: + if strata_field not in self.fields: + raise ValueError("Invalid field name for strata_field {}" + .format(strata_field)) + strata = stratify(self.examples, strata_field) + train_data, test_data, val_data = [], [], [] + for group in strata: + # Stratify each group and add together the indices. + group_train, group_test, group_val = rationed_split(group, train_ratio, + test_ratio, val_ratio, + rnd) + train_data += group_train + test_data += group_test + val_data += group_val + + splits = tuple(Dataset(d, self.fields) + for d in (train_data, val_data, test_data) if d) + + # In case the parent sort key isn't none + if self.sort_key: + for subset in splits: + subset.sort_key = self.sort_key + return splits + + def __getitem__(self, i): + return self.examples[i] + + def __len__(self): + try: + return len(self.examples) + except TypeError: + return 2**32 + + def __iter__(self): + for x in self.examples: + yield x + + def __getattr__(self, attr): + if attr in self.fields: + for x in self.examples: + yield getattr(x, attr) + + @classmethod + def download(cls, root, check=None): + """Download and unzip an online archive (.zip, .gz, or .tgz). + + Arguments: + root (str): Folder to download data to. + check (str or None): Folder whose existence indicates + that the dataset has already been downloaded, or + None to check the existence of root/{cls.name}. + + Returns: + str: Path to extracted dataset. + """ + path = os.path.join(root, cls.name) + check = path if check is None else check + if not os.path.isdir(check): + for url in cls.urls: + if isinstance(url, tuple): + url, filename = url + else: + filename = os.path.basename(url) + zpath = os.path.join(path, filename) + if not os.path.isfile(zpath): + if not os.path.exists(os.path.dirname(zpath)): + os.makedirs(os.path.dirname(zpath)) + print('downloading {}'.format(filename)) + download_from_url(url, zpath) + zroot, ext = os.path.splitext(zpath) + _, ext_inner = os.path.splitext(zroot) + if ext == '.zip': + with zipfile.ZipFile(zpath, 'r') as zfile: + print('extracting') + zfile.extractall(path) + # tarfile cannot handle bare .gz files + elif ext == '.tgz' or ext == '.gz' and ext_inner == '.tar': + with tarfile.open(zpath, 'r:gz') as tar: + dirs = [member for member in tar.getmembers()] + tar.extractall(path=path, members=dirs) + elif ext == '.gz': + with gzip.open(zpath, 'rb') as gz: + with open(zroot, 'wb') as uncompressed: + shutil.copyfileobj(gz, uncompressed) + + return os.path.join(path, cls.dirname) + + def filter_examples(self, field_names): + """Remove unknown words from dataset examples with respect to given field. + + Arguments: + field_names (list(str)): Within example only the parts with field names in + field_names will have their unknown words deleted. + """ + for i, example in enumerate(self.examples): + for field_name in field_names: + vocab = set(self.fields[field_name].vocab.stoi) + text = getattr(example, field_name) + example_part = [word for word in text if word in vocab] + setattr(example, field_name, example_part) + self.examples[i] = example + + +class TabularDataset(Dataset): + """Defines a Dataset of columns stored in CSV, TSV, or JSON format.""" + + def __init__(self, path, format, fields, skip_header=False, + csv_reader_params=None, **kwargs): + """Create a TabularDataset given a path, file format, and field list. + + Arguments: + path (str): Path to the data file. + format (str): The format of the data file. One of "CSV", "TSV", or + "JSON" (case-insensitive). + fields (list(tuple(str, Field)) or dict[str: tuple(str, Field)]: + If using a list, the format must be CSV or TSV, and the values of the list + should be tuples of (name, field). + The fields should be in the same order as the columns in the CSV or TSV + file, while tuples of (name, None) represent columns that will be ignored. + + If using a dict, the keys should be a subset of the JSON keys or CSV/TSV + columns, and the values should be tuples of (name, field). + Keys not present in the input dictionary are ignored. + This allows the user to rename columns from their JSON/CSV/TSV key names + and also enables selecting a subset of columns to load. + skip_header (bool): Whether to skip the first line of the input file. + csv_reader_params(dict): Parameters to pass to the csv reader. + Only relevant when format is csv or tsv. + See + https://docs.python.org/3/library/csv.html#csv.reader + for more details. + """ + if csv_reader_params is None: + csv_reader_params = {} + format = format.lower() + make_example = { + 'json': Example.fromJSON, 'dict': Example.fromdict, + 'tsv': Example.fromCSV, 'csv': Example.fromCSV}[format] + + with io.open(os.path.expanduser(path), encoding="utf8") as f: + if format == 'csv': + reader = unicode_csv_reader(f, **csv_reader_params) + elif format == 'tsv': + reader = unicode_csv_reader(f, delimiter='\t', **csv_reader_params) + else: + reader = f + + if format in ['csv', 'tsv'] and isinstance(fields, dict): + if skip_header: + raise ValueError('When using a dict to specify fields with a {} file,' + 'skip_header must be False and' + 'the file must have a header.'.format(format)) + header = next(reader) + field_to_index = {f: header.index(f) for f in fields.keys()} + make_example = partial(make_example, field_to_index=field_to_index) + + if skip_header: + next(reader) + + examples = [make_example(line, fields) for line in reader] + + if isinstance(fields, dict): + fields, field_dict = [], fields + for field in field_dict.values(): + if isinstance(field, list): + fields.extend(field) + else: + fields.append(field) + + super(TabularDataset, self).__init__(examples, fields, **kwargs) + + +def check_split_ratio(split_ratio): + """Check that the split ratio argument is not malformed""" + valid_ratio = 0. + if isinstance(split_ratio, float): + # Only the train set relative ratio is provided + # Assert in bounds, validation size is zero + assert 0. < split_ratio < 1., ( + "Split ratio {} not between 0 and 1".format(split_ratio)) + + test_ratio = 1. - split_ratio + return (split_ratio, test_ratio, valid_ratio) + elif isinstance(split_ratio, list): + # A list of relative ratios is provided + length = len(split_ratio) + assert length == 2 or length == 3, ( + "Length of split ratio list should be 2 or 3, got {}".format(split_ratio)) + + # Normalize if necessary + ratio_sum = sum(split_ratio) + if not ratio_sum == 1.: + split_ratio = [float(ratio) / ratio_sum for ratio in split_ratio] + + if length == 2: + return tuple(split_ratio + [valid_ratio]) + return tuple(split_ratio) + else: + raise ValueError('Split ratio must be float or a list, got {}' + .format(type(split_ratio))) + + +def stratify(examples, strata_field): + # The field has to be hashable otherwise this doesn't work + # There's two iterations over the whole dataset here, which can be + # reduced to just one if a dedicated method for stratified splitting is used + unique_strata = set(getattr(example, strata_field) for example in examples) + strata_maps = {s: [] for s in unique_strata} + for example in examples: + strata_maps[getattr(example, strata_field)].append(example) + return list(strata_maps.values()) + + +def rationed_split(examples, train_ratio, test_ratio, val_ratio, rnd): + """Create a random permutation of examples, then split them by ratios + + Arguments: + examples: a list of data + train_ratio, test_ratio, val_ratio: split fractions. + rnd: a random shuffler + + Examples: + >>> examples = [] + >>> train_ratio, test_ratio, val_ratio = 0.7, 0.2, 0.1 + >>> rnd = torchtext.data.dataset.RandomShuffler(None) + >>> train_examples, test_examples, valid_examples = \ + torchtext.data.dataset.rationed_split(examples, train_ratio, + test_ratio, val_ratio, + rnd) + """ + N = len(examples) + randperm = rnd(range(N)) + train_len = int(round(train_ratio * N)) + + # Due to possible rounding problems + if not val_ratio: + test_len = N - train_len + else: + test_len = int(round(test_ratio * N)) + + indices = (randperm[:train_len], # Train + randperm[train_len:train_len + test_len], # Test + randperm[train_len + test_len:]) # Validation + + # There's a possibly empty list for the validation set + data = tuple([examples[i] for i in index] for index in indices) + + return data diff --git a/torchtext/legacy/data/example.py b/torchtext/legacy/data/example.py new file mode 100644 index 0000000000..d9f96aeda3 --- /dev/null +++ b/torchtext/legacy/data/example.py @@ -0,0 +1,99 @@ +import json +from functools import reduce + + +class Example(object): + """Defines a single training or test example. + + Stores each column of the example as an attribute. + """ + @classmethod + def fromJSON(cls, data, fields): + ex = cls() + obj = json.loads(data) + + for key, vals in fields.items(): + if vals is not None: + if not isinstance(vals, list): + vals = [vals] + + for val in vals: + # for processing the key likes 'foo.bar' + name, field = val + ks = key.split('.') + + def reducer(obj, key): + if isinstance(obj, list): + results = [] + for data in obj: + if key not in data: + # key error + raise ValueError("Specified key {} was not found in " + "the input data".format(key)) + else: + results.append(data[key]) + return results + else: + # key error + if key not in obj: + raise ValueError("Specified key {} was not found in " + "the input data".format(key)) + else: + return obj[key] + + v = reduce(reducer, ks, obj) + setattr(ex, name, field.preprocess(v)) + return ex + + @classmethod + def fromdict(cls, data, fields): + ex = cls() + for key, vals in fields.items(): + if key not in data: + raise ValueError("Specified key {} was not found in " + "the input data".format(key)) + if vals is not None: + if not isinstance(vals, list): + vals = [vals] + for val in vals: + name, field = val + setattr(ex, name, field.preprocess(data[key])) + return ex + + @classmethod + def fromCSV(cls, data, fields, field_to_index=None): + if field_to_index is None: + return cls.fromlist(data, fields) + else: + assert(isinstance(fields, dict)) + data_dict = {f: data[idx] for f, idx in field_to_index.items()} + return cls.fromdict(data_dict, fields) + + @classmethod + def fromlist(cls, data, fields): + ex = cls() + for (name, field), val in zip(fields, data): + if field is not None: + if isinstance(val, str): + val = val.rstrip('\n') + # Handle field tuples + if isinstance(name, tuple): + for n, f in zip(name, field): + setattr(ex, n, f.preprocess(val)) + else: + setattr(ex, name, field.preprocess(val)) + return ex + + @classmethod + def fromtree(cls, data, fields, subtrees=False): + try: + from nltk.tree import Tree + except ImportError: + print("Please install NLTK. " + "See the docs at http://nltk.org for more information.") + raise + tree = Tree.fromstring(data) + if subtrees: + return [cls.fromlist( + [' '.join(t.leaves()), t.label()], fields) for t in tree.subtrees()] + return cls.fromlist([' '.join(tree.leaves()), tree.label()], fields) diff --git a/torchtext/legacy/data/field.py b/torchtext/legacy/data/field.py new file mode 100644 index 0000000000..c6f3ce3490 --- /dev/null +++ b/torchtext/legacy/data/field.py @@ -0,0 +1,735 @@ +# coding: utf8 +from collections import Counter, OrderedDict +from itertools import chain +import torch +from tqdm import tqdm +from .dataset import Dataset +from .pipeline import Pipeline +from torchtext.data.utils import get_tokenizer, dtype_to_attr, is_tokenizer_serializable +from torchtext.vocab import Vocab, SubwordVocab + + +class RawField(object): + """ Defines a general datatype. + + Every dataset consists of one or more types of data. For instance, a text + classification dataset contains sentences and their classes, while a + machine translation dataset contains paired examples of text in two + languages. Each of these types of data is represented by a RawField object. + A RawField object does not assume any property of the data type and + it holds parameters relating to how a datatype should be processed. + + Attributes: + preprocessing: The Pipeline that will be applied to examples + using this field before creating an example. + Default: None. + postprocessing: A Pipeline that will be applied to a list of examples + using this field before assigning to a batch. + Function signature: (batch(list)) -> object + Default: None. + is_target: Whether this field is a target variable. + Affects iteration over batches. Default: False + """ + + def __init__(self, preprocessing=None, postprocessing=None, is_target=False): + self.preprocessing = preprocessing + self.postprocessing = postprocessing + self.is_target = is_target + + def preprocess(self, x): + """ Preprocess an example if the `preprocessing` Pipeline is provided. """ + if self.preprocessing is not None: + return self.preprocessing(x) + else: + return x + + def process(self, batch, *args, **kwargs): + """ Process a list of examples to create a batch. + + Postprocess the batch with user-provided Pipeline. + + Args: + batch (list(object)): A list of object from a batch of examples. + Returns: + object: Processed object given the input and custom + postprocessing Pipeline. + """ + if self.postprocessing is not None: + batch = self.postprocessing(batch) + return batch + + +class Field(RawField): + """Defines a datatype together with instructions for converting to Tensor. + + Field class models common text processing datatypes that can be represented + by tensors. It holds a Vocab object that defines the set of possible values + for elements of the field and their corresponding numerical representations. + The Field object also holds other parameters relating to how a datatype + should be numericalized, such as a tokenization method and the kind of + Tensor that should be produced. + + If a Field is shared between two columns in a dataset (e.g., question and + answer in a QA dataset), then they will have a shared vocabulary. + + Attributes: + sequential: Whether the datatype represents sequential data. If False, + no tokenization is applied. Default: True. + use_vocab: Whether to use a Vocab object. If False, the data in this + field should already be numerical. Default: True. + init_token: A token that will be prepended to every example using this + field, or None for no initial token. Default: None. + eos_token: A token that will be appended to every example using this + field, or None for no end-of-sentence token. Default: None. + fix_length: A fixed length that all examples using this field will be + padded to, or None for flexible sequence lengths. Default: None. + dtype: The torch.dtype class that represents a batch of examples + of this kind of data. Default: torch.long. + preprocessing: The Pipeline that will be applied to examples + using this field after tokenizing but before numericalizing. Many + Datasets replace this attribute with a custom preprocessor. + Default: None. + postprocessing: A Pipeline that will be applied to examples using + this field after numericalizing but before the numbers are turned + into a Tensor. The pipeline function takes the batch as a list, and + the field's Vocab. + Default: None. + lower: Whether to lowercase the text in this field. Default: False. + tokenize: The function used to tokenize strings using this field into + sequential examples. If "spacy", the SpaCy tokenizer is + used. If a non-serializable function is passed as an argument, + the field will not be able to be serialized. Default: string.split. + tokenizer_language: The language of the tokenizer to be constructed. + Various languages currently supported only in SpaCy. + include_lengths: Whether to return a tuple of a padded minibatch and + a list containing the lengths of each examples, or just a padded + minibatch. Default: False. + batch_first: Whether to produce tensors with the batch dimension first. + Default: False. + pad_token: The string token used as padding. Default: "". + unk_token: The string token used to represent OOV words. Default: "". + pad_first: Do the padding of the sequence at the beginning. Default: False. + truncate_first: Do the truncating of the sequence at the beginning. Default: False + stop_words: Tokens to discard during the preprocessing step. Default: None + is_target: Whether this field is a target variable. + Affects iteration over batches. Default: False + """ + + vocab_cls = Vocab + # Dictionary mapping PyTorch tensor dtypes to the appropriate Python + # numeric type. + dtypes = { + torch.float32: float, + torch.float: float, + torch.float64: float, + torch.double: float, + torch.float16: float, + torch.half: float, + + torch.uint8: int, + torch.int8: int, + torch.int16: int, + torch.short: int, + torch.int32: int, + torch.int: int, + torch.int64: int, + torch.long: int, + } + + ignore = ['dtype', 'tokenize'] + + def __init__(self, sequential=True, use_vocab=True, init_token=None, + eos_token=None, fix_length=None, dtype=torch.long, + preprocessing=None, postprocessing=None, lower=False, + tokenize=None, tokenizer_language='en', include_lengths=False, + batch_first=False, pad_token="", unk_token="", + pad_first=False, truncate_first=False, stop_words=None, + is_target=False): + self.sequential = sequential + self.use_vocab = use_vocab + self.init_token = init_token + self.eos_token = eos_token + self.unk_token = unk_token + self.fix_length = fix_length + self.dtype = dtype + self.preprocessing = preprocessing + self.postprocessing = postprocessing + self.lower = lower + # store params to construct tokenizer for serialization + # in case the tokenizer isn't picklable (e.g. spacy) + self.tokenizer_args = (tokenize, tokenizer_language) + self.tokenize = get_tokenizer(tokenize, tokenizer_language) + self.include_lengths = include_lengths + self.batch_first = batch_first + self.pad_token = pad_token if self.sequential else None + self.pad_first = pad_first + self.truncate_first = truncate_first + try: + self.stop_words = set(stop_words) if stop_words is not None else None + except TypeError: + raise ValueError("Stop words must be convertible to a set") + self.is_target = is_target + + def __getstate__(self): + str_type = dtype_to_attr(self.dtype) + if is_tokenizer_serializable(*self.tokenizer_args): + tokenize = self.tokenize + else: + # signal to restore in `__setstate__` + tokenize = None + attrs = {k: v for k, v in self.__dict__.items() if k not in self.ignore} + attrs['dtype'] = str_type + attrs['tokenize'] = tokenize + + return attrs + + def __setstate__(self, state): + state['dtype'] = getattr(torch, state['dtype']) + if not state['tokenize']: + state['tokenize'] = get_tokenizer(*state['tokenizer_args']) + self.__dict__.update(state) + + def __hash__(self): + # we don't expect this to be called often + return 42 + + def __eq__(self, other): + if not isinstance(other, RawField): + return False + + return self.__dict__ == other.__dict__ + + def preprocess(self, x): + """Load a single example using this field, tokenizing if necessary. + + If `sequential=True`, the input will be tokenized. Then the input + will be optionally lowercased and passed to the user-provided + `preprocessing` Pipeline.""" + if self.sequential and isinstance(x, str): + x = self.tokenize(x.rstrip('\n')) + if self.lower: + x = Pipeline(str.lower)(x) + if self.sequential and self.use_vocab and self.stop_words is not None: + x = [w for w in x if w not in self.stop_words] + if self.preprocessing is not None: + return self.preprocessing(x) + else: + return x + + def process(self, batch, device=None): + """ Process a list of examples to create a torch.Tensor. + + Pad, numericalize, and postprocess a batch and create a tensor. + + Args: + batch (list(object)): A list of object from a batch of examples. + Returns: + torch.autograd.Variable: Processed object given the input + and custom postprocessing Pipeline. + """ + padded = self.pad(batch) + tensor = self.numericalize(padded, device=device) + return tensor + + def pad(self, minibatch): + """Pad a batch of examples using this field. + + Pads to self.fix_length if provided, otherwise pads to the length of + the longest example in the batch. Prepends self.init_token and appends + self.eos_token if those attributes are not None. Returns a tuple of the + padded list and a list containing lengths of each example if + `self.include_lengths` is `True` and `self.sequential` is `True`, else just + returns the padded list. If `self.sequential` is `False`, no padding is applied. + """ + minibatch = list(minibatch) + if not self.sequential: + return minibatch + if self.fix_length is None: + max_len = max(len(x) for x in minibatch) + else: + max_len = self.fix_length + ( + self.init_token, self.eos_token).count(None) - 2 + padded, lengths = [], [] + for x in minibatch: + if self.pad_first: + padded.append( + [self.pad_token] * max(0, max_len - len(x)) + + ([] if self.init_token is None else [self.init_token]) + + list(x[-max_len:] if self.truncate_first else x[:max_len]) + + ([] if self.eos_token is None else [self.eos_token])) + else: + padded.append( + ([] if self.init_token is None else [self.init_token]) + + list(x[-max_len:] if self.truncate_first else x[:max_len]) + + ([] if self.eos_token is None else [self.eos_token]) + + [self.pad_token] * max(0, max_len - len(x))) + lengths.append(len(padded[-1]) - max(0, max_len - len(x))) + if self.include_lengths: + return (padded, lengths) + return padded + + def build_vocab(self, *args, **kwargs): + """Construct the Vocab object for this field from one or more datasets. + + Arguments: + Positional arguments: Dataset objects or other iterable data + sources from which to construct the Vocab object that + represents the set of possible values for this field. If + a Dataset object is provided, all columns corresponding + to this field are used; individual columns can also be + provided directly. + Remaining keyword arguments: Passed to the constructor of Vocab. + """ + counter = Counter() + sources = [] + for arg in args: + if isinstance(arg, Dataset): + sources += [getattr(arg, name) for name, field in + arg.fields.items() if field is self] + else: + sources.append(arg) + for data in sources: + for x in data: + if not self.sequential: + x = [x] + try: + counter.update(x) + except TypeError: + counter.update(chain.from_iterable(x)) + specials = list(OrderedDict.fromkeys( + tok for tok in [self.unk_token, self.pad_token, self.init_token, + self.eos_token] + kwargs.pop('specials', []) + if tok is not None)) + self.vocab = self.vocab_cls(counter, specials=specials, **kwargs) + + def numericalize(self, arr, device=None): + """Turn a batch of examples that use this field into a Variable. + + If the field has include_lengths=True, a tensor of lengths will be + included in the return value. + + Arguments: + arr (List[List[str]], or tuple of (List[List[str]], List[int])): + List of tokenized and padded examples, or tuple of List of + tokenized and padded examples and List of lengths of each + example if self.include_lengths is True. + device (str or torch.device): A string or instance of `torch.device` + specifying which device the Variables are going to be created on. + If left as default, the tensors will be created on cpu. Default: None. + """ + if self.include_lengths and not isinstance(arr, tuple): + raise ValueError("Field has include_lengths set to True, but " + "input data is not a tuple of " + "(data batch, batch lengths).") + if isinstance(arr, tuple): + arr, lengths = arr + lengths = torch.tensor(lengths, dtype=self.dtype, device=device) + + if self.use_vocab: + if self.sequential: + arr = [[self.vocab.stoi[x] for x in ex] for ex in arr] + else: + arr = [self.vocab.stoi[x] for x in arr] + + if self.postprocessing is not None: + arr = self.postprocessing(arr, self.vocab) + else: + if self.dtype not in self.dtypes: + raise ValueError( + "Specified Field dtype {} can not be used with " + "use_vocab=False because we do not know how to numericalize it. " + "Please raise an issue at " + "https://github.com/pytorch/text/issues".format(self.dtype)) + numericalization_func = self.dtypes[self.dtype] + # It doesn't make sense to explicitly coerce to a numeric type if + # the data is sequential, since it's unclear how to coerce padding tokens + # to a numeric type. + if not self.sequential: + arr = [numericalization_func(x) if isinstance(x, str) + else x for x in arr] + if self.postprocessing is not None: + arr = self.postprocessing(arr, None) + + var = torch.tensor(arr, dtype=self.dtype, device=device) + + if self.sequential and not self.batch_first: + var.t_() + if self.sequential: + var = var.contiguous() + + if self.include_lengths: + return var, lengths + return var + + +class ReversibleField(Field): + def __init__(self, **kwargs): + if kwargs.get('tokenize') is list: + self.use_revtok = False + else: + self.use_revtok = True + if kwargs.get('tokenize') is None: + kwargs['tokenize'] = 'revtok' + if 'unk_token' not in kwargs: + kwargs['unk_token'] = ' UNK ' + super(ReversibleField, self).__init__(**kwargs) + + def reverse(self, batch): + if self.use_revtok: + try: + import revtok + except ImportError: + print("Please install revtok.") + raise + if not self.batch_first: + batch = batch.t() + with torch.cuda.device_of(batch): + batch = batch.tolist() + batch = [[self.vocab.itos[ind] for ind in ex] for ex in batch] # denumericalize + + def trim(s, t): + sentence = [] + for w in s: + if w == t: + break + sentence.append(w) + return sentence + + batch = [trim(ex, self.eos_token) for ex in batch] # trim past frst eos + + def filter_special(tok): + return tok not in (self.init_token, self.pad_token) + + batch = [filter(filter_special, ex) for ex in batch] + if self.use_revtok: + return [revtok.detokenize(ex) for ex in batch] + return [''.join(ex) for ex in batch] + + +class SubwordField(ReversibleField): + vocab_cls = SubwordVocab + + def __init__(self, **kwargs): + kwargs['tokenize'] = 'subword' + if 'unk_token' not in kwargs: + kwargs['unk_token'] = '�' + super(SubwordField, self).__init__(**kwargs) + + def segment(self, *args): + """Segment one or more datasets with this subword field. + + Arguments: + Positional arguments: Dataset objects or other indexable + mutable sequences to segment. If a Dataset object is provided, + all columns corresponding to this field are used; individual + columns can also be provided directly. + """ + sources = [] + for arg in args: + if isinstance(arg, Dataset): + sources += [getattr(arg, name) for name, field in + arg.fields.items() if field is self] + else: + sources.append(arg) + for data in sources: + for x in tqdm(data, 'segmenting'): + x[:] = self.vocab.segment(x) + + +class NestedField(Field): + """A nested field. + + A nested field holds another field (called *nesting field*), accepts an untokenized + string or a list string tokens and groups and treats them as one field as described + by the nesting field. Every token will be preprocessed, padded, etc. in the manner + specified by the nesting field. Note that this means a nested field always has + ``sequential=True``. The two fields' vocabularies will be shared. Their + numericalization results will be stacked into a single tensor. And NestedField will + share the same include_lengths with nesting_field, so one shouldn't specify the + include_lengths in the nesting_field. This field is + primarily used to implement character embeddings. See ``tests/data/test_field.py`` + for examples on how to use this field. + + Arguments: + nesting_field (Field): A field contained in this nested field. + use_vocab (bool): Whether to use a Vocab object. If False, the data in this + field should already be numerical. Default: ``True``. + init_token (str): A token that will be prepended to every example using this + field, or None for no initial token. Default: ``None``. + eos_token (str): A token that will be appended to every example using this + field, or None for no end-of-sentence token. Default: ``None``. + fix_length (int): A fixed length that all examples using this field will be + padded to, or ``None`` for flexible sequence lengths. Default: ``None``. + dtype: The torch.dtype class that represents a batch of examples + of this kind of data. Default: ``torch.long``. + preprocessing (Pipeline): The Pipeline that will be applied to examples + using this field after tokenizing but before numericalizing. Many + Datasets replace this attribute with a custom preprocessor. + Default: ``None``. + postprocessing (Pipeline): A Pipeline that will be applied to examples using + this field after numericalizing but before the numbers are turned + into a Tensor. The pipeline function takes the batch as a list, and + the field's Vocab. Default: ``None``. + include_lengths: Whether to return a tuple of a padded minibatch and + a list containing the lengths of each examples, or just a padded + minibatch. Default: False. + tokenize: The function used to tokenize strings using this field into + sequential examples. If "spacy", the SpaCy tokenizer is + used. If a non-serializable function is passed as an argument, + the field will not be able to be serialized. Default: string.split. + tokenizer_language: The language of the tokenizer to be constructed. + Various languages currently supported only in SpaCy. + pad_token (str): The string token used as padding. If ``nesting_field`` is + sequential, this will be set to its ``pad_token``. Default: ``""``. + pad_first (bool): Do the padding of the sequence at the beginning. Default: + ``False``. + """ + + def __init__(self, nesting_field, use_vocab=True, init_token=None, eos_token=None, + fix_length=None, dtype=torch.long, preprocessing=None, + postprocessing=None, tokenize=None, tokenizer_language='en', + include_lengths=False, pad_token='', + pad_first=False, truncate_first=False): + if isinstance(nesting_field, NestedField): + raise ValueError('nesting field must not be another NestedField') + if nesting_field.include_lengths: + raise ValueError('nesting field cannot have include_lengths=True') + + if nesting_field.sequential: + pad_token = nesting_field.pad_token + super(NestedField, self).__init__( + use_vocab=use_vocab, + init_token=init_token, + eos_token=eos_token, + fix_length=fix_length, + dtype=dtype, + preprocessing=preprocessing, + postprocessing=postprocessing, + lower=nesting_field.lower, + tokenize=tokenize, + tokenizer_language=tokenizer_language, + batch_first=True, + pad_token=pad_token, + unk_token=nesting_field.unk_token, + pad_first=pad_first, + truncate_first=truncate_first, + include_lengths=include_lengths + ) + self.nesting_field = nesting_field + # in case the user forget to do that + self.nesting_field.batch_first = True + + def preprocess(self, xs): + """Preprocess a single example. + + Firstly, tokenization and the supplied preprocessing pipeline is applied. Since + this field is always sequential, the result is a list. Then, each element of + the list is preprocessed using ``self.nesting_field.preprocess`` and the resulting + list is returned. + + Arguments: + xs (list or str): The input to preprocess. + + Returns: + list: The preprocessed list. + """ + return [self.nesting_field.preprocess(x) + for x in super(NestedField, self).preprocess(xs)] + + def pad(self, minibatch): + """Pad a batch of examples using this field. + + If ``self.nesting_field.sequential`` is ``False``, each example in the batch must + be a list of string tokens, and pads them as if by a ``Field`` with + ``sequential=True``. Otherwise, each example must be a list of list of tokens. + Using ``self.nesting_field``, pads the list of tokens to + ``self.nesting_field.fix_length`` if provided, or otherwise to the length of the + longest list of tokens in the batch. Next, using this field, pads the result by + filling short examples with ``self.nesting_field.pad_token``. + + Example: + >>> import pprint + >>> pp = pprint.PrettyPrinter(indent=4) + >>> + >>> nesting_field = Field(pad_token='', init_token='', eos_token='') + >>> field = NestedField(nesting_field, init_token='', eos_token='') + >>> minibatch = [ + ... [list('john'), list('loves'), list('mary')], + ... [list('mary'), list('cries')], + ... ] + >>> padded = field.pad(minibatch) + >>> pp.pprint(padded) + [ [ ['', '', '', '', '', '', ''], + ['', 'j', 'o', 'h', 'n', '', ''], + ['', 'l', 'o', 'v', 'e', 's', ''], + ['', 'm', 'a', 'r', 'y', '', ''], + ['', '', '', '', '', '', '']], + [ ['', '', '', '', '', '', ''], + ['', 'm', 'a', 'r', 'y', '', ''], + ['', 'c', 'r', 'i', 'e', 's', ''], + ['', '', '', '', '', '', ''], + ['', '', '', '', '', '', '']]] + + Arguments: + minibatch (list): Each element is a list of string if + ``self.nesting_field.sequential`` is ``False``, a list of list of string + otherwise. + + Returns: + list: The padded minibatch. or (padded, sentence_lens, word_lengths) + """ + minibatch = list(minibatch) + if not self.nesting_field.sequential: + return super(NestedField, self).pad(minibatch) + + # Save values of attributes to be monkeypatched + old_pad_token = self.pad_token + old_init_token = self.init_token + old_eos_token = self.eos_token + old_fix_len = self.nesting_field.fix_length + # Monkeypatch the attributes + if self.nesting_field.fix_length is None: + max_len = max(len(xs) for ex in minibatch for xs in ex) + fix_len = max_len + 2 - (self.nesting_field.init_token, + self.nesting_field.eos_token).count(None) + self.nesting_field.fix_length = fix_len + self.pad_token = [self.pad_token] * self.nesting_field.fix_length + if self.init_token is not None: + # self.init_token = self.nesting_field.pad([[self.init_token]])[0] + self.init_token = [self.init_token] + if self.eos_token is not None: + # self.eos_token = self.nesting_field.pad([[self.eos_token]])[0] + self.eos_token = [self.eos_token] + # Do padding + old_include_lengths = self.include_lengths + self.include_lengths = True + self.nesting_field.include_lengths = True + padded, sentence_lengths = super(NestedField, self).pad(minibatch) + padded_with_lengths = [self.nesting_field.pad(ex) for ex in padded] + word_lengths = [] + final_padded = [] + max_sen_len = len(padded[0]) + for (pad, lens), sentence_len in zip(padded_with_lengths, sentence_lengths): + if sentence_len == max_sen_len: + lens = lens + pad = pad + elif self.pad_first: + lens[:(max_sen_len - sentence_len)] = ( + [0] * (max_sen_len - sentence_len)) + pad[:(max_sen_len - sentence_len)] = ( + [self.pad_token] * (max_sen_len - sentence_len)) + else: + lens[-(max_sen_len - sentence_len):] = ( + [0] * (max_sen_len - sentence_len)) + pad[-(max_sen_len - sentence_len):] = ( + [self.pad_token] * (max_sen_len - sentence_len)) + word_lengths.append(lens) + final_padded.append(pad) + padded = final_padded + + # Restore monkeypatched attributes + self.nesting_field.fix_length = old_fix_len + self.pad_token = old_pad_token + self.init_token = old_init_token + self.eos_token = old_eos_token + self.include_lengths = old_include_lengths + if self.include_lengths: + return padded, sentence_lengths, word_lengths + return padded + + def build_vocab(self, *args, **kwargs): + """Construct the Vocab object for nesting field and combine it with this field's vocab. + + Arguments: + Positional arguments: Dataset objects or other iterable data + sources from which to construct the Vocab object that + represents the set of possible values for the nesting field. If + a Dataset object is provided, all columns corresponding + to this field are used; individual columns can also be + provided directly. + Remaining keyword arguments: Passed to the constructor of Vocab. + """ + sources = [] + for arg in args: + if isinstance(arg, Dataset): + sources.extend( + [getattr(arg, name) for name, field in arg.fields.items() + if field is self] + ) + else: + sources.append(arg) + + flattened = [] + for source in sources: + flattened.extend(source) + old_vectors = None + old_unk_init = None + old_vectors_cache = None + if "vectors" in kwargs.keys(): + old_vectors = kwargs["vectors"] + kwargs["vectors"] = None + if "unk_init" in kwargs.keys(): + old_unk_init = kwargs["unk_init"] + kwargs["unk_init"] = None + if "vectors_cache" in kwargs.keys(): + old_vectors_cache = kwargs["vectors_cache"] + kwargs["vectors_cache"] = None + # just build vocab and does not load vector + self.nesting_field.build_vocab(*flattened, **kwargs) + super(NestedField, self).build_vocab() + self.vocab.extend(self.nesting_field.vocab) + self.vocab.freqs = self.nesting_field.vocab.freqs.copy() + if old_vectors is not None: + self.vocab.load_vectors(old_vectors, + unk_init=old_unk_init, cache=old_vectors_cache) + + self.nesting_field.vocab = self.vocab + + def numericalize(self, arrs, device=None): + """Convert a padded minibatch into a variable tensor. + + Each item in the minibatch will be numericalized independently and the resulting + tensors will be stacked at the first dimension. + + Arguments: + arr (List[List[str]]): List of tokenized and padded examples. + device (str or torch.device): A string or instance of `torch.device` + specifying which device the Variables are going to be created on. + If left as default, the tensors will be created on cpu. Default: None. + """ + numericalized = [] + self.nesting_field.include_lengths = False + if self.include_lengths: + arrs, sentence_lengths, word_lengths = arrs + + for arr in arrs: + numericalized_ex = self.nesting_field.numericalize( + arr, device=device) + numericalized.append(numericalized_ex) + padded_batch = torch.stack(numericalized) + + self.nesting_field.include_lengths = True + if self.include_lengths: + sentence_lengths = \ + torch.tensor(sentence_lengths, dtype=self.dtype, device=device) + word_lengths = torch.tensor(word_lengths, dtype=self.dtype, device=device) + return (padded_batch, sentence_lengths, word_lengths) + return padded_batch + + +class LabelField(Field): + """A Label field. + + A label field is a shallow wrapper around a standard field designed to hold labels + for a classification task. Its only use is to set the unk_token and sequential to + `None` by default. + """ + + def __init__(self, **kwargs): + # whichever value is set for sequential, unk_token, and is_target + # will be overwritten + kwargs['sequential'] = False + kwargs['unk_token'] = None + kwargs['is_target'] = True + + super(LabelField, self).__init__(**kwargs) diff --git a/torchtext/legacy/data/iterator.py b/torchtext/legacy/data/iterator.py new file mode 100644 index 0000000000..b0bb4437b5 --- /dev/null +++ b/torchtext/legacy/data/iterator.py @@ -0,0 +1,297 @@ +import math +import random + +import logging +import torch +from torchtext.data.utils import RandomShuffler +from .batch import Batch +from .dataset import Dataset + +logger = logging.getLogger(__name__) + + +class Iterator(object): + """Defines an iterator that loads batches of data from a Dataset. + + Attributes: + dataset: The Dataset object to load Examples from. + batch_size: Batch size. + batch_size_fn: Function of three arguments (new example to add, current + count of examples in the batch, and current effective batch size) + that returns the new effective batch size resulting from adding + that example to a batch. This is useful for dynamic batching, where + this function would add to the current effective batch size the + number of tokens in the new example. + sort_key: A key to use for sorting examples in order to batch together + examples with similar lengths and minimize padding. The sort_key + provided to the Iterator constructor overrides the sort_key + attribute of the Dataset, or defers to it if None. + train: Whether the iterator represents a train set. + repeat: Whether to repeat the iterator for multiple epochs. Default: False. + shuffle: Whether to shuffle examples between epochs. + sort: Whether to sort examples according to self.sort_key. + Note that shuffle and sort default to train and (not train). + sort_within_batch: Whether to sort (in descending order according to + self.sort_key) within each batch. If None, defaults to self.sort. + If self.sort is True and this is False, the batch is left in the + original (ascending) sorted order. + device (str or `torch.device`): A string or instance of `torch.device` + specifying which device the Variables are going to be created on. + If left as default, the tensors will be created on cpu. Default: None. + """ + + def __init__(self, dataset, batch_size, sort_key=None, device=None, + batch_size_fn=None, train=True, + repeat=False, shuffle=None, sort=None, + sort_within_batch=None): + self.batch_size, self.train, self.dataset = batch_size, train, dataset + self.batch_size_fn = batch_size_fn + self.iterations = 0 + self.repeat = repeat + self.shuffle = train if shuffle is None else shuffle + self.sort = not train if sort is None else sort + + if sort_within_batch is None: + self.sort_within_batch = self.sort + else: + self.sort_within_batch = sort_within_batch + if sort_key is None: + self.sort_key = dataset.sort_key + else: + self.sort_key = sort_key + + if isinstance(device, int): + logger.warning("The `device` argument should be set by using `torch.device`" + + " or passing a string as an argument. This behavior will be" + + " deprecated soon and currently defaults to cpu.") + device = None + + if device is None: + device = torch.device('cpu') + elif isinstance(device, str): + device = torch.device(device) + + self.device = device + self.random_shuffler = RandomShuffler() + + # For state loading/saving only + self._iterations_this_epoch = 0 + self._random_state_this_epoch = None + self._restored_from_state = False + + @classmethod + def splits(cls, datasets, batch_sizes=None, **kwargs): + """Create Iterator objects for multiple splits of a dataset. + + Arguments: + datasets: Tuple of Dataset objects corresponding to the splits. The + first such object should be the train set. + batch_sizes: Tuple of batch sizes to use for the different splits, + or None to use the same batch_size for all splits. + Remaining keyword arguments: Passed to the constructor of the + iterator class being used. + """ + if batch_sizes is None: + batch_sizes = [kwargs.pop('batch_size')] * len(datasets) + ret = [] + for i in range(len(datasets)): + train = i == 0 + ret.append(cls( + datasets[i], batch_size=batch_sizes[i], train=train, **kwargs)) + return tuple(ret) + + def data(self): + """Return the examples in the dataset in order, sorted, or shuffled.""" + if self.sort: + xs = sorted(self.dataset, key=self.sort_key) + elif self.shuffle: + xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))] + else: + xs = self.dataset + return xs + + def init_epoch(self): + """Set up the batch generator for a new epoch.""" + + if self._restored_from_state: + self.random_shuffler.random_state = self._random_state_this_epoch + else: + self._random_state_this_epoch = self.random_shuffler.random_state + + self.create_batches() + + if self._restored_from_state: + self._restored_from_state = False + else: + self._iterations_this_epoch = 0 + + if not self.repeat: + self.iterations = 0 + + def create_batches(self): + self.batches = batch(self.data(), self.batch_size, self.batch_size_fn) + + @property + def epoch(self): + return math.floor(self.iterations / len(self)) + + def __len__(self): + if self.batch_size_fn is not None: + raise NotImplementedError + return math.ceil(len(self.dataset) / self.batch_size) + + def __iter__(self): + while True: + self.init_epoch() + for idx, minibatch in enumerate(self.batches): + # fast-forward if loaded from state + if self._iterations_this_epoch > idx: + continue + self.iterations += 1 + self._iterations_this_epoch += 1 + if self.sort_within_batch: + # NOTE: `rnn.pack_padded_sequence` requires that a minibatch + # be sorted by decreasing order, which requires reversing + # relative to typical sort keys + if self.sort: + minibatch.reverse() + else: + minibatch.sort(key=self.sort_key, reverse=True) + yield Batch(minibatch, self.dataset, self.device) + if not self.repeat: + return + + def state_dict(self): + return { + "iterations": self.iterations, + "iterations_this_epoch": self._iterations_this_epoch, + "random_state_this_epoch": self._random_state_this_epoch} + + def load_state_dict(self, state_dict): + self.iterations = state_dict["iterations"] + self._iterations_this_epoch = state_dict["iterations_this_epoch"] + self._random_state_this_epoch = state_dict["random_state_this_epoch"] + self._restored_from_state = True + + +class BPTTIterator(Iterator): + """Defines an iterator for language modeling tasks that use BPTT. + + Provides contiguous streams of examples together with targets that are + one timestep further forward, for language modeling training with + backpropagation through time (BPTT). Expects a Dataset with a single + example and a single field called 'text' and produces Batches with text and + target attributes. + + Attributes: + dataset: The Dataset object to load Examples from. + batch_size: Batch size. + bptt_len: Length of sequences for backpropagation through time. + sort_key: A key to use for sorting examples in order to batch together + examples with similar lengths and minimize padding. The sort_key + provided to the Iterator constructor overrides the sort_key + attribute of the Dataset, or defers to it if None. + train: Whether the iterator represents a train set. + repeat: Whether to repeat the iterator for multiple epochs. Default: False. + shuffle: Whether to shuffle examples between epochs. + sort: Whether to sort examples according to self.sort_key. + Note that shuffle and sort default to train and (not train). + device (str or torch.device): A string or instance of `torch.device` + specifying which device the Variables are going to be created on. + If left as default, the tensors will be created on cpu. Default: None. + """ + + def __init__(self, dataset, batch_size, bptt_len, **kwargs): + self.bptt_len = bptt_len + super(BPTTIterator, self).__init__(dataset, batch_size, **kwargs) + + def __len__(self): + return math.ceil((len(self.dataset[0].text) / self.batch_size - 1) + / self.bptt_len) + + def __iter__(self): + text = self.dataset[0].text + TEXT = self.dataset.fields['text'] + TEXT.eos_token = None + text = text + ([TEXT.pad_token] * int(math.ceil(len(text) / self.batch_size) + * self.batch_size - len(text))) + data = TEXT.numericalize( + [text], device=self.device) + data = data.view(self.batch_size, -1).t().contiguous() + dataset = Dataset(examples=self.dataset.examples, fields=[ + ('text', TEXT), ('target', TEXT)]) + while True: + for i in range(0, len(self) * self.bptt_len, self.bptt_len): + self.iterations += 1 + seq_len = min(self.bptt_len, len(data) - i - 1) + batch_text = data[i:i + seq_len] + batch_target = data[i + 1:i + 1 + seq_len] + if TEXT.batch_first: + batch_text = batch_text.t().contiguous() + batch_target = batch_target.t().contiguous() + yield Batch.fromvars( + dataset, self.batch_size, + text=batch_text, + target=batch_target) + if not self.repeat: + return + + +class BucketIterator(Iterator): + """Defines an iterator that batches examples of similar lengths together. + + Minimizes amount of padding needed while producing freshly shuffled + batches for each new epoch. See pool for the bucketing procedure used. + """ + + def create_batches(self): + if self.sort: + self.batches = batch(self.data(), self.batch_size, + self.batch_size_fn) + else: + self.batches = pool(self.data(), self.batch_size, + self.sort_key, self.batch_size_fn, + random_shuffler=self.random_shuffler, + shuffle=self.shuffle, + sort_within_batch=self.sort_within_batch) + + +def batch(data, batch_size, batch_size_fn=None): + """Yield elements from data in chunks of batch_size.""" + if batch_size_fn is None: + def batch_size_fn(new, count, sofar): + return count + minibatch, size_so_far = [], 0 + for ex in data: + minibatch.append(ex) + size_so_far = batch_size_fn(ex, len(minibatch), size_so_far) + if size_so_far == batch_size: + yield minibatch + minibatch, size_so_far = [], 0 + elif size_so_far > batch_size: + yield minibatch[:-1] + minibatch, size_so_far = minibatch[-1:], batch_size_fn(ex, 1, 0) + if minibatch: + yield minibatch + + +def pool(data, batch_size, key, batch_size_fn=lambda new, count, sofar: count, + random_shuffler=None, shuffle=False, sort_within_batch=False): + """Sort within buckets, then batch, then shuffle batches. + + Partitions data into chunks of size 100*batch_size, sorts examples within + each chunk using sort_key, then batch these examples and shuffle the + batches. + """ + if random_shuffler is None: + random_shuffler = random.shuffle + for p in batch(data, batch_size * 100, batch_size_fn): + p_batch = batch(sorted(p, key=key), batch_size, batch_size_fn) \ + if sort_within_batch \ + else batch(p, batch_size, batch_size_fn) + if shuffle: + for b in random_shuffler(list(p_batch)): + yield b + else: + for b in list(p_batch): + yield b diff --git a/torchtext/legacy/data/pipeline.py b/torchtext/legacy/data/pipeline.py new file mode 100644 index 0000000000..f576fdc720 --- /dev/null +++ b/torchtext/legacy/data/pipeline.py @@ -0,0 +1,85 @@ +class Pipeline(object): + """Defines a pipeline for transforming sequence data. + + The input is assumed to be utf-8 encoded `str`. + + Attributes: + convert_token: The function to apply to input sequence data. + pipes: The Pipelines that will be applied to input sequence + data in order. + """ + + def __init__(self, convert_token=None): + """Create a pipeline. + + Arguments: + convert_token: The function to apply to input sequence data. + If None, the identity function is used. Default: None + """ + if convert_token is None: + self.convert_token = Pipeline.identity + elif callable(convert_token): + self.convert_token = convert_token + else: + raise ValueError("Pipeline input convert_token {} is not None " + "or callable".format(convert_token)) + self.pipes = [self] + + def __call__(self, x, *args): + """Apply the the current Pipeline(s) to an input. + + Arguments: + x: The input to process with the Pipeline(s). + Positional arguments: Forwarded to the `call` function + of the Pipeline(s). + """ + for pipe in self.pipes: + x = pipe.call(x, *args) + return x + + def call(self, x, *args): + """Apply _only_ the convert_token function of the current pipeline + to the input. If the input is a list, a list with the results of + applying the `convert_token` function to all input elements is + returned. + + Arguments: + x: The input to apply the convert_token function to. + Positional arguments: Forwarded to the `convert_token` function + of the current Pipeline. + """ + if isinstance(x, list): + return [self.convert_token(tok, *args) for tok in x] + return self.convert_token(x, *args) + + def add_before(self, pipeline): + """Add a Pipeline to be applied before this processing pipeline. + + Arguments: + pipeline: The Pipeline or callable to apply before this + Pipeline. + """ + if not isinstance(pipeline, Pipeline): + pipeline = Pipeline(pipeline) + self.pipes = pipeline.pipes[:] + self.pipes[:] + return self + + def add_after(self, pipeline): + """Add a Pipeline to be applied after this processing pipeline. + + Arguments: + pipeline: The Pipeline or callable to apply after this + Pipeline. + """ + if not isinstance(pipeline, Pipeline): + pipeline = Pipeline(pipeline) + self.pipes = self.pipes[:] + pipeline.pipes[:] + return self + + @staticmethod + def identity(x): + """Return a copy of the input. + + This is here for serialization compatibility with pickle. + """ + return x diff --git a/torchtext/legacy/datasets/__init__.py b/torchtext/legacy/datasets/__init__.py new file mode 100644 index 0000000000..5eced837a5 --- /dev/null +++ b/torchtext/legacy/datasets/__init__.py @@ -0,0 +1,42 @@ +from .language_modeling import LanguageModelingDataset, WikiText2, WikiText103, PennTreebank # NOQA +from .nli import SNLI, MultiNLI, XNLI +from .sst import SST +from .translation import TranslationDataset, Multi30k, IWSLT, WMT14 # NOQA +from .sequence_tagging import SequenceTaggingDataset, UDPOS, CoNLL2000Chunking # NOQA +from .trec import TREC +from .imdb import IMDB +from .babi import BABI20 +from .text_classification import TextClassificationDataset, \ + AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ + YelpReviewFull, YahooAnswers, \ + AmazonReviewPolarity, AmazonReviewFull +from .unsupervised_learning import EnWik9 + +__all__ = ['LanguageModelingDataset', + 'SNLI', + 'MultiNLI', + 'XNLI', + 'SST', + 'TranslationDataset', + 'Multi30k', + 'IWSLT', + 'WMT14', + 'WikiText2', + 'WikiText103', + 'PennTreebank', + 'TREC', + 'IMDB', + 'SequenceTaggingDataset', + 'UDPOS', + 'CoNLL2000Chunking', + 'BABI20', + 'TextClassificationDataset', + 'AG_NEWS', + 'SogouNews', + 'DBpedia', + 'YelpReviewPolarity', + 'YelpReviewFull', + 'YahooAnswers', + 'AmazonReviewPolarity', + 'AmazonReviewFull', + 'EnWik9'] diff --git a/torchtext/datasets/babi.py b/torchtext/legacy/datasets/babi.py similarity index 100% rename from torchtext/datasets/babi.py rename to torchtext/legacy/datasets/babi.py diff --git a/torchtext/datasets/imdb.py b/torchtext/legacy/datasets/imdb.py similarity index 98% rename from torchtext/datasets/imdb.py rename to torchtext/legacy/datasets/imdb.py index e59ce19ecb..38fccb97be 100644 --- a/torchtext/datasets/imdb.py +++ b/torchtext/legacy/datasets/imdb.py @@ -18,7 +18,7 @@ def sort_key(ex): def __init__(self, path, text_field, label_field, **kwargs): """Create an IMDB dataset instance given a path and fields. - Args: + Arguments: path: Path to the dataset's highest level directory text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -41,7 +41,7 @@ def splits(cls, text_field, label_field, root='.data', train='train', test='test', **kwargs): """Create dataset objects for splits of the IMDB dataset. - Args: + Arguments: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: Root dataset storage directory. Default is '.data'. @@ -58,7 +58,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the IMDB dataset. - Args: + Arguments: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/language_modeling.py b/torchtext/legacy/datasets/language_modeling.py similarity index 98% rename from torchtext/datasets/language_modeling.py rename to torchtext/legacy/datasets/language_modeling.py index 7ebcca71b1..775fe51d9e 100644 --- a/torchtext/datasets/language_modeling.py +++ b/torchtext/legacy/datasets/language_modeling.py @@ -1,4 +1,4 @@ -from torchtext import data +from .. import data import io @@ -9,7 +9,7 @@ def __init__(self, path, text_field, newline_eos=True, encoding='utf-8', **kwargs): """Create a LanguageModelingDataset given a path and a field. - Args: + Arguments: path: Path to the data file. text_field: The field that will be used for text data. newline_eos: Whether to add an token for every newline in the @@ -44,7 +44,7 @@ def splits(cls, text_field, root='.data', train='wiki.train.tokens', This is the most flexible way to use the dataset. - Args: + Arguments: text_field: The field that will be used for text data. root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-2 @@ -67,7 +67,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Args: + Arguments: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for @@ -105,7 +105,7 @@ def splits(cls, text_field, root='.data', train='wiki.train.tokens', This is the most flexible way to use the dataset. - Args: + Arguments: text_field: The field that will be used for text data. root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-103 @@ -128,7 +128,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Args: + Arguments: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for @@ -174,7 +174,7 @@ def splits(cls, text_field, root='.data', train='ptb.train.txt', **kwargs): """Create dataset objects for splits of the Penn Treebank dataset. - Args: + Arguments: text_field: The field that will be used for text data. root: The root directory where the data files will be stored. train: The filename of the train data. Default: 'ptb.train.txt'. @@ -195,7 +195,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Args: + Arguments: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for diff --git a/torchtext/datasets/nli.py b/torchtext/legacy/datasets/nli.py similarity index 97% rename from torchtext/datasets/nli.py rename to torchtext/legacy/datasets/nli.py index 758576e7cc..453b35d584 100644 --- a/torchtext/datasets/nli.py +++ b/torchtext/legacy/datasets/nli.py @@ -45,13 +45,13 @@ def sort_key(ex): @classmethod def splits(cls, text_field, label_field, parse_field=None, - extra_fields={}, root='.data', train='train.jsonl', + extra_fields=None, root='.data', train='train.jsonl', validation='val.jsonl', test='test.jsonl'): """Create dataset objects for splits of the SNLI dataset. This is the most flexible way to use the dataset. - Args: + Arguments: text_field: The field that will be used for premise and hypothesis data. label_field: The field that will be used for label data. @@ -66,6 +66,8 @@ def splits(cls, text_field, label_field, parse_field=None, test: The filename of the test data, or None to not load the test set. Default: 'test.jsonl'. """ + if extra_fields is None: + extra_fields = {} path = cls.download(root) if parse_field is None: @@ -96,7 +98,7 @@ def iters(cls, batch_size=32, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Args: + Arguments: batch_size: Batch size. device: Device to create batches on. Use -1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/sequence_tagging.py b/torchtext/legacy/datasets/sequence_tagging.py similarity index 96% rename from torchtext/datasets/sequence_tagging.py rename to torchtext/legacy/datasets/sequence_tagging.py index 849d8be15d..1450369efc 100644 --- a/torchtext/datasets/sequence_tagging.py +++ b/torchtext/legacy/datasets/sequence_tagging.py @@ -78,7 +78,8 @@ class CoNLL2000Chunking(SequenceTaggingDataset): def splits(cls, fields, root=".data", train="train.txt", test="test.txt", validation_frac=0.1, **kwargs): """Downloads and loads the CoNLL 2000 Chunking dataset. - NOTE: There is only a train and test dataset so we use 10% of the train set as validation + NOTE: There is only a train and test dataset so we use + 10% of the train set as validation """ train, test = super(CoNLL2000Chunking, cls).splits( diff --git a/torchtext/datasets/sst.py b/torchtext/legacy/datasets/sst.py similarity index 98% rename from torchtext/datasets/sst.py rename to torchtext/legacy/datasets/sst.py index 8c793fad93..95a04e3f6b 100644 --- a/torchtext/datasets/sst.py +++ b/torchtext/legacy/datasets/sst.py @@ -17,7 +17,7 @@ def __init__(self, path, text_field, label_field, subtrees=False, fine_grained=False, **kwargs): """Create an SST dataset instance given a path and fields. - Args: + Arguments: path: Path to the data file text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -49,7 +49,7 @@ def splits(cls, text_field, label_field, root='.data', train_subtrees=False, **kwargs): """Create dataset objects for splits of the SST dataset. - Args: + Arguments: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: The root directory that the dataset's zip archive will be @@ -81,7 +81,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the SST dataset. - Args: + Arguments: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/text_classification.py b/torchtext/legacy/datasets/text_classification.py similarity index 100% rename from torchtext/datasets/text_classification.py rename to torchtext/legacy/datasets/text_classification.py diff --git a/torchtext/datasets/translation.py b/torchtext/legacy/datasets/translation.py similarity index 97% rename from torchtext/datasets/translation.py rename to torchtext/legacy/datasets/translation.py index cbb7ebdb39..ac1b2f322a 100644 --- a/torchtext/datasets/translation.py +++ b/torchtext/legacy/datasets/translation.py @@ -17,7 +17,7 @@ def sort_key(ex): def __init__(self, path, exts, fields, **kwargs): """Create a TranslationDataset given paths and fields. - Args: + Arguments: path: Common prefix of paths to the data files for both languages. exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data @@ -46,7 +46,7 @@ def splits(cls, exts, fields, path=None, root='.data', train='train', validation='val', test='test', **kwargs): """Create dataset objects for splits of a TranslationDataset. - Args: + Arguments: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -87,7 +87,7 @@ def splits(cls, exts, fields, root='.data', train='train', validation='val', test='test2016', **kwargs): """Create dataset objects for splits of the Multi30k dataset. - Args: + Arguments: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -127,7 +127,7 @@ def splits(cls, exts, fields, root='.data', test='IWSLT16.TED.tst2014', **kwargs): """Create dataset objects for splits of the IWSLT dataset. - Args: + Arguments: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -178,9 +178,9 @@ def clean(path): f_txt = f_orig.replace('.tags', '') with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt, \ io.open(f_orig, mode='r', encoding='utf-8') as fd_orig: - for l in fd_orig: - if not any(tag in l for tag in xml_tags): - fd_txt.write(l.strip() + '\n') + for line in fd_orig: + if not any(tag in line for tag in xml_tags): + fd_txt.write(line.strip() + '\n') class WMT14(TranslationDataset): @@ -201,7 +201,7 @@ def splits(cls, exts, fields, root='.data', test='newstest2014.tok.bpe.32000', **kwargs): """Create dataset objects for splits of the WMT 2014 dataset. - Args: + Arguments: exts: A tuple containing the extensions for each language. Must be either ('.en', '.de') or the reverse. fields: A tuple containing the fields that will be used for data diff --git a/torchtext/datasets/trec.py b/torchtext/legacy/datasets/trec.py similarity index 98% rename from torchtext/datasets/trec.py rename to torchtext/legacy/datasets/trec.py index 6e8792b519..d96723c672 100644 --- a/torchtext/datasets/trec.py +++ b/torchtext/legacy/datasets/trec.py @@ -18,7 +18,7 @@ def __init__(self, path, text_field, label_field, fine_grained=False, **kwargs): """Create an TREC dataset instance given a path and fields. - Args: + Arguments: path: Path to the data file. text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -46,7 +46,7 @@ def splits(cls, text_field, label_field, root='.data', train='train_5500.label', test='TREC_10.label', **kwargs): """Create dataset objects for splits of the TREC dataset. - Args: + Arguments: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: Root dataset storage directory. Default is '.data'. @@ -64,7 +64,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the TREC dataset. - Args: + Arguments: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/datasets/unsupervised_learning.py b/torchtext/legacy/datasets/unsupervised_learning.py similarity index 100% rename from torchtext/datasets/unsupervised_learning.py rename to torchtext/legacy/datasets/unsupervised_learning.py diff --git a/tox.ini b/tox.ini index 283f8176f7..34bf99a4ad 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,4 @@ [flake8] -ignore = E401,E402,E722,W503,W504,F821,B006,B007,B008 +ignore = E401,E402,E722,W503,W504,F821,B006,B007,B008,B009 max-line-length = 120 exclude = docs/source From eb2eeae4c21a0e91b1d75f7c327ac4a6cc06bbbe Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Thu, 4 Mar 2021 14:24:52 -0800 Subject: [PATCH 48/68] Sync torchtext GH<->fbcode until GH commit 1197514eb8cc33ccff10f588534f405b43908660 Summary: Import recent torchtext changes up until GH commit 1197514eb8cc33ccff10f588534f405b43908660 Reviewed By: zhangguanheng66 Differential Revision: D26824967 fbshipit-source-id: fc4be4f94a8f748ce2ed5e776e30a42422cbcab9 --- docs/Makefile | 2 +- docs/source/conf.py | 2 + docs/source/experimental_datasets.rst | 4 +- docs/source/experimental_datasets_raw.rst | 153 ++++++ docs/source/index.rst | 3 +- test/asset/raw_datasets.json | 46 ++ test/common/parameterized_utils.py | 17 + test/data/test_builtin_datasets.py | 103 +++- test/legacy/data/test_dataset.py | 479 ++++++++++++++++++ test/legacy/translation.py | 4 +- torchtext/data/dataset.py | 1 + .../datasets/language_modeling.py | 19 +- .../experimental/datasets/question_answer.py | 9 +- .../experimental/datasets/raw/__init__.py | 80 ++- .../experimental/datasets/raw/ag_news.py | 44 ++ .../datasets/raw/amazonreviewfull.py | 39 ++ .../datasets/raw/amazonreviewpolarity.py | 39 ++ torchtext/experimental/datasets/raw/common.py | 151 +++++- .../datasets/raw/conll2000chunking.py | 64 +++ .../experimental/datasets/raw/dbpedia.py | 39 ++ torchtext/experimental/datasets/raw/imdb.py | 37 ++ torchtext/experimental/datasets/raw/iwslt.py | 287 +++++++++++ .../experimental/datasets/raw/multi30k.py | 243 +++++++++ .../experimental/datasets/raw/penntreebank.py | 43 ++ .../experimental/datasets/raw/sogounews.py | 39 ++ torchtext/experimental/datasets/raw/squad1.py | 45 ++ torchtext/experimental/datasets/raw/squad2.py | 45 ++ torchtext/experimental/datasets/raw/udpos.py | 57 +++ .../experimental/datasets/raw/wikitext103.py | 31 ++ .../experimental/datasets/raw/wikitext2.py | 31 ++ torchtext/experimental/datasets/raw/wmt14.py | 188 +++++++ .../experimental/datasets/raw/wmtnewscrawl.py | 32 ++ .../experimental/datasets/raw/yahooanswers.py | 39 ++ .../datasets/raw/yelpreviewfull.py | 39 ++ .../datasets/raw/yelpreviewpolarity.py | 39 ++ .../experimental/datasets/sequence_tagging.py | 7 +- .../datasets/text_classification.py | 29 +- .../experimental/datasets/translation.py | 10 +- torchtext/experimental/vectors.py | 8 +- torchtext/experimental/vocab.py | 5 +- torchtext/legacy/datasets/imdb.py | 6 +- .../legacy/datasets/language_modeling.py | 17 +- torchtext/legacy/datasets/nli.py | 4 +- torchtext/legacy/datasets/sequence_tagging.py | 3 +- torchtext/legacy/datasets/sst.py | 6 +- .../legacy/datasets/text_classification.py | 110 ++-- torchtext/legacy/datasets/translation.py | 10 +- torchtext/legacy/datasets/trec.py | 6 +- torchtext/utils.py | 15 +- 49 files changed, 2558 insertions(+), 171 deletions(-) create mode 100644 docs/source/experimental_datasets_raw.rst create mode 100644 test/asset/raw_datasets.json create mode 100644 test/common/parameterized_utils.py create mode 100644 test/legacy/data/test_dataset.py create mode 100644 torchtext/experimental/datasets/raw/ag_news.py create mode 100644 torchtext/experimental/datasets/raw/amazonreviewfull.py create mode 100644 torchtext/experimental/datasets/raw/amazonreviewpolarity.py create mode 100644 torchtext/experimental/datasets/raw/conll2000chunking.py create mode 100644 torchtext/experimental/datasets/raw/dbpedia.py create mode 100644 torchtext/experimental/datasets/raw/imdb.py create mode 100644 torchtext/experimental/datasets/raw/iwslt.py create mode 100644 torchtext/experimental/datasets/raw/multi30k.py create mode 100644 torchtext/experimental/datasets/raw/penntreebank.py create mode 100644 torchtext/experimental/datasets/raw/sogounews.py create mode 100644 torchtext/experimental/datasets/raw/squad1.py create mode 100644 torchtext/experimental/datasets/raw/squad2.py create mode 100644 torchtext/experimental/datasets/raw/udpos.py create mode 100644 torchtext/experimental/datasets/raw/wikitext103.py create mode 100644 torchtext/experimental/datasets/raw/wikitext2.py create mode 100644 torchtext/experimental/datasets/raw/wmt14.py create mode 100644 torchtext/experimental/datasets/raw/wmtnewscrawl.py create mode 100644 torchtext/experimental/datasets/raw/yahooanswers.py create mode 100644 torchtext/experimental/datasets/raw/yelpreviewfull.py create mode 100644 torchtext/experimental/datasets/raw/yelpreviewpolarity.py diff --git a/docs/Makefile b/docs/Makefile index 9e12f78e06..748711bed6 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = -W # turn warnings into errors SPHINXBUILD = sphinx-build SPHINXPROJ = torchtext SOURCEDIR = source diff --git a/docs/source/conf.py b/docs/source/conf.py index 915319b06c..2756d79f22 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -46,6 +46,8 @@ ] napoleon_use_ivar = True +napoleon_numpy_docstring = False +napoleon_google_docstring = True # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index 2f8842639a..101c3fc442 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -121,7 +121,7 @@ WMTNewsCrawl Machine Translation ^^^^^^^^^^^^^^^^^^^ -Language modeling datasets are subclasses of ``TranslationDataset`` class. +Translation datasets are subclasses of ``TranslationDataset`` class. .. autoclass:: TranslationDataset :members: __init__ @@ -148,7 +148,7 @@ WMT14 Sequence Tagging ^^^^^^^^^^^^^^^^ -Language modeling datasets are subclasses of ``SequenceTaggingDataset`` class. +Sequence Tagging datasets are subclasses of ``SequenceTaggingDataset`` class. .. autoclass:: SequenceTaggingDataset :members: __init__ diff --git a/docs/source/experimental_datasets_raw.rst b/docs/source/experimental_datasets_raw.rst new file mode 100644 index 0000000000..cc898055f7 --- /dev/null +++ b/docs/source/experimental_datasets_raw.rst @@ -0,0 +1,153 @@ +torchtext.experimental.datasets.raw +=================================== + +.. currentmodule:: torchtext.experimental.datasets.raw + +General use cases are as follows: :: + + + # import datasets + from torchtext.experimental.datasets.raw import IMDB + + train_iter = IMDB(split='train') + + def tokenize(label, line): + return line.split() + + tokens = [] + for line in train_iter: + tokens += tokenize(line) + +The following datasets are available: + +.. contents:: Datasets + :local: + + +Text Classification +^^^^^^^^^^^^^^^^^^^ + +TextClassificationDataset +~~~~~~~~~~~~~~~~~~~~~~~~~ + +AG_NEWS +~~~~~~~ + +.. autofunction:: AG_NEWS + + +SogouNews +~~~~~~~~~ + +.. autofunction:: SogouNews + +DBpedia +~~~~~~~ + +.. autofunction:: DBpedia + +YelpReviewPolarity +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: YelpReviewPolarity + +YelpReviewFull +~~~~~~~~~~~~~~ + +.. autofunction:: YelpReviewFull + +YahooAnswers +~~~~~~~~~~~~ + +.. autofunction:: YahooAnswers + +AmazonReviewPolarity +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: AmazonReviewPolarity + +AmazonReviewFull +~~~~~~~~~~~~~~~~ + +.. autofunction:: AmazonReviewFull + +IMDb +~~~~ + +.. autofunction:: IMDB + + +Language Modeling +^^^^^^^^^^^^^^^^^ + +WikiText-2 +~~~~~~~~~~ + +.. autofunction:: WikiText2 + + +WikiText103 +~~~~~~~~~~~ + +.. autofunction:: WikiText103 + + +PennTreebank +~~~~~~~~~~~~ + +.. autofunction:: PennTreebank + + +WMTNewsCrawl +~~~~~~~~~~~~ + +.. autofunction:: WMTNewsCrawl + + +Machine Translation +^^^^^^^^^^^^^^^^^^^ + +Multi30k +~~~~~~~~ + +.. autofunction:: Multi30k + + +IWSLT +~~~~~ + +.. autofunction:: IWSLT + + +WMT14 +~~~~~ + +.. autofunction:: WMT14 + + +Sequence Tagging +^^^^^^^^^^^^^^^^ + +UDPOS +~~~~~ + +.. autofunction:: UDPOS + +CoNLL2000Chunking +~~~~~~~~~~~~~~~~~ + +.. autofunction:: CoNLL2000Chunking + +Question Answer +^^^^^^^^^^^^^^^ + +SQuAD 1.0 +~~~~~~~~~ + +.. autofunction:: SQuAD1 + + +SQuAD 2.0 +~~~~~~~~~ + +.. autofunction:: SQuAD2 diff --git a/docs/source/index.rst b/docs/source/index.rst index 4e812ee286..fcf0135ec2 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -32,15 +32,14 @@ popular datasets for natural language. :caption: Package Reference self - torchtext.data nn_modules data_utils data_functional data_metrics - torchtext.datasets torchtext.vocab torchtext.utils experimental_datasets + experimental_datasets_raw experimental_transforms experimental_vectors experimental_vocab diff --git a/test/asset/raw_datasets.json b/test/asset/raw_datasets.json new file mode 100644 index 0000000000..17d9b12fae --- /dev/null +++ b/test/asset/raw_datasets.json @@ -0,0 +1,46 @@ +{"dataset_name": "IMDB", "split": "train", "NUM_LINES": 25000, "MD5": "7c2ac02c03563afcf9b574c7e56c153a", "URL": "http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz", "first_line": ["neg", "I rented I AM CURIOUS-YELLOW from my video store because of all the controversy that surrounded it when it was first released in 1967. I also heard that at first it was seized by U.S. customs if it ever tried to enter this country, therefore being a fan of films considered \"controversial\" I really had to see this for myself.

      The plot is centered around a young Swedish drama student named Lena who wants to learn everything she can about life. In particular she wants to focus her attentions to making some sort of documentary on what the average Swede thought about certain political issues such as the Vietnam War and race issues in the United States. In between asking politicians and ordinary denizens of Stockholm about their opinions on politics, she has sex with her drama teacher, classmates, and married men.

      What kills me about I AM CURIOUS-YELLOW is that 40 years ago, this was considered pornographic. Really, the sex and nudity scenes are few and far between, even then it's not shot like some cheaply made porno. While my countrymen mind find it shocking, in reality sex and nudity are a major staple in Swedish cinema. Even Ingmar Bergman, arguably their answer to good old boy John Ford, had sex scenes in his films.

      I do commend the filmmakers for the fact that any sex shown in the film is shown for artistic purposes rather than just to shock people and make money to be shown in pornographic theaters in America. I AM CURIOUS-YELLOW is a good film for anyone wanting to study the meat and potatoes (no pun intended) of Swedish cinema. But really, this film doesn't have much of a plot."]} +{"dataset_name": "IMDB", "split": "test", "NUM_LINES": 25000, "MD5": "7c2ac02c03563afcf9b574c7e56c153a", "URL": "http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz", "first_line": ["neg", "I love sci-fi and am willing to put up with a lot. Sci-fi movies/TV are usually underfunded, under-appreciated and misunderstood. I tried to like this, I really did, but it is to good TV sci-fi as Babylon 5 is to Star Trek (the original). Silly prosthetics, cheap cardboard sets, stilted dialogues, CG that doesn't match the background, and painfully one-dimensional characters cannot be overcome with a 'sci-fi' setting. (I'm sure there are those of you out there who think Babylon 5 is good sci-fi TV. It's not. It's clich\u00e9d and uninspiring.) While US viewers might like emotion and character development, sci-fi is a genre that does not take itself seriously (cf. Star Trek). It may treat important issues, yet not as a serious philosophy. It's really difficult to care about the characters here as they are not simply foolish, just missing a spark of life. Their actions and reactions are wooden and predictable, often painful to watch. The makers of Earth KNOW it's rubbish as they have to always say \"Gene Roddenberry's Earth...\" otherwise people would not continue watching. Roddenberry's ashes must be turning in their orbit as this dull, cheap, poorly edited (watching it without advert breaks really brings this home) trudging Trabant of a show lumbers into space. Spoiler. So, kill off a main character. And then bring him back as another actor. Jeeez! Dallas all over again."]} +{"dataset_name": "AG_NEWS", "split": "train", "NUM_LINES": 120000, "MD5": "b1a00f826fdfbd249f79597b59e1dc12", "URL": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", "first_line": [3, "Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\band of ultra-cynics, are seeing green again."]} +{"dataset_name": "AG_NEWS", "split": "test", "NUM_LINES": 7600, "MD5": "d52ea96a97a2d943681189a97654912d", "URL": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv", "first_line": [3, "Fears for T N pension after talks Unions representing workers at Turner Newall say they are 'disappointed' after talks with stricken parent firm Federal Mogul."]} +{"dataset_name": "SogouNews", "split": "train", "NUM_LINES": 450000, "MD5": "0c1700ba70b73f964dd8de569d3fd03e", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE", "first_line": [4, "2008 di4 qi1 jie4 qi1ng da3o guo2 ji4 che1 zha3n me3i nv3 mo2 te4 2008di4 qi1 jie4 qi1ng da3o guo2 ji4 che1 zha3n yu2 15 ri4 za4i qi1ng da3o guo2 ji4 hui4 zha3n zho1ng xi1n she4ng da4 ka1i mu4 . be3n ci4 che1 zha3n jia1ng chi2 xu4 da4o be3n yue4 19 ri4 . ji1n nia2n qi1ng da3o guo2 ji4 che1 zha3n shi4 li4 nia2n da3o che2ng che1 zha3n gui1 mo2 zui4 da4 di2 yi1 ci4 , shi3 yo4ng lia3o qi1ng da3o guo2 ji4 hui4 zha3n zho1ng xi1n di2 qua2n bu4 shi4 ne4i wa4i zha3n gua3n . yi3 xia4 we2i xia4n cha3ng mo2 te4 tu2 pia4n ."]} +{"dataset_name": "SogouNews", "split": "test", "NUM_LINES": 60000, "MD5": "0c1700ba70b73f964dd8de569d3fd03e", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE", "first_line": [1, " ti3 ca1o shi4 jie4 be1i : che2ng fe1i na2 pi2ng he2ng mu4 zi4 yo2u ca1o ji1n pa2i su4 du4 : ( shuo1 mi2ng : dia3n ji1 zi4 do4ng bo1 fa4ng )\\n shuo1 mi2ng : dia3n ji1 ga1i a4n niu3 , xua3n ze2 yi1 lu4n ta2n ji2 ke3 "]} +{"dataset_name": "DBpedia", "split": "train", "NUM_LINES": 560000, "MD5": "dca7b1ae12b1091090db52aa7ec5ca64", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k", "first_line": [1, "E. D. Abbott Ltd Abbott of Farnham E D Abbott Limited was a British coachbuilding business based in Farnham Surrey trading under that name from 1929. A major part of their output was under sub-contract to motor vehicle manufacturers. Their business closed in 1972."]} +{"dataset_name": "DBpedia", "split": "test", "NUM_LINES": 70000, "MD5": "dca7b1ae12b1091090db52aa7ec5ca64", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k", "first_line": [1, "TY KU TY KU /ta\u026aku\u02d0/ is an American alcoholic beverage company that specializes in sake and other spirits. The privately-held company was founded in 2004 and is headquartered in New York City New York. While based in New York TY KU's beverages are made in Japan through a joint venture with two sake breweries. Since 2011 TY KU's growth has extended its products into all 50 states."]} +{"dataset_name": "YelpReviewPolarity", "split": "train", "NUM_LINES": 560000, "MD5": "620c8ae4bd5a150b730f1ba9a7c6a4d3", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg", "first_line": [1, "Unfortunately, the frustration of being Dr. Goldberg's patient is a repeat of the experience I've had with so many other doctors in NYC -- good doctor, terrible staff. It seems that his staff simply never answers the phone. It usually takes 2 hours of repeated calling to get an answer. Who has time for that or wants to deal with it? I have run into this problem with many other doctors and I just don't get it. You have office workers, you have patients with medical needs, why isn't anyone answering the phone? It's incomprehensible and not work the aggravation. It's with regret that I feel that I have to give Dr. Goldberg 2 stars."]} +{"dataset_name": "YelpReviewPolarity", "split": "test", "NUM_LINES": 38000, "MD5": "620c8ae4bd5a150b730f1ba9a7c6a4d3", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg", "first_line": [2, "Contrary to other reviews, I have zero complaints about the service or the prices. I have been getting tire service here for the past 5 years now, and compared to my experience with places like Pep Boys, these guys are experienced and know what they're doing. \\nAlso, this is one place that I do not feel like I am being taken advantage of, just because of my gender. Other auto mechanics have been notorious for capitalizing on my ignorance of cars, and have sucked my bank account dry. But here, my service and road coverage has all been well explained - and let up to me to decide. \\nAnd they just renovated the waiting room. It looks a lot better than it did in previous years."]} +{"dataset_name": "YelpReviewFull", "split": "train", "NUM_LINES": 650000, "MD5": "f7ddfafed1033f68ec72b9267863af6c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0", "first_line": [5, "dr. goldberg offers everything i look for in a general practitioner. he's nice and easy to talk to without being patronizing; he's always on time in seeing his patients; he's affiliated with a top-notch hospital (nyu) which my parents have explained to me is very important in case something happens and you need surgery; and you can get referrals to see specialists without having to see him first. really, what more do you need? i'm sitting here trying to think of any complaints i have about him, but i'm really drawing a blank."]} +{"dataset_name": "YelpReviewFull", "split": "test", "NUM_LINES": 50000, "MD5": "f7ddfafed1033f68ec72b9267863af6c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0", "first_line": [1, "I got 'new' tires from them and within two weeks got a flat. I took my car to a local mechanic to see if i could get the hole patched, but they said the reason I had a flat was because the previous patch had blown - WAIT, WHAT? I just got the tire and never needed to have it patched? This was supposed to be a new tire. \\nI took the tire over to Flynn's and they told me that someone punctured my tire, then tried to patch it. So there are resentful tire slashers? I find that very unlikely. After arguing with the guy and telling him that his logic was far fetched he said he'd give me a new tire \\\"this time\\\". \\nI will never go back to Flynn's b/c of the way this guy treated me and the simple fact that they gave me a used tire!"]} +{"dataset_name": "YahooAnswers", "split": "train", "NUM_LINES": 1400000, "MD5": "f3f9899b997a42beb24157e62e3eea8d", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU", "first_line": [5, "why doesn't an optical mouse work on a glass table? or even on some surfaces? Optical mice use an LED and a camera to rapidly capture images of the surface beneath the mouse. The infomation from the camera is analyzed by a DSP (Digital Signal Processor) and used to detect imperfections in the underlying surface and determine motion. Some materials, such as glass, mirrors or other very shiny, uniform surfaces interfere with the ability of the DSP to accurately analyze the surface beneath the mouse. \\nSince glass is transparent and very uniform, the mouse is unable to pick up enough imperfections in the underlying surface to determine motion. Mirrored surfaces are also a problem, since they constantly reflect back the same image, causing the DSP not to recognize motion properly. When the system is unable to see surface changes associated with movement, the mouse will not work properly."]} +{"dataset_name": "YahooAnswers", "split": "test", "NUM_LINES": 60000, "MD5": "f3f9899b997a42beb24157e62e3eea8d", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU", "first_line": [9, "What makes friendship click? How does the spark keep going? good communication is what does it. Can you move beyond small talk and say what's really on your mind. If you start doing this, my expereince is that potentially good friends will respond or shun you. Then you know who the really good friends are."]} +{"dataset_name": "AmazonReviewPolarity", "split": "train", "NUM_LINES": 3600000, "MD5": "fe39f8b653cada45afd5792e0f0e8f9b", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM", "first_line": [2, "Stuning even for the non-gamer This sound track was beautiful! It paints the senery in your mind so well I would recomend it even to people who hate vid. game music! I have played the game Chrono Cross but out of all of the games I have ever played it has the best music! It backs away from crude keyboarding and takes a fresher step with grate guitars and soulful orchestras. It would impress anyone who cares to listen! ^_^"]} +{"dataset_name": "AmazonReviewPolarity", "split": "test", "NUM_LINES": 400000, "MD5": "fe39f8b653cada45afd5792e0f0e8f9b", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM", "first_line": [2, "Great CD My lovely Pat has one of the GREAT voices of her generation. I have listened to this CD for YEARS and I still LOVE IT. When I'm in a good mood it makes me feel better. A bad mood just evaporates like sugar in the rain. This CD just oozes LIFE. Vocals are jusat STUUNNING and lyrics just kill. One of life's hidden gems. This is a desert isle CD in my book. Why she never made it big is just beyond me. Everytime I play this, no matter black, white, young, old, male, female EVERYBODY says one thing \"Who was that singing ?\""]} +{"dataset_name": "AmazonReviewFull", "split": "train", "NUM_LINES": 3000000, "MD5": "57d28bd5d930e772930baddf36641c7c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA", "first_line": [3, "more like funchuck Gave this to my dad for a gag gift after directing \"Nunsense,\" he got a reall kick out of it!"]} +{"dataset_name": "AmazonReviewFull", "split": "test", "NUM_LINES": 650000, "MD5": "57d28bd5d930e772930baddf36641c7c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA", "first_line": [1, "mens ultrasheer This model may be ok for sedentary types, but I'm active and get around alot in my job - consistently found these stockings rolled up down by my ankles! Not Good!! Solution: go with the standard compression stocking, 20-30, stock #114622. Excellent support, stays up and gives me what I need. Both pair of these also tore as I struggled to pull them up all the time. Good riddance/bad investment!"]} +{"dataset_name": "UDPOS", "split": "train", "NUM_LINES": 12543, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": [["Al", "-", "Zaman", ":", "American", "forces", "killed", "Shaikh", "Abdullah", "al", "-", "Ani", ",", "the", "preacher", "at", "the", "mosque", "in", "the", "town", "of", "Qaim", ",", "near", "the", "Syrian", "border", "."], ["PROPN", "PUNCT", "PROPN", "PUNCT", "ADJ", "NOUN", "VERB", "PROPN", "PROPN", "PROPN", "PUNCT", "PROPN", "PUNCT", "DET", "NOUN", "ADP", "DET", "NOUN", "ADP", "DET", "NOUN", "ADP", "PROPN", "PUNCT", "ADP", "DET", "ADJ", "NOUN", "PUNCT"], ["NNP", "HYPH", "NNP", ":", "JJ", "NNS", "VBD", "NNP", "NNP", "NNP", "HYPH", "NNP", ",", "DT", "NN", "IN", "DT", "NN", "IN", "DT", "NN", "IN", "NNP", ",", "IN", "DT", "JJ", "NN", "."]]} +{"dataset_name": "UDPOS", "split": "valid", "NUM_LINES": 2002, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": [["From", "the", "AP", "comes", "this", "story", ":"], ["ADP", "DET", "PROPN", "VERB", "DET", "NOUN", "PUNCT"], ["IN", "DT", "NNP", "VBZ", "DT", "NN", ":"]]} +{"dataset_name": "UDPOS", "split": "test", "NUM_LINES": 2077, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": [["What", "if", "Google", "Morphed", "Into", "GoogleOS", "?"], ["PRON", "SCONJ", "PROPN", "VERB", "ADP", "PROPN", "PUNCT"], ["WP", "IN", "NNP", "VBD", "IN", "NNP", "."]]} +{"dataset_name": "CoNLL2000Chunking", "split": "train", "NUM_LINES": 8936, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": [["Confidence", "in", "the", "pound", "is", "widely", "expected", "to", "take", "another", "sharp", "dive", "if", "trade", "figures", "for", "September", ",", "due", "for", "release", "tomorrow", ",", "fail", "to", "show", "a", "substantial", "improvement", "from", "July", "and", "August", "'s", "near-record", "deficits", "."], ["NN", "IN", "DT", "NN", "VBZ", "RB", "VBN", "TO", "VB", "DT", "JJ", "NN", "IN", "NN", "NNS", "IN", "NNP", ",", "JJ", "IN", "NN", "NN", ",", "VB", "TO", "VB", "DT", "JJ", "NN", "IN", "NNP", "CC", "NNP", "POS", "JJ", "NNS", "."], ["B-NP", "B-PP", "B-NP", "I-NP", "B-VP", "I-VP", "I-VP", "I-VP", "I-VP", "B-NP", "I-NP", "I-NP", "B-SBAR", "B-NP", "I-NP", "B-PP", "B-NP", "O", "B-ADJP", "B-PP", "B-NP", "B-NP", "O", "B-VP", "I-VP", "I-VP", "B-NP", "I-NP", "I-NP", "B-PP", "B-NP", "I-NP", "I-NP", "B-NP", "I-NP", "I-NP", "O"]]} +{"dataset_name": "CoNLL2000Chunking", "split": "test", "NUM_LINES": 2012, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": [["Rockwell", "International", "Corp.", "'s", "Tulsa", "unit", "said", "it", "signed", "a", "tentative", "agreement", "extending", "its", "contract", "with", "Boeing", "Co.", "to", "provide", "structural", "parts", "for", "Boeing", "'s", "747", "jetliners", "."], ["NNP", "NNP", "NNP", "POS", "NNP", "NN", "VBD", "PRP", "VBD", "DT", "JJ", "NN", "VBG", "PRP$", "NN", "IN", "NNP", "NNP", "TO", "VB", "JJ", "NNS", "IN", "NNP", "POS", "CD", "NNS", "."], ["B-NP", "I-NP", "I-NP", "B-NP", "I-NP", "I-NP", "B-VP", "B-NP", "B-VP", "B-NP", "I-NP", "I-NP", "B-VP", "B-NP", "I-NP", "B-PP", "B-NP", "I-NP", "B-VP", "I-VP", "B-NP", "I-NP", "B-PP", "B-NP", "B-NP", "I-NP", "I-NP", "O"]]} +{"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Zwei junge wei\u00dfe M\u00e4nner sind im Freien in der N\u00e4he vieler B\u00fcsche.\n", "Two young, White males are outside near many bushes.\n"]} +{"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Eine Gruppe von M\u00e4nnern l\u00e4dt Baumwolle auf einen Lastwagen\n", "A group of men are loading cotton onto a truck\n"]} +{"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Ein Mann mit einem orangefarbenen Hut, der etwas anstarrt.\n", "A man in an orange hat starring at something.\n"]} +{"dataset_name": "IWSLT", "split": "train", "NUM_LINES": 196884, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["David Gallo: Das ist Bill Lange. Ich bin Dave Gallo.\n", "David Gallo: This is Bill Lange. I'm Dave Gallo.\n"]} +{"dataset_name": "IWSLT", "split": "valid", "NUM_LINES": 993, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich 11 Jahre alt war, wurde ich eines Morgens von den Kl\u00e4ngen heller Freude geweckt.\n", "When I was 11, I remember waking up one morning to the sound of joy in my house.\n"]} +{"dataset_name": "IWSLT", "split": "test", "NUM_LINES": 1305, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich in meinen 20ern war, hatte ich meine erste Psychotherapie-Patientin.\n", "When I was in my 20s, I saw my very first psychotherapy client.\n"]} +{"dataset_name": "WMT14", "split": "train", "NUM_LINES": 4500966, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Wiederaufnahme der Sitzungsperiode\n", "Res@@ um@@ ption of the session\n"]} +{"dataset_name": "WMT14", "split": "valid", "NUM_LINES": 3000, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Eine repub@@ li@@ kanische Strategie , um der Wieder@@ wahl von Obama entgegen@@ zu@@ treten\n", "A Republic@@ an strategy to counter the re-@@ election of Obama\n"]} +{"dataset_name": "WMT14", "split": "test", "NUM_LINES": 3003, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Gut@@ ach : Noch mehr Sicherheit f\u00fcr Fu\u00dfg\u00e4n@@ ger\n", "Gut@@ ach : Incre@@ ased safety for pedestri@@ ans\n"]} +{"dataset_name": "WikiText2", "split": "train", "NUM_LINES": 36718, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": " \n"} +{"dataset_name": "WikiText2", "split": "valid", "NUM_LINES": 3760, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": " \n"} +{"dataset_name": "WikiText2", "split": "test", "NUM_LINES": 4358, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": " \n"} +{"dataset_name": "WikiText103", "split": "train", "NUM_LINES": 1801350, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": " \n"} +{"dataset_name": "WikiText103", "split": "valid", "NUM_LINES": 3760, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": " \n"} +{"dataset_name": "WikiText103", "split": "test", "NUM_LINES": 4358, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": " \n"} +{"dataset_name": "PennTreebank", "split": "train", "NUM_LINES": 42068, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " aer banknote berlitz calloway centrust cluett fromstein gitano guterman hydro-quebec ipo kia memotec mlx nahb punts rake regatta rubens sim snack-food ssangyong swapo wachter \n"} +{"dataset_name": "PennTreebank", "split": "valid", "NUM_LINES": 3370, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " consumers may want to move their telephones a little closer to the tv set \n"} +{"dataset_name": "PennTreebank", "split": "test", "NUM_LINES": 3761, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " no it was n't black monday \n"} +{"dataset_name": "WMTNewsCrawl", "split": "train", "NUM_LINES": 17676013, "MD5": "c70da2ba79db33fb0fc9119cbad16260", "URL": "http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz", "first_line": "I Need to Vent.\n"} +{"dataset_name": "SQuAD1", "split": "train", "NUM_LINES": 87599, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": ["Architecturally, the school has a Catholic character. Atop the Main Building's gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend \"Venite Ad Me Omnes\". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.", "To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?", ["Saint Bernadette Soubirous"], [515]]} +{"dataset_name": "SQuAD1", "split": "dev", "NUM_LINES": 10570, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": ["Super Bowl 50 was an American football game to determine the champion of the National Football League (NFL) for the 2015 season. The American Football Conference (AFC) champion Denver Broncos defeated the National Football Conference (NFC) champion Carolina Panthers 24\u201310 to earn their third Super Bowl title. The game was played on February 7, 2016, at Levi's Stadium in the San Francisco Bay Area at Santa Clara, California. As this was the 50th Super Bowl, the league emphasized the \"golden anniversary\" with various gold-themed initiatives, as well as temporarily suspending the tradition of naming each Super Bowl game with Roman numerals (under which the game would have been known as \"Super Bowl L\"), so that the logo could prominently feature the Arabic numerals 50.", "Which NFL team represented the AFC at Super Bowl 50?", ["Denver Broncos", "Denver Broncos", "Denver Broncos"], [177, 177, 177]]} +{"dataset_name": "SQuAD2", "split": "train", "NUM_LINES": 130319, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": ["Beyonc\u00e9 Giselle Knowles-Carter (/bi\u02d0\u02c8j\u0252nse\u026a/ bee-YON-say) (born September 4, 1981) is an American singer, songwriter, record producer and actress. Born and raised in Houston, Texas, she performed in various singing and dancing competitions as a child, and rose to fame in the late 1990s as lead singer of R&B girl-group Destiny's Child. Managed by her father, Mathew Knowles, the group became one of the world's best-selling girl groups of all time. Their hiatus saw the release of Beyonc\u00e9's debut album, Dangerously in Love (2003), which established her as a solo artist worldwide, earned five Grammy Awards and featured the Billboard Hot 100 number-one singles \"Crazy in Love\" and \"Baby Boy\".", "When did Beyonce start becoming popular?", ["in the late 1990s"], [269]]} +{"dataset_name": "SQuAD2", "split": "dev", "NUM_LINES": 11873, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": ["The Normans (Norman: Nourmands; French: Normands; Latin: Normanni) were the people who in the 10th and 11th centuries gave their name to Normandy, a region in France. They were descended from Norse (\"Norman\" comes from \"Norseman\") raiders and pirates from Denmark, Iceland and Norway who, under their leader Rollo, agreed to swear fealty to King Charles III of West Francia. Through generations of assimilation and mixing with the native Frankish and Roman-Gaulish populations, their descendants would gradually merge with the Carolingian-based cultures of West Francia. The distinct cultural and ethnic identity of the Normans emerged initially in the first half of the 10th century, and it continued to evolve over the succeeding centuries.", "In what country is Normandy located?", ["France", "France", "France", "France"], [159, 159, 159, 159]]} diff --git a/test/common/parameterized_utils.py b/test/common/parameterized_utils.py new file mode 100644 index 0000000000..85d5bcb0f5 --- /dev/null +++ b/test/common/parameterized_utils.py @@ -0,0 +1,17 @@ +import json +from parameterized import param +import os.path + + +_TEST_DIR_PATH = os.path.realpath( + os.path.join(os.path.dirname(__file__), '..')) + + +def get_asset_path(*paths): + """Return full path of a test asset""" + return os.path.join(_TEST_DIR_PATH, 'asset', *paths) + + +def load_params(*paths): + with open(get_asset_path(*paths), 'r') as file: + return [param(json.loads(line)) for line in file] diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index b955a57c18..bdd579df1d 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -1,12 +1,36 @@ #!/user/bin/env python3 # Note that all the tests in this module require dataset (either network access or cached) import os -from torchtext.legacy import data import torch import torchtext +from torchtext.legacy import data +from parameterized import parameterized from ..common.torchtext_test_case import TorchtextTestCase +from ..common.parameterized_utils import load_params from ..common.assets import conditional_remove +GOOGLE_DRIVE_BASED_DATASETS = [ + 'AmazonReviewFull', + 'AmazonReviewPolarity', + 'DBpedia', + 'IMDB', + 'IWSLT', + 'SogouNews', + 'WMT14', + 'YahooAnswers', + 'YelpReviewFull', + 'YelpReviewPolarity' +] + + +def _raw_text_custom_name_func(testcase_func, param_num, param): + info = param.args[0] + name_info = [info['dataset_name'], info['split']] + return "%s_%s" % ( + testcase_func.__name__, + parameterized.to_safe_name("_".join(name_info)) + ) + class TestDataset(TorchtextTestCase): def _helper_test_func(self, length, target_length, results, target_results): @@ -19,11 +43,6 @@ def _helper_test_func(self, length, target_length, results, target_results): def test_wikitext2_legacy(self): from torchtext.legacy.datasets import WikiText2 - # smoke test to ensure wikitext2 works properly - - # NOTE - # test_wikitext2 and test_wikitext2_legacy have some cache incompatibility. - # Keeping one's cache make the other fail. So we need to clean up the cache dir cachedir = os.path.join(self.project_root, ".data", "wikitext-2") conditional_remove(cachedir) @@ -133,21 +152,77 @@ def test_text_classification(self): [3525, 319, 4053, 34, 5407, 3607, 70, 6798, 10599, 4053]) self._helper_test_func(len(test_dataset), 7600, test_dataset[-1][1][:10], [2351, 758, 96, 38581, 2351, 220, 5, 396, 3, 14786]) - # Add test for the subset of the standard datasets - train_dataset, = AG_NEWS(split=('train')) + train_dataset = AG_NEWS(split='train') self._helper_test_func(len(train_dataset), 120000, train_dataset[-1][1][:10], [2155, 223, 2405, 30, 3010, 2204, 54, 3603, 4930, 2405]) + + def test_raw_ag_news(self): train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() self._helper_test_func(len(train_iter), 120000, next(train_iter)[1][:25], 'Wall St. Bears Claw Back ') self._helper_test_func(len(test_iter), 7600, next(test_iter)[1][:25], 'Fears for T N pension aft') del train_iter, test_iter + @parameterized.expand( + load_params('raw_datasets.json'), + name_func=_raw_text_custom_name_func) + def test_raw_text_classification(self, info): + dataset_name = info['dataset_name'] + if dataset_name in GOOGLE_DRIVE_BASED_DATASETS: + return + + # Currently disabled due to incredibly slow download + if dataset_name == "WMTNewsCrawl": + return + split = info['split'] + data_iter = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) + self.assertEqual(len(data_iter), info['NUM_LINES']) + self.assertEqual(next(data_iter), info['first_line']) + if dataset_name == "AG_NEWS": + self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name][split], info['URL']) + self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name][split], info['MD5']) + else: + self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name], info['URL']) + self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name], info['MD5']) + del data_iter + def test_num_lines_of_dataset(self): train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS(offset=10) _data = [item for item in train_iter] self.assertEqual(len(_data), 119990) + @parameterized.expand(list(sorted(torchtext.experimental.datasets.raw.DATASETS.keys()))) + def test_raw_datasets_split_argument(self, dataset_name): + if dataset_name in GOOGLE_DRIVE_BASED_DATASETS: + return + if 'statmt' in torchtext.experimental.datasets.raw.URLS[dataset_name]: + return + dataset = torchtext.experimental.datasets.raw.DATASETS[dataset_name] + train1 = dataset(split='train') + train2, = dataset(split=('train',)) + for d1, d2 in zip(train1, train2): + self.assertEqual(d1, d2) + # This test only aims to exercise the argument parsing and uses + # the first line as a litmus test for correctness. + break + # Exercise default constructor + _ = dataset() + + @parameterized.expand(["AG_NEWS", "WikiText2", "IMDB"]) + def test_datasets_split_argument(self, dataset_name): + if dataset_name in GOOGLE_DRIVE_BASED_DATASETS: + return + dataset = torchtext.experimental.datasets.DATASETS[dataset_name] + train1 = dataset(split='train') + train2, = dataset(split=('train',)) + for d1, d2 in zip(train1, train2): + self.assertEqual(d1, d2) + # This test only aims to exercise the argument parsing and uses + # the first line as a litmus test for correctness. + break + # Exercise default constructor + _ = dataset() + def test_offset_dataset(self): train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS(split=('train', 'test'), offset=10) @@ -185,7 +260,7 @@ def test_imdb(self): new_train_data, new_test_data = IMDB(vocab=new_vocab) # Add test for the subset of the standard datasets - train_dataset, = IMDB(split=('train')) + train_dataset = IMDB(split='train') self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], [13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]) train_iter, test_iter = torchtext.experimental.datasets.raw.IMDB() @@ -273,7 +348,7 @@ def test_multi30k(self): ' '.join(['Eine Gruppe von Männern lädt Baumwolle auf einen Lastwagen\n', 'A group of men are loading cotton onto a truck\n'])) del train_iter, valid_iter - train_dataset, = Multi30k(split=('train')) + train_dataset = Multi30k(split='train') # This change is due to the BC breaking in spacy 3.0 self._helper_test_func(len(train_dataset), 29000, train_dataset[20], @@ -336,7 +411,7 @@ def test_udpos_sequence_tagging(self): self.assertEqual(tokens_ids, [1206, 8, 69, 60, 157, 452]) # Add test for the subset of the standard datasets - train_dataset, = UDPOS(split=('train')) + train_dataset = UDPOS(split='train') self._helper_test_func(len(train_dataset), 12543, (train_dataset[0][0][:10], train_dataset[-1][2][:10]), ([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585], [6, 20, 8, 10, 8, 8, 24, 13, 8, 15])) @@ -383,7 +458,7 @@ def test_conll_sequence_tagging(self): self.assertEqual(tokens_ids, [970, 5, 135, 43, 214, 690]) # Add test for the subset of the standard datasets - train_dataset, = CoNLL2000Chunking(split=('train')) + train_dataset = CoNLL2000Chunking(split='train') self._helper_test_func(len(train_dataset), 8936, (train_dataset[0][0][:10], train_dataset[0][1][:10], train_dataset[0][2][:10], train_dataset[-1][0][:10], train_dataset[-1][1][:10], train_dataset[-1][2][:10]), @@ -418,7 +493,7 @@ def test_squad1(self): new_train_data, new_test_data = SQuAD1(vocab=new_vocab) # Add test for the subset of the standard datasets - train_dataset, = SQuAD1(split=('train')) + train_dataset = SQuAD1(split='train') context, question, answers, ans_pos = train_dataset[100] self._helper_test_func(len(train_dataset), 87599, (question[:5], ans_pos[0]), ([7, 24, 86, 52, 2], [72, 72])) @@ -447,7 +522,7 @@ def test_squad2(self): new_train_data, new_test_data = SQuAD2(vocab=new_vocab) # Add test for the subset of the standard datasets - train_dataset, = SQuAD2(split=('train')) + train_dataset = SQuAD2(split='train') context, question, answers, ans_pos = train_dataset[200] self._helper_test_func(len(train_dataset), 130319, (question[:5], ans_pos[0]), ([84, 50, 1421, 12, 5439], [9, 9])) diff --git a/test/legacy/data/test_dataset.py b/test/legacy/data/test_dataset.py new file mode 100644 index 0000000000..603a9e3857 --- /dev/null +++ b/test/legacy/data/test_dataset.py @@ -0,0 +1,479 @@ +# -*- coding: utf-8 -*- +from torchtext.legacy import data +import os +import sys +import tempfile +import unittest + +import pytest + +from ...common.torchtext_test_case import TorchtextTestCase + + +class TestDataset(TorchtextTestCase): + def test_tabular_simple_data(self): + for data_format in ["csv", "tsv", "json"]: + self.write_test_ppid_dataset(data_format=data_format) + + if data_format == "json": + question_field = data.Field(sequential=True) + label_field = data.Field(sequential=False) + fields = {"question1": ("q1", question_field), + "question2": ("q2", question_field), + "label": ("label", label_field)} + else: + question_field = data.Field(sequential=True) + label_field = data.Field(sequential=False) + fields = [("id", None), ("q1", question_field), + ("q2", question_field), ("label", label_field)] + + dataset = data.TabularDataset( + path=self.test_ppid_dataset_path, format=data_format, fields=fields) + + assert len(dataset) == 3 + + expected_examples = [ + (["When", "do", "you", "use", "シ", "instead", "of", "し?"], + ["When", "do", "you", "use", "\"&\"", + "instead", "of", "\"and\"?"], "0"), + (["Where", "was", "Lincoln", "born?"], + ["Which", "location", "was", "Abraham", "Lincoln", "born?"], "1"), + (["What", "is", "2+2"], ["2+2=?"], "1")] + + # Ensure examples have correct contents / test __getitem__ + for i in range(len(dataset)): + self.assertEqual(dataset[i].q1, expected_examples[i][0]) + self.assertEqual(dataset[i].q2, expected_examples[i][1]) + self.assertEqual(dataset[i].label, expected_examples[i][2]) + + # Test __getattr__ + for i, (q1, q2, label) in enumerate(zip(dataset.q1, dataset.q2, + dataset.label)): + self.assertEqual(q1, expected_examples[i][0]) + self.assertEqual(q2, expected_examples[i][1]) + self.assertEqual(label, expected_examples[i][2]) + + # Test __iter__ + for i, example in enumerate(dataset): + self.assertEqual(example.q1, expected_examples[i][0]) + self.assertEqual(example.q2, expected_examples[i][1]) + self.assertEqual(example.label, expected_examples[i][2]) + + def test_json_valid_and_invalid_nested_key(self): + self.write_test_nested_key_json_dataset() + valid_fields = {'foods.vegetables.name': ('vegs', data.Field()), + 'foods.fruits': ('fruits', data.Field())} + invalid_fields = {'foods.vegetables.color': ('vegs', data.Field())} + + expected_examples = [ + {"fruits": ["Apple", "Banana"], + "vegs": ["Broccoli", "Cabbage"]}, + {"fruits": ["Cherry", "Grape", "Lemon"], + "vegs": ["Cucumber", "Lettuce"]}, + {"fruits": ["Orange", "Pear", "Strawberry"], + "vegs": ["Marrow", "Spinach"]} + ] + dataset = data.TabularDataset( + path=self.test_nested_key_json_dataset_path, + format="json", + fields=valid_fields) + # check results + for example, expect in zip(dataset.examples, expected_examples): + self.assertEqual(example.vegs, expect['vegs']) + self.assertEqual(example.fruits, expect['fruits']) + + with self.assertRaises(ValueError): + data.TabularDataset( + path=self.test_nested_key_json_dataset_path, + format="json", + fields=invalid_fields) + + def test_errors(self): + # Ensure that trying to retrieve a key not in JSON data errors + self.write_test_ppid_dataset(data_format="json") + + question_field = data.Field(sequential=True) + label_field = data.Field(sequential=False) + fields = {"qeustion1": ("q1", question_field), + "question2": ("q2", question_field), + "label": ("label", label_field)} + + with self.assertRaises(ValueError): + data.TabularDataset( + path=self.test_ppid_dataset_path, format="json", fields=fields) + + def test_input_with_newlines_in_text(self): + # Smoke test for ensuring that TabularDataset works with files with newlines + example_with_newlines = [("\"hello \n world\"", "1"), + ("\"there is a \n newline\"", "0"), + ("\"there is no newline\"", "1")] + fields = [("text", data.Field(lower=True)), + ("label", data.Field(sequential=False))] + + for delim in [",", "\t"]: + with open(self.test_newline_dataset_path, "wt") as f: + for line in example_with_newlines: + f.write("{}\n".format(delim.join(line))) + + format_ = "csv" if delim == "," else "tsv" + dataset = data.TabularDataset( + path=self.test_newline_dataset_path, format=format_, fields=fields) + # if the newline is not parsed correctly, this should raise an error + for example in dataset: + self.assert_(hasattr(example, "text")) + self.assert_(hasattr(example, "label")) + + def test_csv_file_with_header(self): + example_with_header = [("text", "label"), + ("HELLO WORLD", "0"), + ("goodbye world", "1")] + + TEXT = data.Field(lower=True, tokenize=lambda x: x.split()) + fields = { + "label": ("label", data.Field(use_vocab=False, + sequential=False)), + "text": ("text", TEXT) + } + + for format_, delim in zip(["csv", "tsv"], [",", "\t"]): + with open(self.test_has_header_dataset_path, "wt") as f: + for line in example_with_header: + f.write("{}\n".format(delim.join(line))) + + # check that an error is raised here if a non-existent field is specified + with self.assertRaises(ValueError): + data.TabularDataset( + path=self.test_has_header_dataset_path, format=format_, + fields={"non_existent": ("label", data.Field())}) + + dataset = data.TabularDataset( + path=self.test_has_header_dataset_path, format=format_, + skip_header=False, fields=fields) + + TEXT.build_vocab(dataset) + + for i, example in enumerate(dataset): + self.assertEqual(example.text, + example_with_header[i + 1][0].lower().split()) + self.assertEqual(example.label, example_with_header[i + 1][1]) + + # check that the vocabulary is built correctly (#225) + expected_freqs = {"hello": 1, "world": 2, "goodbye": 1, "text": 0} + for k, v in expected_freqs.items(): + self.assertEqual(TEXT.vocab.freqs[k], v) + + data_iter = data.Iterator(dataset, batch_size=1, + sort_within_batch=False, repeat=False) + next(data_iter.__iter__()) + + @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") + def test_csv_dataset_quotechar(self): + # Based on issue #349 + example_data = [("text", "label"), + ('" hello world', "0"), + ('goodbye " world', "1"), + ('this is a pen " ', "0")] + + with tempfile.NamedTemporaryFile(dir=self.test_dir) as f: + for example in example_data: + f.write("{}\n".format(",".join(example)).encode("latin-1")) + + TEXT = data.Field(lower=True, tokenize=lambda x: x.split()) + fields = { + "label": ("label", data.Field(use_vocab=False, + sequential=False)), + "text": ("text", TEXT) + } + + f.seek(0) + + dataset = data.TabularDataset( + path=f.name, format="csv", + skip_header=False, fields=fields, + csv_reader_params={"quotechar": None}) + + TEXT.build_vocab(dataset) + + self.assertEqual(len(dataset), len(example_data) - 1) + + for i, example in enumerate(dataset): + self.assertEqual(example.text, + example_data[i + 1][0].lower().split()) + self.assertEqual(example.label, example_data[i + 1][1]) + + def test_dataset_split_arguments(self): + num_examples, num_labels = 30, 3 + self.write_test_splitting_dataset(num_examples=num_examples, + num_labels=num_labels) + text_field = data.Field() + label_field = data.LabelField() + fields = [('text', text_field), ('label', label_field)] + + dataset = data.TabularDataset( + path=self.test_dataset_splitting_path, format="csv", fields=fields) + + # Test default split ratio (0.7) + expected_train_size = 21 + expected_test_size = 9 + + train, test = dataset.split() + assert len(train) == expected_train_size + assert len(test) == expected_test_size + + # Test array arguments with same ratio + split_ratio = [0.7, 0.3] + train, test = dataset.split(split_ratio=split_ratio) + assert len(train) == expected_train_size + assert len(test) == expected_test_size + + # Add validation set + split_ratio = [0.6, 0.3, 0.1] + expected_train_size = 18 + expected_valid_size = 3 + expected_test_size = 9 + + train, valid, test = dataset.split(split_ratio=split_ratio) + assert len(train) == expected_train_size + assert len(valid) == expected_valid_size + assert len(test) == expected_test_size + + # Test ratio normalization + split_ratio = [6, 3, 1] + train, valid, test = dataset.split(split_ratio=split_ratio) + assert len(train) == expected_train_size + assert len(valid) == expected_valid_size + assert len(test) == expected_test_size + + # Test only two splits returned for too small valid split size + split_ratio = [0.66, 0.33, 0.01] + expected_length = 2 + splits = dataset.split(split_ratio=split_ratio) + assert len(splits) == expected_length + + # Test invalid arguments + split_ratio = 1.1 + with pytest.raises(AssertionError): + dataset.split(split_ratio=split_ratio) + + split_ratio = -1. + with pytest.raises(AssertionError): + dataset.split(split_ratio=split_ratio) + + split_ratio = [0.7] + with pytest.raises(AssertionError): + dataset.split(split_ratio=split_ratio) + + split_ratio = [1, 2, 3, 4] + with pytest.raises(AssertionError): + dataset.split(split_ratio=split_ratio) + + split_ratio = "string" + with pytest.raises(ValueError): + dataset.split(split_ratio=split_ratio) + + def test_stratified_dataset_split(self): + num_examples, num_labels = 30, 3 + self.write_test_splitting_dataset(num_examples=num_examples, + num_labels=num_labels) + text_field = data.Field() + label_field = data.LabelField() + fields = [('text', text_field), ('label', label_field)] + + dataset = data.TabularDataset( + path=self.test_dataset_splitting_path, format="csv", fields=fields) + + # Default split ratio + expected_train_size = 21 + expected_test_size = 9 + + train, test = dataset.split(stratified=True) + assert len(train) == expected_train_size + assert len(test) == expected_test_size + + # Test array arguments with same ratio + split_ratio = [0.7, 0.3] + train, test = dataset.split(split_ratio=split_ratio, stratified=True) + assert len(train) == expected_train_size + assert len(test) == expected_test_size + + # Test strata_field argument + train, test = dataset.split(split_ratio=split_ratio, stratified=True, + strata_field='label') + assert len(train) == expected_train_size + assert len(test) == expected_test_size + + # Test invalid field name + strata_field = 'dummy' + with pytest.raises(ValueError): + dataset.split(split_ratio=split_ratio, stratified=True, + strata_field=strata_field) + + # Test uneven stratify sizes + num_examples, num_labels = 28, 3 + self.write_test_splitting_dataset(num_examples=num_examples, + num_labels=num_labels) + # 10 examples for class 1 and 9 examples for classes 2,3 + dataset = data.TabularDataset( + path=self.test_dataset_splitting_path, format="csv", fields=fields) + + expected_train_size = 7 + 6 + 6 + expected_test_size = 3 + 3 + 3 + train, test = dataset.split(split_ratio=split_ratio, stratified=True) + assert len(train) == expected_train_size + assert len(test) == expected_test_size + + split_ratio = [0.7, 0.3] + train, test = dataset.split(split_ratio=split_ratio, stratified=True) + assert len(train) == expected_train_size + assert len(test) == expected_test_size + + # Add validation set + split_ratio = [0.6, 0.3, 0.1] + expected_train_size = 6 + 5 + 5 + expected_valid_size = 1 + 1 + 1 + expected_test_size = 3 + 3 + 3 + train, valid, test = dataset.split(split_ratio=split_ratio, stratified=True) + assert len(train) == expected_train_size + assert len(valid) == expected_valid_size + assert len(test) == expected_test_size + + def test_filter(self): + # Create test examples + sentence11 = [["who", "is", "there"]] + sentence12 = [["bernardo", "is", "there"]] + label1 = [1] + sentence21 = [["nay", "answer", "me"]] + sentence22 = [["stand", "unfold", "yourself"]] + label2 = [0] + sentence31 = [["is", "Horatio", "there"]] + sentence32 = [["a", "piece", "of", "him"]] + label3 = [0] + + example1_values = sentence11 + sentence12 + label1 + example2_values = sentence21 + sentence22 + label2 + example3_values = sentence31 + sentence32 + label3 + + # Test filter remove words from single field only + dataset, text_field = filter_init( + example1_values, + example2_values, + example3_values + ) + + text_field.vocab.stoi.pop("there") + text_field.vocab.stoi.pop("bernardo") + + dataset.filter_examples(["text1"]) + + assert dataset[0].text1 == ["who", "is"] + assert dataset[0].text2 == ["bernardo", "is", "there"] + assert dataset[0].label == 1 + + assert dataset[1].text1 == ["nay", "answer", "me"] + assert dataset[1].text2 == ["stand", "unfold", "yourself"] + assert dataset[1].label == 0 + + assert dataset[2].text1 == ["is", "Horatio"] + assert dataset[2].text2 == ["a", "piece", "of", "him"] + assert dataset[2].label == 0 + + # Test filter remove words from multiple fields + dataset, text_field = filter_init( + example1_values, + example2_values, + example3_values + ) + + text_field.vocab.stoi.pop("there") + text_field.vocab.stoi.pop("bernardo") + + dataset.filter_examples(["text1", "text2"]) + + assert dataset[0].text1 == ["who", "is"] + assert dataset[0].text2 == ["is"] + assert dataset[0].label == 1 + + assert dataset[1].text1 == ["nay", "answer", "me"] + assert dataset[1].text2 == ["stand", "unfold", "yourself"] + assert dataset[1].label == 0 + + assert dataset[2].text1 == ["is", "Horatio"] + assert dataset[2].text2 == ["a", "piece", "of", "him"] + assert dataset[2].label == 0 + + # Test filter remove all words in example + dataset, text_field = filter_init( + example1_values, + example2_values, + example3_values + ) + + text_field.vocab.stoi.pop("who") + text_field.vocab.stoi.pop("is") + text_field.vocab.stoi.pop("there") + + dataset.filter_examples(["text1", "text2"]) + + assert dataset[0].text1 == [] + assert dataset[0].text2 == ["bernardo"] + assert dataset[0].label == 1 + + assert dataset[1].text1 == ["nay", "answer", "me"] + assert dataset[1].text2 == ["stand", "unfold", "yourself"] + assert dataset[1].label == 0 + + assert dataset[2].text1 == ["Horatio"] + assert dataset[2].text2 == ["a", "piece", "of", "him"] + assert dataset[2].label == 0 + + def test_gz_extraction(self): + # tar.gz file contains train.txt and test.txt + tgz = (b'\x1f\x8b\x08\x00\x1e\xcc\xd5Z\x00\x03\xed\xd1;\n\x800\x10E' + b'\xd1,%+\x90\xc9G\xb3\x1e\x0b\x0b\x1b\x03q\x04\x97\xef\xa7' + b'\xb0\xb0P,R\x08\xf74o`\x9aa\x9e\x96~\x9c\x1a]\xd5\xd4#\xbb' + b'\x94\xd2\x99\xbb{\x9e\xb3\x0b\xbekC\x8c\x12\x9c\x11\xe7b\x10c' + b'\xa5\xe2M\x97e\xd6\xbeXkJ\xce\x8f?x\xdb\xff\x94\x0e\xb3V\xae' + b'\xff[\xffQ\x8e\xfe}\xf2\xf4\x0f\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00O6\x1c\xc6\xbd\x89\x00(\x00\x00') + + # .gz file contains dummy.txt + gz = (b'\x1f\x8b\x08\x08W\xce\xd5Z\x00\x03dummy.txt\x00\x0bq\r\x0e\x01' + b'\x00\xb8\x93\xea\xee\x04\x00\x00\x00') + + # Create both files + with open(os.path.join(self.test_dir, 'dummy.tar.gz'), 'wb') as fp: + fp.write(tgz) + + with open(os.path.join(self.test_dir, 'dummy.txt.gz'), 'wb') as fp: + fp.write(gz) + + # Set the urls in a dummy class + class DummyDataset(data.Dataset): + urls = ['dummy.tar.gz', 'dummy.txt.gz'] + name = '' + dirname = '' + + # Run extraction + DummyDataset.download(self.test_dir, check='') + + # Check if files were extracted correctly + assert os.path.isfile(os.path.join(self.test_dir, 'dummy.txt')) + assert os.path.isfile(os.path.join(self.test_dir, 'train.txt')) + assert os.path.isfile(os.path.join(self.test_dir, 'test.txt')) + + +def filter_init(ex_val1, ex_val2, ex_val3): + text_field = data.Field(sequential=True) + label_field = data.Field(sequential=False) + fields = [("text1", text_field), ("text2", text_field), + ("label", label_field)] + + example1 = data.Example.fromlist(ex_val1, fields) + example2 = data.Example.fromlist(ex_val2, fields) + example3 = data.Example.fromlist(ex_val3, fields) + examples = [example1, example2, example3] + + dataset = data.Dataset(examples, fields) + text_field.build_vocab(dataset) + + return dataset, text_field diff --git a/test/legacy/translation.py b/test/legacy/translation.py index 9a0e9a7f2f..8861fba93b 100644 --- a/test/legacy/translation.py +++ b/test/legacy/translation.py @@ -4,8 +4,8 @@ import re import spacy -spacy_de = spacy.load('de') -spacy_en = spacy.load('en') +spacy_de = spacy.load('de_core_news_sm') +spacy_en = spacy.load('en_core_web_sm') url = re.compile('(.*)') diff --git a/torchtext/data/dataset.py b/torchtext/data/dataset.py index 5ee7176d73..defd6e565f 100644 --- a/torchtext/data/dataset.py +++ b/torchtext/data/dataset.py @@ -1,4 +1,5 @@ import torch.utils.data +import warnings class Dataset(torch.utils.data.Dataset): diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index e841314c91..fb575e16f6 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -2,8 +2,9 @@ import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets.raw import language_modeling as raw +from torchtext.experimental.datasets import raw from torchtext.experimental.datasets.raw.common import check_default_set +from torchtext.experimental.datasets.raw.common import wrap_datasets logger_ = logging.getLogger(__name__) @@ -58,11 +59,11 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, tokenizer, root, vocab, split, year, language): +def _setup_datasets(dataset_name, tokenizer, root, vocab, split_, year, language): if tokenizer is None: tokenizer = get_tokenizer('basic_english') - split = check_default_set(split, ('train', 'test', 'valid')) + split = check_default_set(split_, ('train', 'test', 'valid'), dataset_name) if vocab is None: if 'train' not in split: @@ -84,8 +85,8 @@ def text_transform(line): raw_datasets = raw.DATASETS[dataset_name](root=root, split=split) raw_data = {name: list(map(text_transform, raw_dataset)) for name, raw_dataset in zip(split, raw_datasets)} logger_.info('Building datasets for {}'.format(split)) - return tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform) - for item in split) + return wrap_datasets(tuple(LanguageModelingDataset(raw_data[item], vocab, text_transform) + for item in split), split_) def WikiText2(tokenizer=None, root='.data', vocab=None, split=('train', 'valid', 'test')): @@ -115,7 +116,7 @@ def WikiText2(tokenizer=None, root='.data', vocab=None, split=('train', 'valid', >>> tokenizer = get_tokenizer("spacy") >>> train_dataset, valid_dataset, test_dataset = WikiText2(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() - >>> valid_dataset, = WikiText2(tokenizer=tokenizer, vocab=vocab, + >>> valid_dataset = WikiText2(tokenizer=tokenizer, vocab=vocab, split='valid') """ @@ -149,7 +150,7 @@ def WikiText103(tokenizer=None, root='.data', vocab=None, split=('train', 'valid >>> tokenizer = get_tokenizer("spacy") >>> train_dataset, valid_dataset, test_dataset = WikiText103(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() - >>> valid_dataset, = WikiText103(tokenizer=tokenizer, vocab=vocab, + >>> valid_dataset = WikiText103(tokenizer=tokenizer, vocab=vocab, split='valid') """ @@ -184,7 +185,7 @@ def PennTreebank(tokenizer=None, root='.data', vocab=None, split=('train', 'vali >>> tokenizer = get_tokenizer("spacy") >>> train_dataset, valid_dataset, test_dataset = PennTreebank(tokenizer=tokenizer) >>> vocab = train_dataset.get_vocab() - >>> valid_dataset, = PennTreebank(tokenizer=tokenizer, vocab=vocab, + >>> valid_dataset = PennTreebank(tokenizer=tokenizer, vocab=vocab, split='valid') """ @@ -215,7 +216,7 @@ def WMTNewsCrawl(tokenizer=None, root='.data', vocab=None, split=('train'), year >>> from torchtext.experimental.datasets import WMTNewsCrawl >>> from torchtext.data.utils import get_tokenizer >>> tokenizer = get_tokenizer("spacy") - >>> train_dataset, = WMTNewsCrawl(tokenizer=tokenizer, split='train') + >>> train_dataset = WMTNewsCrawl(tokenizer=tokenizer, split='train') Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. """ diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index f24551c5a4..14e601e328 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -2,8 +2,9 @@ import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets.raw import question_answer as raw +from torchtext.experimental.datasets import raw from torchtext.experimental.datasets.raw.common import check_default_set +from torchtext.experimental.datasets.raw.common import wrap_datasets from torchtext.experimental.functional import ( totensor, vocab_func, @@ -61,12 +62,12 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, root, vocab, tokenizer, split): +def _setup_datasets(dataset_name, root, vocab, tokenizer, split_): text_transform = [] if tokenizer is None: tokenizer = get_tokenizer('basic_english') text_transform = sequential_transforms(tokenizer) - split = check_default_set(split, ('train', 'dev')) + split = check_default_set(split_, ('train', 'dev'), dataset_name) raw_datasets = raw.DATASETS[dataset_name](root=root, split=split) raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} if vocab is None: @@ -86,7 +87,7 @@ def apply_transform(data): transforms = {'context': text_transform, 'question': text_transform, 'answers': text_transform, 'ans_pos': totensor(dtype=torch.long)} logger_.info('Building datasets for {}'.format(split)) - return tuple(QuestionAnswerDataset(raw_data[item], vocab, transforms) for item in split) + return wrap_datasets(tuple(QuestionAnswerDataset(raw_data[item], vocab, transforms) for item in split), split_) def SQuAD1(root='.data', vocab=None, tokenizer=None, split=('train', 'dev')): diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py index 5a3eeabc6f..bee58c74ec 100644 --- a/torchtext/experimental/datasets/raw/__init__.py +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -1,30 +1,56 @@ -from .text_classification import AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, \ - YelpReviewFull, YahooAnswers, \ - AmazonReviewPolarity, AmazonReviewFull, IMDB -from .sequence_tagging import UDPOS, CoNLL2000Chunking -from .translation import Multi30k, IWSLT, WMT14 -from .language_modeling import WikiText2, WikiText103, PennTreebank, WMTNewsCrawl -from .question_answer import SQuAD1, SQuAD2 +import importlib +from .ag_news import AG_NEWS +from .amazonreviewfull import AmazonReviewFull +from .amazonreviewpolarity import AmazonReviewPolarity +from .conll2000chunking import CoNLL2000Chunking +from .dbpedia import DBpedia +from .imdb import IMDB +from .iwslt import IWSLT +from .multi30k import Multi30k +from .penntreebank import PennTreebank +from .sogounews import SogouNews +from .squad1 import SQuAD1 +from .squad2 import SQuAD2 +from .udpos import UDPOS +from .wikitext103 import WikiText103 +from .wikitext2 import WikiText2 +from .wmt14 import WMT14 +from .wmtnewscrawl import WMTNewsCrawl +from .yahooanswers import YahooAnswers +from .yelpreviewfull import YelpReviewFull +from .yelpreviewpolarity import YelpReviewPolarity -DATASETS = {'IMDB': IMDB, - 'AG_NEWS': AG_NEWS, - 'SogouNews': SogouNews, - 'DBpedia': DBpedia, - 'YelpReviewPolarity': YelpReviewPolarity, - 'YelpReviewFull': YelpReviewFull, - 'YahooAnswers': YahooAnswers, - 'AmazonReviewPolarity': AmazonReviewPolarity, - 'AmazonReviewFull': AmazonReviewFull, - 'UDPOS': UDPOS, - 'CoNLL2000Chunking': CoNLL2000Chunking, - 'Multi30k': Multi30k, - 'IWSLT': IWSLT, - 'WMT14': WMT14, - 'WikiText2': WikiText2, - 'WikiText103': WikiText103, - 'PennTreebank': PennTreebank, - 'WMTNewsCrawl': WMTNewsCrawl, - 'SQuAD1': SQuAD1, - 'SQuAD2': SQuAD2} +DATASETS = { + 'AG_NEWS': AG_NEWS, + 'AmazonReviewFull': AmazonReviewFull, + 'AmazonReviewPolarity': AmazonReviewPolarity, + 'CoNLL2000Chunking': CoNLL2000Chunking, + 'DBpedia': DBpedia, + 'IMDB': IMDB, + 'IWSLT': IWSLT, + 'Multi30k': Multi30k, + 'PennTreebank': PennTreebank, + 'SQuAD1': SQuAD1, + 'SQuAD2': SQuAD2, + 'SogouNews': SogouNews, + 'UDPOS': UDPOS, + 'WMT14': WMT14, + 'WMTNewsCrawl': WMTNewsCrawl, + 'WikiText103': WikiText103, + 'WikiText2': WikiText2, + 'YahooAnswers': YahooAnswers, + 'YelpReviewFull': YelpReviewFull, + 'YelpReviewPolarity': YelpReviewPolarity +} + +URLS = {} +NUM_LINES = {} +MD5 = {} +for dataset in DATASETS: + dataset_module_path = "torchtext.experimental.datasets.raw." + dataset.lower() + dataset_module = importlib.import_module(dataset_module_path) + URLS[dataset] = dataset_module.URL + NUM_LINES[dataset] = dataset_module.NUM_LINES + MD5[dataset] = dataset_module.MD5 __all__ = sorted(list(map(str, DATASETS.keys()))) diff --git a/torchtext/experimental/datasets/raw/ag_news.py b/torchtext/experimental/datasets/raw/ag_news.py new file mode 100644 index 0000000000..91843f5206 --- /dev/null +++ b/torchtext/experimental/datasets/raw/ag_news.py @@ -0,0 +1,44 @@ +from torchtext.utils import download_from_url, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = { + 'train': "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", + 'test': "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv", +} + +MD5 = { + 'train': "b1a00f826fdfbd249f79597b59e1dc12", + 'test': "d52ea96a97a2d943681189a97654912d", +} + +NUM_LINES = { + 'train': 120000, + 'test': 7600, +} + + +@wrap_split_argument +@add_docstring_header() +def AG_NEWS(root='.data', split=('train', 'test'), offset=0): + + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + + extracted_files = [download_from_url(URL[item], root=root, + path=os.path.join(root, item + ".csv"), + hash_value=MD5[item], + hash_type='md5') for item in ('train', 'test')] + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("AG_NEWS", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/amazonreviewfull.py b/torchtext/experimental/datasets/raw/amazonreviewfull.py new file mode 100644 index 0000000000..7bbe72ba95 --- /dev/null +++ b/torchtext/experimental/datasets/raw/amazonreviewfull.py @@ -0,0 +1,39 @@ +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA' + +MD5 = '57d28bd5d930e772930baddf36641c7c' + +NUM_LINES = { + 'train': 3000000, + 'test': 650000, +} + +_PATH = 'amazon_review_full_csv.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def AmazonReviewFull(root='.data', split=('train', 'test'), offset=0): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + dataset_tar = download_from_url(URL, root=root, + path=os.path.join(root, _PATH), + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("AmazonReviewFull", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/amazonreviewpolarity.py b/torchtext/experimental/datasets/raw/amazonreviewpolarity.py new file mode 100644 index 0000000000..36d4583c2f --- /dev/null +++ b/torchtext/experimental/datasets/raw/amazonreviewpolarity.py @@ -0,0 +1,39 @@ +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM' + +MD5 = 'fe39f8b653cada45afd5792e0f0e8f9b' + +NUM_LINES = { + 'train': 3600000, + 'test': 400000, +} + +_PATH = 'amazon_review_polarity_csv.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def AmazonReviewPolarity(root='.data', split=('train', 'test'), offset=0): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + dataset_tar = download_from_url(URL, root=root, + path=os.path.join(root, _PATH), + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("AmazonReviewPolarity", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/common.py b/torchtext/experimental/datasets/raw/common.py index e53786ae54..51a334385a 100644 --- a/torchtext/experimental/datasets/raw/common.py +++ b/torchtext/experimental/datasets/raw/common.py @@ -1,13 +1,148 @@ import torch +import inspect +import functools -def check_default_set(data_select, target_select): - if isinstance(data_select, str): - data_select = (data_select,) - if not set(data_select).issubset(set(target_select)): - raise TypeError('A subset of data selection {} is supported but {} is passed in'.format(target_select, - data_select)) - return data_select +def check_default_set(split, target_select, dataset_name): + # Check whether given object split is either a tuple of strings or string + # and represents a valid selection of options given by the tuple of strings + # target_select. + if isinstance(split, str): + split = (split,) + if isinstance(target_select, str): + target_select = (target_select,) + if not isinstance(split, tuple): + raise ValueError("Internal error: Expected split to be of type tuple.") + if not set(split).issubset(set(target_select)): + raise TypeError('Given selection {} of splits is not supported for dataset {}. Please choose from {}.'.format( + split, dataset_name, target_select)) + return split + + +def wrap_datasets(datasets, split): + # Wrap return value for _setup_datasets functions to support singular values instead + # of tuples when split is a string. + if isinstance(split, str): + if len(datasets) != 1: + raise ValueError("Internal error: Expected number of datasets is not 1.") + return datasets[0] + return datasets + + +def find_match(match, lst): + """ + Searches list of strings and returns first entry that partially or fully + contains the given string match. + """ + for element in lst: + if match in element: + return element + return None + + +def dataset_docstring_header(fn): + """ + Returns docstring for a dataset based on function arguments. + + Assumes function signature of form (root='.data', split=, offset=0, **kwargs) + """ + argspec = inspect.getfullargspec(fn) + if not (argspec.args[0] == "root" and + argspec.args[1] == "split" and + argspec.args[2] == "offset"): + raise ValueError("Internal Error: Given function {} did not adhere to standard signature.".format(fn)) + default_split = argspec.defaults[1] + + if isinstance(default_split, tuple): + example_subset = default_split[:2] + if len(default_split) < 3: + example_subset = (default_split[1],) + return """{} dataset + + Separately returns the {} split + + Args: + root: Directory where the datasets are saved. + Default: ".data" + split: split or splits to be returned. Can be a string or tuple of strings. + By default, all three datasets are generated. Users + could also choose any subset of them, for example {} or just 'train'. + Default: {} + offset: the number of the starting line. + Default: 0 + """.format(fn.__name__, "/".join(default_split), str(example_subset), str(default_split)) + + if isinstance(default_split, str): + return """{} dataset + + Only returns the {default_split} split + + Args: + root: Directory where the datasets are saved. + Default: ".data" + split: Only {default_split} is available. + Default: {default_split} + offset: the number of the starting line. + Default: 0""".format(fn.__name__, default_split=default_split) + + raise ValueError("default_split type expected to be of string or tuple but got {}".format(type(default_split))) + + +def add_docstring_header(): + def docstring_decorator(fn): + fn.__doc__ = dataset_docstring_header(fn) + fn.__doc__ if fn.__doc__ else "" + return fn + return docstring_decorator + + +def wrap_split_argument(fn): + """ + Wraps given function of specific signature to extend behavior of split + to support individual strings. The given function is expected to have a split + kwarg that accepts tuples of strings, e.g. ('train', 'valid') and the returned + function will have a split argument that also accepts strings, e.g. 'train', which + are then turned single entry tuples. Furthermore, the return value of the wrapped + function is unpacked if split is only a single string to enable behavior such as + + train = AG_NEWS(split='train') + train, valid = AG_NEWS(split=('train', 'valid')) + """ + + argspec = inspect.getfullargspec(fn) + if not (argspec.args[0] == "root" and + argspec.args[1] == "split" and + argspec.args[2] == "offset" and + argspec.defaults[0] == ".data" and + argspec.defaults[2] == 0 and + argspec.varargs is None and + argspec.varkw is None and + len(argspec.kwonlyargs) == 0 and + argspec.kwonlydefaults is None and + len(argspec.annotations) == 0 + ): + raise ValueError("Internal Error: Given function {} did not adhere to standard signature.".format(fn)) + + # functools.wraps only forwards __module__, __name__, etc + # (see https://docs.python.org/3/library/functools.html#functools.update_wrapper) + # but not default values of arguments. The wrapped function fn is assumed to have + # keyword arguments with default values only, so only a dictionary of default + # values is needed to support that behavior for new_fn as well. + fn_kwargs_dict = {} + for arg, default in zip(argspec.args[3:], argspec.defaults[3:]): + fn_kwargs_dict[arg] = default + + @functools.wraps(fn) + def new_fn(root='.data', split=argspec.defaults[1], offset=0, **kwargs): + for arg in fn_kwargs_dict: + if arg not in kwargs: + kwargs[arg] = fn_kwargs_dict[arg] + kwargs["root"] = root + kwargs["offset"] = offset + kwargs["split"] = check_default_set(split, argspec.defaults[1], fn.__name__) + result = fn(**kwargs) + return wrap_datasets(tuple(result), split) + + return new_fn class RawTextIterableDataset(torch.utils.data.IterableDataset): @@ -22,6 +157,8 @@ def __init__(self, name, full_num_lines, iterator, offset=0): self.full_num_lines = full_num_lines self._iterator = iterator self.start = offset + if offset < 0: + raise ValueError("Given offset must be non-negative, got {} instead.".format(offset)) self.num_lines = full_num_lines - offset def __iter__(self): diff --git a/torchtext/experimental/datasets/raw/conll2000chunking.py b/torchtext/experimental/datasets/raw/conll2000chunking.py new file mode 100644 index 0000000000..2980708952 --- /dev/null +++ b/torchtext/experimental/datasets/raw/conll2000chunking.py @@ -0,0 +1,64 @@ +from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header + +URL = { + 'train': "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", + 'test': "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz", +} + +MD5 = { + 'train': "6969c2903a1f19a83569db643e43dcc8", + 'test': "a916e1c2d83eb3004b38fc6fcd628939", +} + +NUM_LINES = { + 'train': 8936, + 'test': 2012, +} + + +def _create_data_from_iob(data_path, separator="\t"): + with open(data_path, encoding="utf-8") as input_file: + columns = [] + for line in input_file: + line = line.strip() + if line == "": + if columns: + yield columns + columns = [] + else: + for i, column in enumerate(line.split(separator)): + if len(columns) < i + 1: + columns.append([]) + columns[i].append(column) + if len(columns) > 0: + yield columns + + +def _construct_filepath(paths, file_suffix): + if file_suffix: + path = None + for p in paths: + path = p if p.endswith(file_suffix) else path + return path + return None + + +@wrap_split_argument +@add_docstring_header() +def CoNLL2000Chunking(root='.data', split=('train', 'test'), offset=0): + extracted_files = [] + for name, item in URL.items(): + dataset_tar = download_from_url(item, root=root, hash_value=MD5[name], hash_type='md5') + extracted_files.extend(extract_archive(dataset_tar)) + + data_filenames = { + "train": _construct_filepath(extracted_files, "train.txt"), + "valid": _construct_filepath(extracted_files, "dev.txt"), + "test": _construct_filepath(extracted_files, "test.txt") + } + return [RawTextIterableDataset("CoNLL2000Chunking", NUM_LINES[item], + _create_data_from_iob(data_filenames[item], " "), offset=offset) + if data_filenames[item] is not None else None for item in split] diff --git a/torchtext/experimental/datasets/raw/dbpedia.py b/torchtext/experimental/datasets/raw/dbpedia.py new file mode 100644 index 0000000000..256a402903 --- /dev/null +++ b/torchtext/experimental/datasets/raw/dbpedia.py @@ -0,0 +1,39 @@ +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k' + +MD5 = 'dca7b1ae12b1091090db52aa7ec5ca64' + +NUM_LINES = { + 'train': 560000, + 'test': 70000, +} + +_PATH = 'dbpedia_csv.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def DBpedia(root='.data', split=('train', 'test'), offset=0): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + dataset_tar = download_from_url(URL, root=root, + path=os.path.join(root, _PATH), + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("DBpedia", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/imdb.py b/torchtext/experimental/datasets/raw/imdb.py new file mode 100644 index 0000000000..2cde9a7658 --- /dev/null +++ b/torchtext/experimental/datasets/raw/imdb.py @@ -0,0 +1,37 @@ +from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +import io + +URL = 'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz' + +MD5 = '7c2ac02c03563afcf9b574c7e56c153a' + +NUM_LINES = { + 'train': 25000, + 'test': 25000, +} + +_PATH = 'aclImdb_v1.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def IMDB(root='.data', split=('train', 'test'), offset=0): + def generate_imdb_data(key, extracted_files): + for fname in extracted_files: + if 'urls' in fname: + continue + elif key in fname and ('pos' in fname or 'neg' in fname): + with io.open(fname, encoding="utf8") as f: + label = 'pos' if 'pos' in fname else 'neg' + yield label, f.read() + dataset_tar = download_from_url(URL, root=root, + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + datasets = [] + for item in split: + iterator = generate_imdb_data(item, extracted_files) + datasets.append(RawTextIterableDataset("IMDB", NUM_LINES[item], iterator, offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/iwslt.py b/torchtext/experimental/datasets/raw/iwslt.py new file mode 100644 index 0000000000..a0fd4e6a5f --- /dev/null +++ b/torchtext/experimental/datasets/raw/iwslt.py @@ -0,0 +1,287 @@ +import os +import io +import codecs +import xml.etree.ElementTree as ET +from torchtext.utils import (download_from_url, extract_archive) +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header + +URL = 'https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8' + +_PATH = '2016-01.tgz' + +MD5 = 'c393ed3fc2a1b0f004b3331043f615ae' + +NUM_LINES = { + 'train': 196884, + 'valid': 993, + 'test': 1305, +} + + +def _read_text_iterator(path): + with io.open(path, encoding="utf8") as f: + for row in f: + yield row + + +def _clean_xml_file(f_xml): + f_txt = os.path.splitext(f_xml)[0] + with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: + root = ET.parse(f_xml).getroot()[0] + for doc in root.findall('doc'): + for e in doc.findall('seg'): + fd_txt.write(e.text.strip() + '\n') + + +def _clean_tags_file(f_orig): + xml_tags = [ + '>> from torchtext.experimental.datasets.raw import IWSLT + >>> train_dataset, valid_dataset, test_dataset = IWSLT() + + The available datasets include: + IWSLT16.TED.dev2010.ar-en.ar + IWSLT16.TED.dev2010.ar-en.en + IWSLT16.TED.dev2010.cs-en.cs + IWSLT16.TED.dev2010.cs-en.en + IWSLT16.TED.dev2010.de-en.de + IWSLT16.TED.dev2010.de-en.en + IWSLT16.TED.dev2010.en-ar.ar + IWSLT16.TED.dev2010.en-ar.en + IWSLT16.TED.dev2010.en-cs.cs + IWSLT16.TED.dev2010.en-cs.en + IWSLT16.TED.dev2010.en-de.de + IWSLT16.TED.dev2010.en-de.en + IWSLT16.TED.dev2010.en-fr.en + IWSLT16.TED.dev2010.en-fr.fr + IWSLT16.TED.dev2010.fr-en.en + IWSLT16.TED.dev2010.fr-en.fr + IWSLT16.TED.tst2010.ar-en.ar + IWSLT16.TED.tst2010.ar-en.en + IWSLT16.TED.tst2010.cs-en.cs + IWSLT16.TED.tst2010.cs-en.en + IWSLT16.TED.tst2010.de-en.de + IWSLT16.TED.tst2010.de-en.en + IWSLT16.TED.tst2010.en-ar.ar + IWSLT16.TED.tst2010.en-ar.en + IWSLT16.TED.tst2010.en-cs.cs + IWSLT16.TED.tst2010.en-cs.en + IWSLT16.TED.tst2010.en-de.de + IWSLT16.TED.tst2010.en-de.en + IWSLT16.TED.tst2010.en-fr.en + IWSLT16.TED.tst2010.en-fr.fr + IWSLT16.TED.tst2010.fr-en.en + IWSLT16.TED.tst2010.fr-en.fr + IWSLT16.TED.tst2011.ar-en.ar + IWSLT16.TED.tst2011.ar-en.en + IWSLT16.TED.tst2011.cs-en.cs + IWSLT16.TED.tst2011.cs-en.en + IWSLT16.TED.tst2011.de-en.de + IWSLT16.TED.tst2011.de-en.en + IWSLT16.TED.tst2011.en-ar.ar + IWSLT16.TED.tst2011.en-ar.en + IWSLT16.TED.tst2011.en-cs.cs + IWSLT16.TED.tst2011.en-cs.en + IWSLT16.TED.tst2011.en-de.de + IWSLT16.TED.tst2011.en-de.en + IWSLT16.TED.tst2011.en-fr.en + IWSLT16.TED.tst2011.en-fr.fr + IWSLT16.TED.tst2011.fr-en.en + IWSLT16.TED.tst2011.fr-en.fr + IWSLT16.TED.tst2012.ar-en.ar + IWSLT16.TED.tst2012.ar-en.en + IWSLT16.TED.tst2012.cs-en.cs + IWSLT16.TED.tst2012.cs-en.en + IWSLT16.TED.tst2012.de-en.de + IWSLT16.TED.tst2012.de-en.en + IWSLT16.TED.tst2012.en-ar.ar + IWSLT16.TED.tst2012.en-ar.en + IWSLT16.TED.tst2012.en-cs.cs + IWSLT16.TED.tst2012.en-cs.en + IWSLT16.TED.tst2012.en-de.de + IWSLT16.TED.tst2012.en-de.en + IWSLT16.TED.tst2012.en-fr.en + IWSLT16.TED.tst2012.en-fr.fr + IWSLT16.TED.tst2012.fr-en.en + IWSLT16.TED.tst2012.fr-en.fr + IWSLT16.TED.tst2013.ar-en.ar + IWSLT16.TED.tst2013.ar-en.en + IWSLT16.TED.tst2013.cs-en.cs + IWSLT16.TED.tst2013.cs-en.en + IWSLT16.TED.tst2013.de-en.de + IWSLT16.TED.tst2013.de-en.en + IWSLT16.TED.tst2013.en-ar.ar + IWSLT16.TED.tst2013.en-ar.en + IWSLT16.TED.tst2013.en-cs.cs + IWSLT16.TED.tst2013.en-cs.en + IWSLT16.TED.tst2013.en-de.de + IWSLT16.TED.tst2013.en-de.en + IWSLT16.TED.tst2013.en-fr.en + IWSLT16.TED.tst2013.en-fr.fr + IWSLT16.TED.tst2013.fr-en.en + IWSLT16.TED.tst2013.fr-en.fr + IWSLT16.TED.tst2014.ar-en.ar + IWSLT16.TED.tst2014.ar-en.en + IWSLT16.TED.tst2014.de-en.de + IWSLT16.TED.tst2014.de-en.en + IWSLT16.TED.tst2014.en-ar.ar + IWSLT16.TED.tst2014.en-ar.en + IWSLT16.TED.tst2014.en-de.de + IWSLT16.TED.tst2014.en-de.en + IWSLT16.TED.tst2014.en-fr.en + IWSLT16.TED.tst2014.en-fr.fr + IWSLT16.TED.tst2014.fr-en.en + IWSLT16.TED.tst2014.fr-en.fr + IWSLT16.TEDX.dev2012.de-en.de + IWSLT16.TEDX.dev2012.de-en.en + IWSLT16.TEDX.tst2013.de-en.de + IWSLT16.TEDX.tst2013.de-en.en + IWSLT16.TEDX.tst2014.de-en.de + IWSLT16.TEDX.tst2014.de-en.en + train.ar + train.ar-en.ar + train.ar-en.en + train.cs + train.cs-en.cs + train.cs-en.en + train.de + train.de-en.de + train.de-en.en + train.en + train.en-ar.ar + train.en-ar.en + train.en-cs.cs + train.en-cs.en + train.en-de.de + train.en-de.en + train.en-fr.en + train.en-fr.fr + train.fr + train.fr-en.en + train.fr-en.fr + train.tags.ar-en.ar + train.tags.ar-en.en + train.tags.cs-en.cs + train.tags.cs-en.en + train.tags.de-en.de + train.tags.de-en.en + train.tags.en-ar.ar + train.tags.en-ar.en + train.tags.en-cs.cs + train.tags.en-cs.en + train.tags.en-de.de + train.tags.en-de.en + train.tags.en-fr.en + train.tags.en-fr.fr + train.tags.fr-en.en + train.tags.fr-en.fr + """ + if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ + and not isinstance(test_filenames, tuple): + raise ValueError("All filenames must be tuples") + src_train, tgt_train = train_filenames + src_eval, tgt_eval = valid_filenames + src_test, tgt_test = test_filenames + + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, path=os.path.join(root, _PATH), hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + extracted_files = [] # list of paths to the extracted files + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, + path=os.path.join(root, _PATH), hash_type='md5') + extracted_dataset_tar = extract_archive(dataset_tar) + # IWSLT dataset's url downloads a multilingual tgz. + # We need to take an extra step to pick out the specific language pair from it. + src_language = train_filenames[0].split(".")[-1] + tgt_language = train_filenames[1].split(".")[-1] + languages = "-".join([src_language, tgt_language]) + iwslt_tar = '.data/2016-01/texts/{}/{}/{}.tgz' + iwslt_tar = iwslt_tar.format( + src_language, tgt_language, languages) + extracted_dataset_tar = extract_archive(iwslt_tar) + extracted_files.extend(extracted_dataset_tar) + + # Clean the xml and tag file in the archives + file_archives = [] + for fname in extracted_files: + if 'xml' in fname: + _clean_xml_file(fname) + file_archives.append(os.path.splitext(fname)[0]) + elif "tags" in fname: + _clean_tags_file(fname) + file_archives.append(fname.replace('.tags', '')) + else: + file_archives.append(fname) + + data_filenames = { + "train": _construct_filepaths(file_archives, src_train, tgt_train), + "valid": _construct_filepaths(file_archives, src_eval, tgt_eval), + "test": _construct_filepaths(file_archives, src_test, tgt_test) + } + + for key in data_filenames.keys(): + if len(data_filenames[key]) == 0 or data_filenames[key] is None: + raise FileNotFoundError( + "Files are not found for data type {}".format(key)) + + datasets = [] + for key in split: + src_data_iter = _read_text_iterator(data_filenames[key][0]) + tgt_data_iter = _read_text_iterator(data_filenames[key][1]) + + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item + + datasets.append( + RawTextIterableDataset("IWSLT", NUM_LINES[key], _iter(src_data_iter, tgt_data_iter), offset=offset)) + + return datasets diff --git a/torchtext/experimental/datasets/raw/multi30k.py b/torchtext/experimental/datasets/raw/multi30k.py new file mode 100644 index 0000000000..73c852eeb4 --- /dev/null +++ b/torchtext/experimental/datasets/raw/multi30k.py @@ -0,0 +1,243 @@ +import io +from torchtext.utils import (download_from_url, extract_archive) +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header + +_URL_BASE_ = 'https://raw.githubusercontent.com/multi30k/dataset/master/data/task' + +URL = [ + '1/raw/test_2016_flickr.cs.gz', + '1/raw/test_2016_flickr.de.gz', + '1/raw/test_2016_flickr.en.gz', + '1/raw/test_2016_flickr.fr.gz', + '1/raw/test_2017_flickr.de.gz', + '1/raw/test_2017_flickr.en.gz', + '1/raw/test_2017_flickr.fr.gz', + '1/raw/test_2017_mscoco.de.gz', + '1/raw/test_2017_mscoco.en.gz', + '1/raw/test_2017_mscoco.fr.gz', + '1/raw/test_2018_flickr.en.gz', + '1/raw/train.cs.gz', + '1/raw/train.de.gz', + '1/raw/train.en.gz', + '1/raw/train.fr.gz', + '1/raw/val.cs.gz', + '1/raw/val.de.gz', + '1/raw/val.en.gz', + '1/raw/val.fr.gz', + '2/raw/test_2016.1.de.gz', + '2/raw/test_2016.1.en.gz', + '2/raw/test_2016.2.de.gz', + '2/raw/test_2016.2.en.gz', + '2/raw/test_2016.3.de.gz', + '2/raw/test_2016.3.en.gz', + '2/raw/test_2016.4.de.gz', + '2/raw/test_2016.4.en.gz', + '2/raw/test_2016.5.de.gz', + '2/raw/test_2016.5.en.gz', + '2/raw/train.1.de.gz', + '2/raw/train.1.en.gz', + '2/raw/train.2.de.gz', + '2/raw/train.2.en.gz', + '2/raw/train.3.de.gz', + '2/raw/train.3.en.gz', + '2/raw/train.4.de.gz', + '2/raw/train.4.en.gz', + '2/raw/train.5.de.gz', + '2/raw/train.5.en.gz', + '2/raw/val.1.de.gz', + '2/raw/val.1.en.gz', + '2/raw/val.2.de.gz', + '2/raw/val.2.en.gz', + '2/raw/val.3.de.gz', + '2/raw/val.3.en.gz', + '2/raw/val.4.de.gz', + '2/raw/val.4.en.gz', + '2/raw/val.5.de.gz', + '2/raw/val.5.en.gz' +] +URL = [_URL_BASE_ + u for u in URL] + +MD5 = [ + '3104872229daa1bef3b401d44dd2220b', + 'efd67d314d98489b716b145475101932', + 'ff2c0fcb4893a13bd73414306bc250ae', + '08dc7cd4a662f31718412de95ca9bfe3', + '6a8d5c87f6ae19e3d35681aa6fd16571', + '005396bac545d880abe6f00bbb7dbbb4', + 'cb09af7d2b501f9112f2d6a59fa1360d', + 'e8cd6ec2bc8a11fc846fa48a46e3d0bb', + 'a7b684e0edbef1d4a23660c8e8e743fd', + '4995d10954a804d3cdfd907b9fd093e8', + 'a152878809942757a55ce087073486b8', + 'd9a5fc268917725a2b0efce3a0cc8607', + '81ff90b99829c0cd4b1b587d394afd39', + '0065d13af80720a55ca8153d126e6627', + '6cb767741dcad3931f966fefbc05203f', + '83cdc082f646b769095615384cf5c0ca', + '6e0e229eb049e3fc99a1ef02fb2d5f91', + '2b69aa9253948ac9f67e94917272dd40', + '93fc564584b7e5ba410c761ea5a1c682', + 'ac0c72653c140dd96707212a1baa4278', + 'eec05227daba4bb8f3f8f25b1cb335f4', + '6dfb42cae4e4fd9a3c40e62ff5398a55', + '9318fa08c0c0b96114eadb10eb2fc633', + 'ece8cec6b87bf00dd12607f3062dae4c', + '088ec0765fa213a0eb937a62adfd4996', + '9a7e7b2dcc33135a32cd621c3b37d2d8', + '5f7c8d0be0ac739856b47d32a9434998', + '7d5ef0f069ee2d74dc2fdc6b46cd47fa', + '713ed720636622a54546d5f14f88b00f', + '62f36422bfab90fb42a560546b704009', + 'cbf5bfc2147706f228d288e1b18bf4af', + '540da4566bb6dd35fdbc720218b742b7', + 'bdfe4222f4692ccaa1e3389460f0890e', + '613eb4a3f0c2b13f0871ced946851b0e', + '0e1ee2b4145795bd180b193424db204b', + 'd848fe0ae8b9447209fb49c5c31cb3d2', + '1cff688d1aadef7fdb22e9ad27d6fd2c', + 'abc13b4042f4fef1cdff6de3b6c53b71', + '3e10289959d0059952511c31df3c7550', + 'b26486ede1d4436d5acf6e38c65bb44d', + 'df57faf5f00d434d2559c021ef55f1aa', + '16165248083beacebfe18866d5f4f0ae', + '9077a5127480cc799116384de501bd70', + '7180780822d4b600eb81c1ccf171c230', + 'c1f697c3b6dfb7305349db34e26b45fc', + '8edb43c90cae66ec762748a968089b99', + 'acb5ea26a577ceccfae6337181c31716', + '873a377a348713d3ab84db1fb57cdede', + '680816e0938fea5cf5331444bc09a4cf' +] + +NUM_LINES = { + 'train': 29000, + 'valid': 1014, + 'test': 1000, +} + + +def _read_text_iterator(path): + with io.open(path, encoding="utf8") as f: + for row in f: + yield row + + +def _construct_filepaths(paths, src_filename, tgt_filename): + src_path = None + tgt_path = None + for p in paths: + src_path = p if src_filename in p else src_path + tgt_path = p if tgt_filename in p else tgt_path + return (src_path, tgt_path) + + +@wrap_split_argument +@add_docstring_header() +def Multi30k(root='.data', split=('train', 'valid', 'test'), offset=0, + train_filenames=("train.de", "train.en"), + valid_filenames=("val.de", "val.en"), + test_filenames=("test_2016_flickr.de", "test_2016_flickr.en")): + """ train_filenames: the source and target filenames for training. + Default: ('train.de', 'train.en') + valid_filenames: the source and target filenames for valid. + Default: ('val.de', 'val.en') + test_filenames: the source and target filenames for test. + Default: ('test2016.de', 'test2016.en') + + Examples: + >>> from torchtext.experimental.datasets.raw import Multi30k + >>> train_dataset, valid_dataset, test_dataset = Multi30k() + + The available dataset include: + test_2016_flickr.cs + test_2016_flickr.de + test_2016_flickr.en + test_2016_flickr.fr + test_2017_flickr.de + test_2017_flickr.en + test_2017_flickr.fr + test_2017_mscoco.de + test_2017_mscoco.en + test_2017_mscoco.fr + test_2018_flickr.en + train.cs + train.de + train.en + train.fr + val.cs + val.de + val.en + val.fr + test_2016.1.de + test_2016.1.en + test_2016.2.de + test_2016.2.en + test_2016.3.de + test_2016.3.en + test_2016.4.de + test_2016.4.en + test_2016.5.de + test_2016.5.en + train.1.de + train.1.en + train.2.de + train.2.en + train.3.de + train.3.en + train.4.de + train.4.en + train.5.de + train.5.en + val.1.de + val.1.en + val.2.de + val.2.en + val.3.de + val.3.en + val.4.de + val.4.en + val.5.de + val.5.en + """ + if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ + and not isinstance(test_filenames, tuple): + raise ValueError("All filenames must be tuples") + src_train, tgt_train = train_filenames + src_eval, tgt_eval = valid_filenames + src_test, tgt_test = test_filenames + + extracted_files = [] # list of paths to the extracted files + + for idx, f in enumerate(URL): + dataset_tar = download_from_url( + f, root=root, hash_value=MD5[idx], hash_type='md5') + extracted_files.extend(extract_archive(dataset_tar)) + + file_archives = extracted_files + + data_filenames = { + "train": _construct_filepaths(file_archives, src_train, tgt_train), + "valid": _construct_filepaths(file_archives, src_eval, tgt_eval), + "test": _construct_filepaths(file_archives, src_test, tgt_test) + } + + for key in data_filenames.keys(): + if len(data_filenames[key]) == 0 or data_filenames[key] is None: + raise FileNotFoundError( + "Files are not found for data type {}".format(key)) + + datasets = [] + for key in split: + src_data_iter = _read_text_iterator(data_filenames[key][0]) + tgt_data_iter = _read_text_iterator(data_filenames[key][1]) + + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item + + datasets.append( + RawTextIterableDataset("Multi30k", NUM_LINES[key], _iter(src_data_iter, tgt_data_iter), offset=offset)) + + return datasets diff --git a/torchtext/experimental/datasets/raw/penntreebank.py b/torchtext/experimental/datasets/raw/penntreebank.py new file mode 100644 index 0000000000..f2b50dc7af --- /dev/null +++ b/torchtext/experimental/datasets/raw/penntreebank.py @@ -0,0 +1,43 @@ +import logging +from torchtext.utils import download_from_url +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import io + +URL = { + 'train': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", + 'test': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", + 'valid': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt", +} + +MD5 = { + 'train': "f26c4b92c5fdc7b3f8c7cdcb991d8420", + 'valid': "aa0affc06ff7c36e977d7cd49e3839bf", + 'test': "8b80168b89c18661a38ef683c0dc3721", +} + +NUM_LINES = { + 'train': 42068, + 'valid': 3370, + 'test': 3761, +} + + +@wrap_split_argument +@add_docstring_header() +def PennTreebank(root='.data', split=('train', 'valid', 'test'), offset=0): + extracted_files = [download_from_url(URL[key], + root=root, hash_value=MD5[key], + hash_type='md5') for key in split] + datasets = [] + for item in split: + path = find_match(item, extracted_files) + logging.info('Creating {} data'.format(item)) + datasets.append(RawTextIterableDataset('PennTreebank', + NUM_LINES[item], + iter(io.open(path, encoding="utf8")), + offset=offset)) + + return datasets diff --git a/torchtext/experimental/datasets/raw/sogounews.py b/torchtext/experimental/datasets/raw/sogounews.py new file mode 100644 index 0000000000..51565443aa --- /dev/null +++ b/torchtext/experimental/datasets/raw/sogounews.py @@ -0,0 +1,39 @@ +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE' + +MD5 = '0c1700ba70b73f964dd8de569d3fd03e' + +NUM_LINES = { + 'train': 450000, + 'test': 60000, +} + +_PATH = 'sogou_news_csv.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def SogouNews(root='.data', split=('train', 'test'), offset=0): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + dataset_tar = download_from_url(URL, root=root, + path=os.path.join(root, _PATH), + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("SogouNews", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/squad1.py b/torchtext/experimental/datasets/raw/squad1.py new file mode 100644 index 0000000000..97962c42ec --- /dev/null +++ b/torchtext/experimental/datasets/raw/squad1.py @@ -0,0 +1,45 @@ +from torchtext.utils import download_from_url +import json +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header + +URL = { + 'train': "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", + 'dev': "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json", +} + +MD5 = { + 'train': "981b29407e0affa3b1b156f72073b945", + 'dev': "3e85deb501d4e538b6bc56f786231552", +} + +NUM_LINES = { + 'train': 87599, + 'dev': 10570, +} + + +def _create_data_from_json(data_path): + with open(data_path) as json_file: + raw_json_data = json.load(json_file)['data'] + for layer1 in raw_json_data: + for layer2 in layer1['paragraphs']: + for layer3 in layer2['qas']: + _context, _question = layer2['context'], layer3['question'] + _answers = [item['text'] for item in layer3['answers']] + _answer_start = [item['answer_start'] for item in layer3['answers']] + if len(_answers) == 0: + _answers = [""] + _answer_start = [-1] + # yield the raw data in the order of context, question, answers, answer_start + yield (_context, _question, _answers, _answer_start) + + +@wrap_split_argument +@add_docstring_header() +def SQuAD1(root='.data', split=('train', 'dev'), offset=0): + extracted_files = {key: download_from_url(URL[key], root=root, + hash_value=MD5[key], hash_type='md5') for key in split} + return [RawTextIterableDataset('SQuAD1', NUM_LINES[item], + _create_data_from_json(extracted_files[item]), offset=offset) for item in split] diff --git a/torchtext/experimental/datasets/raw/squad2.py b/torchtext/experimental/datasets/raw/squad2.py new file mode 100644 index 0000000000..a61e305429 --- /dev/null +++ b/torchtext/experimental/datasets/raw/squad2.py @@ -0,0 +1,45 @@ +from torchtext.utils import download_from_url +import json +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header + +URL = { + 'train': "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", + 'dev': "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json", +} + +MD5 = { + 'train': "62108c273c268d70893182d5cf8df740", + 'dev': "246adae8b7002f8679c027697b0b7cf8", +} + +NUM_LINES = { + 'train': 130319, + 'dev': 11873, +} + + +def _create_data_from_json(data_path): + with open(data_path) as json_file: + raw_json_data = json.load(json_file)['data'] + for layer1 in raw_json_data: + for layer2 in layer1['paragraphs']: + for layer3 in layer2['qas']: + _context, _question = layer2['context'], layer3['question'] + _answers = [item['text'] for item in layer3['answers']] + _answer_start = [item['answer_start'] for item in layer3['answers']] + if len(_answers) == 0: + _answers = [""] + _answer_start = [-1] + # yield the raw data in the order of context, question, answers, answer_start + yield (_context, _question, _answers, _answer_start) + + +@wrap_split_argument +@add_docstring_header() +def SQuAD2(root='.data', split=('train', 'dev'), offset=0): + extracted_files = {key: download_from_url(URL[key], root=root, + hash_value=MD5[key], hash_type='md5') for key in split} + return [RawTextIterableDataset('SQuAD2', NUM_LINES[item], + _create_data_from_json(extracted_files[item]), offset=offset) for item in split] diff --git a/torchtext/experimental/datasets/raw/udpos.py b/torchtext/experimental/datasets/raw/udpos.py new file mode 100644 index 0000000000..a7e3a8e0ea --- /dev/null +++ b/torchtext/experimental/datasets/raw/udpos.py @@ -0,0 +1,57 @@ +from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header + +URL = 'https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip' + +MD5 = 'bdcac7c52d934656bae1699541424545' + +NUM_LINES = { + 'train': 12543, + 'valid': 2002, + 'test': 2077, +} + + +def _create_data_from_iob(data_path, separator="\t"): + with open(data_path, encoding="utf-8") as input_file: + columns = [] + for line in input_file: + line = line.strip() + if line == "": + if columns: + yield columns + columns = [] + else: + for i, column in enumerate(line.split(separator)): + if len(columns) < i + 1: + columns.append([]) + columns[i].append(column) + if len(columns) > 0: + yield columns + + +def _construct_filepath(paths, file_suffix): + if file_suffix: + path = None + for p in paths: + path = p if p.endswith(file_suffix) else path + return path + return None + + +@wrap_split_argument +@add_docstring_header() +def UDPOS(root='.data', split=('train', 'valid', 'test'), offset=0): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + data_filenames = { + "train": _construct_filepath(extracted_files, "train.txt"), + "valid": _construct_filepath(extracted_files, "dev.txt"), + "test": _construct_filepath(extracted_files, "test.txt") + } + return [RawTextIterableDataset("UDPOS", NUM_LINES[item], + _create_data_from_iob(data_filenames[item]), offset=offset) + if data_filenames[item] is not None else None for item in split] diff --git a/torchtext/experimental/datasets/raw/wikitext103.py b/torchtext/experimental/datasets/raw/wikitext103.py new file mode 100644 index 0000000000..ea75f1efe6 --- /dev/null +++ b/torchtext/experimental/datasets/raw/wikitext103.py @@ -0,0 +1,31 @@ +import logging +from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import io + +URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip' + +MD5 = '9ddaacaf6af0710eda8c456decff7832' + +NUM_LINES = { + 'train': 1801350, + 'valid': 3760, + 'test': 4358, +} + + +@wrap_split_argument +@add_docstring_header() +def WikiText103(root='.data', split=('train', 'valid', 'test'), offset=0): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + datasets = [] + for item in split: + path = find_match(item, extracted_files) + logging.info('Creating {} data'.format(item)) + datasets.append(RawTextIterableDataset('WikiText103', + NUM_LINES[item], iter(io.open(path, encoding="utf8")), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/wikitext2.py b/torchtext/experimental/datasets/raw/wikitext2.py new file mode 100644 index 0000000000..a6f9a02a9c --- /dev/null +++ b/torchtext/experimental/datasets/raw/wikitext2.py @@ -0,0 +1,31 @@ +import logging +from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import io + +URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip' + +MD5 = '542ccefacc6c27f945fb54453812b3cd' + +NUM_LINES = { + 'train': 36718, + 'valid': 3760, + 'test': 4358, +} + + +@wrap_split_argument +@add_docstring_header() +def WikiText2(root='.data', split=('train', 'valid', 'test'), offset=0): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + datasets = [] + for item in split: + path = find_match(item, extracted_files) + logging.info('Creating {} data'.format(item)) + datasets.append(RawTextIterableDataset('WikiText2', + NUM_LINES[item], iter(io.open(path, encoding="utf8")), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/wmt14.py b/torchtext/experimental/datasets/raw/wmt14.py new file mode 100644 index 0000000000..f610df417a --- /dev/null +++ b/torchtext/experimental/datasets/raw/wmt14.py @@ -0,0 +1,188 @@ +import os +import io +import codecs +import xml.etree.ElementTree as ET +from torchtext.utils import (download_from_url, extract_archive) +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header + +URL = 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8' + +_PATH = 'wmt16_en_de.tar.gz' + +MD5 = '874ab6bbfe9c21ec987ed1b9347f95ec' + +NUM_LINES = { + 'train': 4500966, + 'valid': 3000, + 'test': 3003, +} + + +def _read_text_iterator(path): + with io.open(path, encoding="utf8") as f: + for row in f: + yield row + + +def _clean_xml_file(f_xml): + f_txt = os.path.splitext(f_xml)[0] + with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: + root = ET.parse(f_xml).getroot()[0] + for doc in root.findall('doc'): + for e in doc.findall('seg'): + fd_txt.write(e.text.strip() + '\n') + + +def _clean_tags_file(f_orig): + xml_tags = [ + '>> from torchtext.experimental.datasets.raw import WMT14 + >>> train_dataset, valid_dataset, test_dataset = WMT14() + + The available datasets include: + newstest2016.en + newstest2016.de + newstest2015.en + newstest2015.de + newstest2014.en + newstest2014.de + newstest2013.en + newstest2013.de + newstest2012.en + newstest2012.de + newstest2011.tok.de + newstest2011.en + newstest2011.de + newstest2010.tok.de + newstest2010.en + newstest2010.de + newstest2009.tok.de + newstest2009.en + newstest2009.de + newstest2016.tok.de + newstest2015.tok.de + newstest2014.tok.de + newstest2013.tok.de + newstest2012.tok.de + newstest2010.tok.en + newstest2009.tok.en + newstest2015.tok.en + newstest2014.tok.en + newstest2013.tok.en + newstest2012.tok.en + newstest2011.tok.en + newstest2016.tok.en + newstest2009.tok.bpe.32000.en + newstest2011.tok.bpe.32000.en + newstest2010.tok.bpe.32000.en + newstest2013.tok.bpe.32000.en + newstest2012.tok.bpe.32000.en + newstest2015.tok.bpe.32000.en + newstest2014.tok.bpe.32000.en + newstest2016.tok.bpe.32000.en + train.tok.clean.bpe.32000.en + newstest2009.tok.bpe.32000.de + newstest2010.tok.bpe.32000.de + newstest2011.tok.bpe.32000.de + newstest2013.tok.bpe.32000.de + newstest2012.tok.bpe.32000.de + newstest2014.tok.bpe.32000.de + newstest2016.tok.bpe.32000.de + newstest2015.tok.bpe.32000.de + train.tok.clean.bpe.32000.de + """ + if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ + and not isinstance(test_filenames, tuple): + raise ValueError("All filenames must be tuples") + src_train, tgt_train = train_filenames + src_eval, tgt_eval = valid_filenames + src_test, tgt_test = test_filenames + + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, path=os.path.join(root, _PATH), hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + # Clean the xml and tag file in the archives + file_archives = [] + for fname in extracted_files: + if 'xml' in fname: + _clean_xml_file(fname) + file_archives.append(os.path.splitext(fname)[0]) + elif "tags" in fname: + _clean_tags_file(fname) + file_archives.append(fname.replace('.tags', '')) + else: + file_archives.append(fname) + + data_filenames = { + "train": _construct_filepaths(file_archives, src_train, tgt_train), + "valid": _construct_filepaths(file_archives, src_eval, tgt_eval), + "test": _construct_filepaths(file_archives, src_test, tgt_test) + } + + for key in data_filenames.keys(): + if len(data_filenames[key]) == 0 or data_filenames[key] is None: + raise FileNotFoundError( + "Files are not found for data type {}".format(key)) + + datasets = [] + for key in split: + src_data_iter = _read_text_iterator(data_filenames[key][0]) + tgt_data_iter = _read_text_iterator(data_filenames[key][1]) + + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item + + datasets.append( + RawTextIterableDataset("WMT14", NUM_LINES[key], _iter(src_data_iter, tgt_data_iter), offset=offset)) + + return datasets diff --git a/torchtext/experimental/datasets/raw/wmtnewscrawl.py b/torchtext/experimental/datasets/raw/wmtnewscrawl.py new file mode 100644 index 0000000000..6c16c6dee3 --- /dev/null +++ b/torchtext/experimental/datasets/raw/wmtnewscrawl.py @@ -0,0 +1,32 @@ +import logging +from torchtext.utils import download_from_url, extract_archive +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import io + +URL = 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' + +MD5 = 'c70da2ba79db33fb0fc9119cbad16260' + +NUM_LINES = { + 'train': 17676013, +} + + +@wrap_split_argument +@add_docstring_header() +def WMTNewsCrawl(root='.data', split='train', offset=0): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + file_name = 'news.{}.{}.shuffled'.format(year, language) + extracted_files = [f for f in extracted_files if file_name in f] + + datasets = [] + for item in split: + path = find_match(item, extracted_files) + logging.info('Creating {} data'.format(item)) + datasets.append(RawTextIterableDataset('WMTNewsCrawl', + NUM_LINES[item], iter(io.open(path, encoding="utf8")), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/yahooanswers.py b/torchtext/experimental/datasets/raw/yahooanswers.py new file mode 100644 index 0000000000..563c6008e2 --- /dev/null +++ b/torchtext/experimental/datasets/raw/yahooanswers.py @@ -0,0 +1,39 @@ +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU' + +MD5 = 'f3f9899b997a42beb24157e62e3eea8d' + +NUM_LINES = { + 'train': 1400000, + 'test': 60000, +} + +_PATH = 'yahoo_answers_csv.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def YahooAnswers(root='.data', split=('train', 'test'), offset=0): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + dataset_tar = download_from_url(URL, root=root, + path=os.path.join(root, _PATH), + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("YahooAnswers", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/yelpreviewfull.py b/torchtext/experimental/datasets/raw/yelpreviewfull.py new file mode 100644 index 0000000000..eca3648fbd --- /dev/null +++ b/torchtext/experimental/datasets/raw/yelpreviewfull.py @@ -0,0 +1,39 @@ +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0' + +MD5 = 'f7ddfafed1033f68ec72b9267863af6c' + +NUM_LINES = { + 'train': 650000, + 'test': 50000, +} + +_PATH = 'yelp_review_full_csv.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def YelpReviewFull(root='.data', split=('train', 'test'), offset=0): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + dataset_tar = download_from_url(URL, root=root, + path=os.path.join(root, _PATH), + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("YelpReviewFull", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/raw/yelpreviewpolarity.py b/torchtext/experimental/datasets/raw/yelpreviewpolarity.py new file mode 100644 index 0000000000..22e82618a7 --- /dev/null +++ b/torchtext/experimental/datasets/raw/yelpreviewpolarity.py @@ -0,0 +1,39 @@ +from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader +from torchtext.experimental.datasets.raw.common import RawTextIterableDataset +from torchtext.experimental.datasets.raw.common import wrap_split_argument +from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.experimental.datasets.raw.common import find_match +import os +import io + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg' + +MD5 = '620c8ae4bd5a150b730f1ba9a7c6a4d3' + +NUM_LINES = { + 'train': 560000, + 'test': 38000, +} + +_PATH = 'yelp_review_polarity_csv.tar.gz' + + +@wrap_split_argument +@add_docstring_header() +def YelpReviewPolarity(root='.data', split=('train', 'test'), offset=0): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + dataset_tar = download_from_url(URL, root=root, + path=os.path.join(root, _PATH), + hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + datasets = [] + for item in split: + path = find_match(item + '.csv', extracted_files) + datasets.append(RawTextIterableDataset("YelpReviewPolarity", NUM_LINES[item], + _create_data_from_csv(path), offset=offset)) + return datasets diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index 2ff9ee873b..fe64e67bc4 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -1,6 +1,7 @@ import torch import logging from torchtext.experimental.datasets.raw.common import check_default_set +from torchtext.experimental.datasets.raw.common import wrap_datasets from torchtext.experimental.datasets import raw from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.functional import ( @@ -26,8 +27,8 @@ def build_vocab(data): return vocabs -def _setup_datasets(dataset_name, root, vocabs, split): - split = check_default_set(split, ('train', 'valid', 'test')) +def _setup_datasets(dataset_name, root, vocabs, split_): + split = check_default_set(split_, ('train', 'valid', 'test'), dataset_name) raw_iter_tuple = raw.DATASETS[dataset_name](root=root, split=split) raw_data = {} for name, raw_iter in zip(split, raw_iter_tuple): @@ -59,7 +60,7 @@ def _setup_datasets(dataset_name, root, vocabs, split): for idx in range(len(vocabs)) ] logger_.info('Building datasets for {}'.format(split)) - return tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in split) + return wrap_datasets(tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in split), split_) class SequenceTaggingDataset(torch.utils.data.Dataset): diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index f968cc518b..01a5e29557 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -2,8 +2,9 @@ import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets.raw import text_classification as raw +from torchtext.experimental.datasets import raw from torchtext.experimental.datasets.raw.common import check_default_set +from torchtext.experimental.datasets.raw.common import wrap_datasets from torchtext.experimental.functional import ( vocab_func, totensor, @@ -69,12 +70,12 @@ def get_vocab(self): return self.vocab -def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, split): +def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, split_): text_transform = [] if tokenizer is None: tokenizer = get_tokenizer("basic_english") text_transform = sequential_transforms(tokenizer, ngrams_func(ngrams)) - split = check_default_set(split, ('train', 'test')) + split = check_default_set(split_, ('train', 'test'), dataset_name) raw_datasets = raw.DATASETS[dataset_name](root=root, split=split) # Materialize raw text iterable dataset raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} @@ -93,12 +94,12 @@ def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, split): else: label_transform = sequential_transforms(totensor(dtype=torch.long)) logger_.info('Building datasets for {}'.format(split)) - return tuple( + return wrap_datasets(tuple( TextClassificationDataset( raw_data[item], vocab, (label_transform, text_transform) ) for item in split - ) + ), split_) def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'test')): @@ -137,7 +138,7 @@ def AG_NEWS(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', >>> train, test = AG_NEWS(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = AG_NEWS(tokenizer=tokenizer) - >>> train, = AG_NEWS(tokenizer=tokenizer, split='train') + >>> train = AG_NEWS(tokenizer=tokenizer, split='train') """ @@ -181,7 +182,7 @@ def SogouNews(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train' >>> train, test = SogouNews(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = SogouNews(tokenizer=tokenizer) - >>> train, = SogouNews(tokenizer=tokenizer, split='train') + >>> train = SogouNews(tokenizer=tokenizer, split='train') """ @@ -234,7 +235,7 @@ def DBpedia(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', >>> train, test = DBpedia(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = DBpedia(tokenizer=tokenizer) - >>> train, = DBpedia(tokenizer=tokenizer, split='train') + >>> train = DBpedia(tokenizer=tokenizer, split='train') """ @@ -275,7 +276,7 @@ def YelpReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, split >>> train, test = YelpReviewPolarity(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = YelpReviewPolarity(tokenizer=tokenizer) - >>> train, = YelpReviewPolarity(tokenizer=tokenizer, split='train') + >>> train = YelpReviewPolarity(tokenizer=tokenizer, split='train') """ @@ -315,7 +316,7 @@ def YelpReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('t >>> train, test = YelpReviewFull(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = YelpReviewFull(tokenizer=tokenizer) - >>> train, = YelpReviewFull(tokenizer=tokenizer, split='train') + >>> train = YelpReviewFull(tokenizer=tokenizer, split='train') """ @@ -364,7 +365,7 @@ def YahooAnswers(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('tra >>> train, test = YahooAnswers(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = YahooAnswers(tokenizer=tokenizer) - >>> train, = YahooAnswers(tokenizer=tokenizer, split='train') + >>> train = YahooAnswers(tokenizer=tokenizer, split='train') """ @@ -405,7 +406,7 @@ def AmazonReviewPolarity(root='.data', ngrams=1, vocab=None, tokenizer=None, spl >>> train, test = AmazonReviewPolarity(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = AmazonReviewPolarity(tokenizer=tokenizer) - >>> train, = AmazonReviewPolarity(tokenizer=tokenizer, split='train') + >>> train = AmazonReviewPolarity(tokenizer=tokenizer, split='train') """ @@ -445,7 +446,7 @@ def AmazonReviewFull(root='.data', ngrams=1, vocab=None, tokenizer=None, split=( >>> train, test = AmazonReviewFull(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = AmazonReviewFull(tokenizer=tokenizer) - >>> train, = AmazonReviewFull(tokenizer=tokenizer, split='train') + >>> train = AmazonReviewFull(tokenizer=tokenizer, split='train') """ @@ -487,7 +488,7 @@ def IMDB(root='.data', ngrams=1, vocab=None, tokenizer=None, split=('train', 'te >>> train, test = IMDB(ngrams=3) >>> tokenizer = get_tokenizer("spacy") >>> train, test = IMDB(tokenizer=tokenizer) - >>> train, = IMDB(tokenizer=tokenizer, split='train') + >>> train = IMDB(tokenizer=tokenizer, split='train') """ diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index 1429b509ef..ce7077be6c 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -1,6 +1,7 @@ import torch import logging from torchtext.experimental.datasets.raw.common import check_default_set +from torchtext.experimental.datasets.raw.common import wrap_datasets from torchtext.experimental.datasets import raw from torchtext.vocab import Vocab, build_vocab_from_iterator from torchtext.data.utils import get_tokenizer @@ -18,8 +19,8 @@ def apply_transforms(data): def _setup_datasets(dataset_name, train_filenames, valid_filenames, test_filenames, - split, root, vocab, tokenizer): - split = check_default_set(split, ('train', 'valid', 'test')) + split_, root, vocab, tokenizer): + split = check_default_set(split_, ('train', 'valid', 'test'), dataset_name) src_vocab, tgt_vocab = vocab if tokenizer is None: src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') @@ -79,7 +80,7 @@ def _setup_datasets(dataset_name, TranslationDataset(raw_data[key], (src_vocab, tgt_vocab), (src_text_transform, tgt_text_transform))) - return tuple(datasets) + return wrap_datasets(tuple(datasets), split_) class TranslationDataset(torch.utils.data.Dataset): @@ -139,7 +140,6 @@ def Multi30k(train_filenames=("train.de", "train.en"), root='.data', vocab=(None, None), tokenizer=None): - """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple @@ -240,7 +240,6 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), root='.data', vocab=(None, None), tokenizer=None): - """ Define translation datasets: IWSLT Separately returns train/valid/test datasets The available datasets include: @@ -430,7 +429,6 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', root='.data', vocab=(None, None), tokenizer=None): - """ Define translation datasets: WMT14 Separately returns train/valid/test datasets The available datasets include: diff --git a/torchtext/experimental/vectors.py b/torchtext/experimental/vectors.py index e7779d9ad4..9ebab526ae 100644 --- a/torchtext/experimental/vectors.py +++ b/torchtext/experimental/vectors.py @@ -38,7 +38,7 @@ def FastText(language="en", unk_tensor=None, root=".data", validate_file=True, n num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. Returns: - Vectors: a Vectors object. + torchtext.experimental.vectors.Vector: a Vectors object. Raises: ValueError: if duplicate tokens are found in FastText file. @@ -99,7 +99,7 @@ def GloVe(name="840B", dim=300, unk_tensor=None, root=".data", validate_file=Tru Should be `False` when running tests with a local asset. num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 10. Returns: - Vectors: a Vectors object. + torchtext.experimental.vectors.Vector: a Vectors object. Raises: ValueError: if unexpected duplicate tokens are found in GloVe file. @@ -185,6 +185,7 @@ def load_vectors_from_file_path(filepath, delimiter=",", unk_tensor=None, num_cp def build_vectors(tokens, vectors, unk_tensor=None): r"""Factory method for creating a vectors object which maps tokens to vectors. + Args: tokens (List[str]): a list of tokens. vectors (torch.Tensor): a 2d tensor representing the vector associated with each token. @@ -208,6 +209,7 @@ def build_vectors(tokens, vectors, unk_tensor=None): class Vectors(nn.Module): __jit_unused_properties__ = ["is_jitable"] r"""Creates a vectors object which maps tokens to vectors. + Args: vectors (torch.classes.torchtext.Vectors or torchtext._torchtext.Vectors): a cpp vectors object. """ @@ -223,6 +225,7 @@ def is_jitable(self): @torch.jit.export def forward(self, tokens: List[str]) -> Tensor: r"""Calls the `lookup_vectors` method + Args: tokens: a list of string tokens @@ -269,6 +272,7 @@ def __len__(self) -> int: @torch.jit.export def lookup_vectors(self, tokens: List[str]) -> Tensor: """Look up embedding vectors for a list of tokens. + Args: tokens: a list of tokens diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 606965daa9..2f13b083d6 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -35,7 +35,7 @@ def build_vocab_from_text_file(file_object, jited_tokenizer, min_freq=1, unk_tok num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. Returns: - Vocab: a `Vocab` object. + torchtext.experimental.vocab.Vocab: a `Vocab` object. Examples: >>> from torchtext.experimental.vocab import build_vocab_from_text_file @@ -69,7 +69,7 @@ def load_vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4) num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. Returns: - Vocab: a `Vocab` object. + torchtext.experimental.vocab.Vocab: a `Vocab` object. Examples: >>> from torchtext.experimental.vocab import load_vocab_from_file @@ -162,6 +162,7 @@ def is_jitable(self): @torch.jit.export def forward(self, tokens: List[str]) -> List[int]: r"""Calls the `lookup_indices` method + Args: tokens (List[str]): a list of tokens used to lookup their corresponding `indices`. diff --git a/torchtext/legacy/datasets/imdb.py b/torchtext/legacy/datasets/imdb.py index 38fccb97be..e59ce19ecb 100644 --- a/torchtext/legacy/datasets/imdb.py +++ b/torchtext/legacy/datasets/imdb.py @@ -18,7 +18,7 @@ def sort_key(ex): def __init__(self, path, text_field, label_field, **kwargs): """Create an IMDB dataset instance given a path and fields. - Arguments: + Args: path: Path to the dataset's highest level directory text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -41,7 +41,7 @@ def splits(cls, text_field, label_field, root='.data', train='train', test='test', **kwargs): """Create dataset objects for splits of the IMDB dataset. - Arguments: + Args: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: Root dataset storage directory. Default is '.data'. @@ -58,7 +58,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the IMDB dataset. - Arguments: + Args: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/legacy/datasets/language_modeling.py b/torchtext/legacy/datasets/language_modeling.py index 775fe51d9e..ab297ca815 100644 --- a/torchtext/legacy/datasets/language_modeling.py +++ b/torchtext/legacy/datasets/language_modeling.py @@ -9,7 +9,7 @@ def __init__(self, path, text_field, newline_eos=True, encoding='utf-8', **kwargs): """Create a LanguageModelingDataset given a path and a field. - Arguments: + Args: path: Path to the data file. text_field: The field that will be used for text data. newline_eos: Whether to add an token for every newline in the @@ -44,7 +44,7 @@ def splits(cls, text_field, root='.data', train='wiki.train.tokens', This is the most flexible way to use the dataset. - Arguments: + Args: text_field: The field that will be used for text data. root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-2 @@ -67,7 +67,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for @@ -105,7 +105,7 @@ def splits(cls, text_field, root='.data', train='wiki.train.tokens', This is the most flexible way to use the dataset. - Arguments: + Args: text_field: The field that will be used for text data. root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-103 @@ -128,7 +128,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for @@ -156,8 +156,7 @@ class PennTreebank(LanguageModelingDataset): """The Penn Treebank dataset. A relatively small dataset originally created for POS tagging. - References - ---------- + References: Marcus, Mitchell P., Marcinkiewicz, Mary Ann & Santorini, Beatrice (1993). Building a Large Annotated Corpus of English: The Penn Treebank """ @@ -174,7 +173,7 @@ def splits(cls, text_field, root='.data', train='ptb.train.txt', **kwargs): """Create dataset objects for splits of the Penn Treebank dataset. - Arguments: + Args: text_field: The field that will be used for text data. root: The root directory where the data files will be stored. train: The filename of the train data. Default: 'ptb.train.txt'. @@ -195,7 +194,7 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. bptt_len: Length of sequences for backpropagation through time. device: Device to create batches on. Use -1 for CPU and None for diff --git a/torchtext/legacy/datasets/nli.py b/torchtext/legacy/datasets/nli.py index 453b35d584..78a4a172f4 100644 --- a/torchtext/legacy/datasets/nli.py +++ b/torchtext/legacy/datasets/nli.py @@ -51,7 +51,7 @@ def splits(cls, text_field, label_field, parse_field=None, This is the most flexible way to use the dataset. - Arguments: + Args: text_field: The field that will be used for premise and hypothesis data. label_field: The field that will be used for label data. @@ -98,7 +98,7 @@ def iters(cls, batch_size=32, device=0, root='.data', This is the simplest way to use the dataset, and assumes common defaults for field, vocabulary, and iterator parameters. - Arguments: + Args: batch_size: Batch size. device: Device to create batches on. Use -1 for CPU and None for the currently active GPU device. diff --git a/torchtext/legacy/datasets/sequence_tagging.py b/torchtext/legacy/datasets/sequence_tagging.py index 1450369efc..849d8be15d 100644 --- a/torchtext/legacy/datasets/sequence_tagging.py +++ b/torchtext/legacy/datasets/sequence_tagging.py @@ -78,8 +78,7 @@ class CoNLL2000Chunking(SequenceTaggingDataset): def splits(cls, fields, root=".data", train="train.txt", test="test.txt", validation_frac=0.1, **kwargs): """Downloads and loads the CoNLL 2000 Chunking dataset. - NOTE: There is only a train and test dataset so we use - 10% of the train set as validation + NOTE: There is only a train and test dataset so we use 10% of the train set as validation """ train, test = super(CoNLL2000Chunking, cls).splits( diff --git a/torchtext/legacy/datasets/sst.py b/torchtext/legacy/datasets/sst.py index 95a04e3f6b..8c793fad93 100644 --- a/torchtext/legacy/datasets/sst.py +++ b/torchtext/legacy/datasets/sst.py @@ -17,7 +17,7 @@ def __init__(self, path, text_field, label_field, subtrees=False, fine_grained=False, **kwargs): """Create an SST dataset instance given a path and fields. - Arguments: + Args: path: Path to the data file text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -49,7 +49,7 @@ def splits(cls, text_field, label_field, root='.data', train_subtrees=False, **kwargs): """Create dataset objects for splits of the SST dataset. - Arguments: + Args: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: The root directory that the dataset's zip archive will be @@ -81,7 +81,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the SST dataset. - Arguments: + Args: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/legacy/datasets/text_classification.py b/torchtext/legacy/datasets/text_classification.py index fc08876a34..f50c3b9d8b 100644 --- a/torchtext/legacy/datasets/text_classification.py +++ b/torchtext/legacy/datasets/text_classification.py @@ -144,11 +144,13 @@ def _setup_datasets(dataset_name, root='.data', ngrams=1, vocab=None, include_un def AG_NEWS(*args, **kwargs): """ Defines AG_NEWS datasets. - The labels includes: - - 0 : World - - 1 : Sports - - 2 : Business - - 3 : Sci/Tech + + The labels include: + + - 0 : World + - 1 : Sports + - 2 : Business + - 3 : Sci/Tech Create supervised learning dataset: AG_NEWS @@ -172,12 +174,14 @@ def AG_NEWS(*args, **kwargs): def SogouNews(*args, **kwargs): """ Defines SogouNews datasets. - The labels includes: - - 0 : Sports - - 1 : Finance - - 2 : Entertainment - - 3 : Automobile - - 4 : Technology + + The labels include: + + - 0 : Sports + - 1 : Finance + - 2 : Entertainment + - 3 : Automobile + - 4 : Technology Create supervised learning dataset: SogouNews @@ -201,21 +205,23 @@ def SogouNews(*args, **kwargs): def DBpedia(*args, **kwargs): """ Defines DBpedia datasets. - The labels includes: - - 0 : Company - - 1 : EducationalInstitution - - 2 : Artist - - 3 : Athlete - - 4 : OfficeHolder - - 5 : MeanOfTransportation - - 6 : Building - - 7 : NaturalPlace - - 8 : Village - - 9 : Animal - - 10 : Plant - - 11 : Album - - 12 : Film - - 13 : WrittenWork + + The labels include: + + - 0 : Company + - 1 : EducationalInstitution + - 2 : Artist + - 3 : Athlete + - 4 : OfficeHolder + - 5 : MeanOfTransportation + - 6 : Building + - 7 : NaturalPlace + - 8 : Village + - 9 : Animal + - 10 : Plant + - 11 : Album + - 12 : Film + - 13 : WrittenWork Create supervised learning dataset: DBpedia @@ -239,9 +245,11 @@ def DBpedia(*args, **kwargs): def YelpReviewPolarity(*args, **kwargs): """ Defines YelpReviewPolarity datasets. - The labels includes: - - 0 : Negative polarity. - - 1 : Positive polarity. + + The labels include: + + - 0 : Negative polarity. + - 1 : Positive polarity. Create supervised learning dataset: YelpReviewPolarity @@ -265,8 +273,10 @@ def YelpReviewPolarity(*args, **kwargs): def YelpReviewFull(*args, **kwargs): """ Defines YelpReviewFull datasets. - The labels includes: - 0 - 4 : rating classes (4 is highly recommended). + + The labels include: + + 0 - 4 : rating classes (4 is highly recommended). Create supervised learning dataset: YelpReviewFull @@ -290,17 +300,19 @@ def YelpReviewFull(*args, **kwargs): def YahooAnswers(*args, **kwargs): """ Defines YahooAnswers datasets. - The labels includes: - - 0 : Society & Culture - - 1 : Science & Mathematics - - 2 : Health - - 3 : Education & Reference - - 4 : Computers & Internet - - 5 : Sports - - 6 : Business & Finance - - 7 : Entertainment & Music - - 8 : Family & Relationships - - 9 : Politics & Government + + The labels include: + + - 0 : Society & Culture + - 1 : Science & Mathematics + - 2 : Health + - 3 : Education & Reference + - 4 : Computers & Internet + - 5 : Sports + - 6 : Business & Finance + - 7 : Entertainment & Music + - 8 : Family & Relationships + - 9 : Politics & Government Create supervised learning dataset: YahooAnswers @@ -324,9 +336,11 @@ def YahooAnswers(*args, **kwargs): def AmazonReviewPolarity(*args, **kwargs): """ Defines AmazonReviewPolarity datasets. - The labels includes: - - 0 : Negative polarity - - 1 : Positive polarity + + The labels include: + + - 0 : Negative polarity + - 1 : Positive polarity Create supervised learning dataset: AmazonReviewPolarity @@ -350,8 +364,10 @@ def AmazonReviewPolarity(*args, **kwargs): def AmazonReviewFull(*args, **kwargs): """ Defines AmazonReviewFull datasets. - The labels includes: - 0 - 4 : rating classes (4 is highly recommended) + + The labels include: + + 0 - 4 : rating classes (4 is highly recommended) Create supervised learning dataset: AmazonReviewFull diff --git a/torchtext/legacy/datasets/translation.py b/torchtext/legacy/datasets/translation.py index ac1b2f322a..275e7cea90 100644 --- a/torchtext/legacy/datasets/translation.py +++ b/torchtext/legacy/datasets/translation.py @@ -17,7 +17,7 @@ def sort_key(ex): def __init__(self, path, exts, fields, **kwargs): """Create a TranslationDataset given paths and fields. - Arguments: + Args: path: Common prefix of paths to the data files for both languages. exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data @@ -46,7 +46,7 @@ def splits(cls, exts, fields, path=None, root='.data', train='train', validation='val', test='test', **kwargs): """Create dataset objects for splits of a TranslationDataset. - Arguments: + Args: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -87,7 +87,7 @@ def splits(cls, exts, fields, root='.data', train='train', validation='val', test='test2016', **kwargs): """Create dataset objects for splits of the Multi30k dataset. - Arguments: + Args: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -127,7 +127,7 @@ def splits(cls, exts, fields, root='.data', test='IWSLT16.TED.tst2014', **kwargs): """Create dataset objects for splits of the IWSLT dataset. - Arguments: + Args: exts: A tuple containing the extension to path for each language. fields: A tuple containing the fields that will be used for data in each language. @@ -201,7 +201,7 @@ def splits(cls, exts, fields, root='.data', test='newstest2014.tok.bpe.32000', **kwargs): """Create dataset objects for splits of the WMT 2014 dataset. - Arguments: + Args: exts: A tuple containing the extensions for each language. Must be either ('.en', '.de') or the reverse. fields: A tuple containing the fields that will be used for data diff --git a/torchtext/legacy/datasets/trec.py b/torchtext/legacy/datasets/trec.py index d96723c672..6e8792b519 100644 --- a/torchtext/legacy/datasets/trec.py +++ b/torchtext/legacy/datasets/trec.py @@ -18,7 +18,7 @@ def __init__(self, path, text_field, label_field, fine_grained=False, **kwargs): """Create an TREC dataset instance given a path and fields. - Arguments: + Args: path: Path to the data file. text_field: The field that will be used for text data. label_field: The field that will be used for label data. @@ -46,7 +46,7 @@ def splits(cls, text_field, label_field, root='.data', train='train_5500.label', test='TREC_10.label', **kwargs): """Create dataset objects for splits of the TREC dataset. - Arguments: + Args: text_field: The field that will be used for the sentence. label_field: The field that will be used for label data. root: Root dataset storage directory. Default is '.data'. @@ -64,7 +64,7 @@ def splits(cls, text_field, label_field, root='.data', def iters(cls, batch_size=32, device=0, root='.data', vectors=None, **kwargs): """Create iterator objects for splits of the TREC dataset. - Arguments: + Args: batch_size: Batch_size device: Device to create batches on. Use - 1 for CPU and None for the currently active GPU device. diff --git a/torchtext/utils.py b/torchtext/utils.py index d5a749487f..41d794fbd1 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -55,14 +55,17 @@ def download_from_url(url, path=None, root='.data', overwrite=False, hash_value= """ def _check_hash(path): if hash_value: + logging.info('Validating hash {} matches hash of {}'.format(hash_value, path)) with open(path, "rb") as file_obj: if not validate_file(file_obj, hash_value, hash_type): - raise RuntimeError("The hash of {} does not match. Delete the file manually and retry.".format(path)) + raise RuntimeError("The hash of {} does not match. Delete the file manually and retry.".format(os.path.abspath(path))) def _process_response(r, root, filename): chunk_size = 16 * 1024 total_size = int(r.headers.get('Content-length', 0)) if filename is None: + if 'content-disposition' not in r.headers: + raise RuntimeError("Internal error: headers don't contain content-disposition.") d = r.headers['content-disposition'] filename = re.findall("filename=\"(.+)\"", d) if filename is None: @@ -91,7 +94,7 @@ def _process_response(r, root, filename): if path is None: _, filename = os.path.split(url) else: - root, filename = os.path.split(path) + root, filename = os.path.split(os.path.abspath(path)) if not os.path.exists(root): try: @@ -123,6 +126,14 @@ def _process_response(r, root, filename): for k, v in response.cookies.items(): if k.startswith("download_warning"): confirm_token = v + if confirm_token is None: + if "Quota exceeded" in str(response.content): + raise RuntimeError( + "Google drive link {} is currently unavailable, because the quota was exceeded.".format( + url + )) + else: + raise RuntimeError("Internal error: confirm_token was not found in Google drive link.") if confirm_token: url = url + "&confirm=" + confirm_token From 8fdea5dc968fc6474781b47648f884e1eba689a6 Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Mon, 8 Mar 2021 09:38:56 -0800 Subject: [PATCH 49/68] 20210304[2] Sync torchtext GH<->fbcode until GH commit 2764143865678c41e69ad3b993556fe90c1e6391 Summary: Sync up until commit in title Reviewed By: zhangguanheng66 Differential Revision: D26829429 fbshipit-source-id: a059a36d83b3803dfed9198d0e474e0e75f94f17 --- .../benchmark_basic_english_normalize.py | 2 +- benchmark/benchmark_sentencepiece.py | 2 +- docs/source/_templates/layout.html | 8 + docs/source/data.rst | 143 ----- docs/source/datasets.rst | 179 ++---- docs/source/experimental_datasets.rst | 10 +- docs/source/experimental_datasets_raw.rst | 153 ----- docs/source/index.rst | 4 +- examples/data_pipeline/dataset.py | 2 +- examples/data_pipeline/pipelines.py | 2 +- packaging/pkg_helpers.bash | 6 +- test/asset/raw_datasets.json | 10 +- test/common/torchtext_test_case.py | 2 +- test/data/test_batch.py | 43 -- test/data/test_builtin_datasets.py | 89 +-- test/data/test_dataset.py | 479 -------------- test/data/test_subword.py | 25 - test/experimental/test_with_asset.py | 2 +- test/test_build.py | 2 + test/test_utils.py | 16 +- torchtext/data/__init__.py | 21 +- torchtext/data/batch.py | 9 - torchtext/data/dataset.py | 19 - torchtext/data/datasets_utils.py | 210 +++++++ torchtext/data/example.py | 38 -- torchtext/data/field.py | 61 -- torchtext/data/iterator.py | 31 - torchtext/data/pipeline.py | 6 - torchtext/datasets/__init__.py | 60 ++ torchtext/datasets/ag_news.py | 38 ++ torchtext/datasets/amazonreviewfull.py | 44 ++ torchtext/datasets/amazonreviewpolarity.py | 43 ++ torchtext/datasets/conll2000chunking.py | 62 ++ .../datasets/raw => datasets}/dbpedia.py | 23 +- torchtext/datasets/enwik9.py | 25 + .../datasets/raw => datasets}/imdb.py | 19 +- torchtext/datasets/iwslt2016.py | 331 ++++++++++ torchtext/datasets/iwslt2017.py | 292 +++++++++ .../datasets/raw => datasets}/multi30k.py | 152 ++--- torchtext/datasets/penntreebank.py | 36 ++ torchtext/datasets/sogounews.py | 43 ++ .../datasets/raw => datasets}/squad1.py | 19 +- .../datasets/raw => datasets}/squad2.py | 19 +- torchtext/datasets/udpos.py | 46 ++ torchtext/datasets/wikitext103.py | 29 + torchtext/datasets/wikitext2.py | 28 + .../datasets/raw => datasets}/wmt14.py | 39 +- torchtext/datasets/wmtnewscrawl.py | 55 ++ .../datasets/raw => datasets}/yahooanswers.py | 23 +- .../raw => datasets}/yelpreviewfull.py | 23 +- .../raw => datasets}/yelpreviewpolarity.py | 23 +- torchtext/experimental/datasets/__init__.py | 5 +- .../datasets/language_modeling.py | 6 +- .../experimental/datasets/question_answer.py | 6 +- .../experimental/datasets/raw/__init__.py | 56 -- .../experimental/datasets/raw/ag_news.py | 44 -- .../datasets/raw/amazonreviewfull.py | 39 -- .../datasets/raw/amazonreviewpolarity.py | 39 -- torchtext/experimental/datasets/raw/common.py | 180 ------ .../datasets/raw/conll2000chunking.py | 64 -- torchtext/experimental/datasets/raw/iwslt.py | 287 --------- .../datasets/raw/language_modeling.py | 176 ------ .../experimental/datasets/raw/penntreebank.py | 43 -- .../datasets/raw/question_answer.py | 101 --- .../datasets/raw/sequence_tagging.py | 117 ---- .../experimental/datasets/raw/sogounews.py | 39 -- .../datasets/raw/text_classification.py | 293 --------- .../experimental/datasets/raw/translation.py | 583 ------------------ torchtext/experimental/datasets/raw/udpos.py | 57 -- .../experimental/datasets/raw/wikitext103.py | 31 - .../experimental/datasets/raw/wikitext2.py | 31 - .../experimental/datasets/raw/wmtnewscrawl.py | 32 - .../experimental/datasets/sequence_tagging.py | 6 +- .../datasets/text_classification.py | 6 +- .../experimental/datasets/translation.py | 266 +++----- torchtext/legacy/__init__.py | 9 +- torchtext/legacy/data/__init__.py | 16 +- torchtext/utils.py | 8 + 78 files changed, 1761 insertions(+), 3825 deletions(-) create mode 100644 docs/source/_templates/layout.html delete mode 100644 docs/source/data.rst delete mode 100644 docs/source/experimental_datasets_raw.rst delete mode 100644 test/data/test_batch.py delete mode 100644 test/data/test_dataset.py delete mode 100644 test/data/test_subword.py delete mode 100644 torchtext/data/batch.py delete mode 100644 torchtext/data/dataset.py create mode 100644 torchtext/data/datasets_utils.py delete mode 100644 torchtext/data/example.py delete mode 100644 torchtext/data/field.py delete mode 100644 torchtext/data/iterator.py delete mode 100644 torchtext/data/pipeline.py create mode 100644 torchtext/datasets/ag_news.py create mode 100644 torchtext/datasets/amazonreviewfull.py create mode 100644 torchtext/datasets/amazonreviewpolarity.py create mode 100644 torchtext/datasets/conll2000chunking.py rename torchtext/{experimental/datasets/raw => datasets}/dbpedia.py (53%) create mode 100644 torchtext/datasets/enwik9.py rename torchtext/{experimental/datasets/raw => datasets}/imdb.py (59%) create mode 100644 torchtext/datasets/iwslt2016.py create mode 100644 torchtext/datasets/iwslt2017.py rename torchtext/{experimental/datasets/raw => datasets}/multi30k.py (58%) create mode 100644 torchtext/datasets/penntreebank.py create mode 100644 torchtext/datasets/sogounews.py rename torchtext/{experimental/datasets/raw => datasets}/squad1.py (63%) rename torchtext/{experimental/datasets/raw => datasets}/squad2.py (63%) create mode 100644 torchtext/datasets/udpos.py create mode 100644 torchtext/datasets/wikitext103.py create mode 100644 torchtext/datasets/wikitext2.py rename torchtext/{experimental/datasets/raw => datasets}/wmt14.py (83%) create mode 100644 torchtext/datasets/wmtnewscrawl.py rename torchtext/{experimental/datasets/raw => datasets}/yahooanswers.py (53%) rename torchtext/{experimental/datasets/raw => datasets}/yelpreviewfull.py (53%) rename torchtext/{experimental/datasets/raw => datasets}/yelpreviewpolarity.py (52%) delete mode 100644 torchtext/experimental/datasets/raw/__init__.py delete mode 100644 torchtext/experimental/datasets/raw/ag_news.py delete mode 100644 torchtext/experimental/datasets/raw/amazonreviewfull.py delete mode 100644 torchtext/experimental/datasets/raw/amazonreviewpolarity.py delete mode 100644 torchtext/experimental/datasets/raw/common.py delete mode 100644 torchtext/experimental/datasets/raw/conll2000chunking.py delete mode 100644 torchtext/experimental/datasets/raw/iwslt.py delete mode 100644 torchtext/experimental/datasets/raw/language_modeling.py delete mode 100644 torchtext/experimental/datasets/raw/penntreebank.py delete mode 100644 torchtext/experimental/datasets/raw/question_answer.py delete mode 100644 torchtext/experimental/datasets/raw/sequence_tagging.py delete mode 100644 torchtext/experimental/datasets/raw/sogounews.py delete mode 100644 torchtext/experimental/datasets/raw/text_classification.py delete mode 100644 torchtext/experimental/datasets/raw/translation.py delete mode 100644 torchtext/experimental/datasets/raw/udpos.py delete mode 100644 torchtext/experimental/datasets/raw/wikitext103.py delete mode 100644 torchtext/experimental/datasets/raw/wikitext2.py delete mode 100644 torchtext/experimental/datasets/raw/wmtnewscrawl.py diff --git a/benchmark/benchmark_basic_english_normalize.py b/benchmark/benchmark_basic_english_normalize.py index fa395b1299..cb24235746 100644 --- a/benchmark/benchmark_basic_english_normalize.py +++ b/benchmark/benchmark_basic_english_normalize.py @@ -1,7 +1,7 @@ import time import torch -from torchtext.experimental.datasets.raw import AG_NEWS +from torchtext.datasets import AG_NEWS from torchtext.experimental.transforms import basic_english_normalize from torchtext.data.utils import get_tokenizer diff --git a/benchmark/benchmark_sentencepiece.py b/benchmark/benchmark_sentencepiece.py index bbf1f47c81..1049a95523 100644 --- a/benchmark/benchmark_sentencepiece.py +++ b/benchmark/benchmark_sentencepiece.py @@ -3,7 +3,7 @@ from torchtext.experimental.transforms import load_sp_model as load_pybind_sp_model from torchtext.data.functional import load_sp_model as load_torchbind_sp_model from torchtext.utils import download_from_url -from torchtext.experimental.datasets.raw import text_classification as raw +from torchtext.datasets import text_classification as raw def benchmark_sentencepiece(args): diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html new file mode 100644 index 0000000000..6d329de72d --- /dev/null +++ b/docs/source/_templates/layout.html @@ -0,0 +1,8 @@ +{% extends "!layout.html" %} + +{% block sidebartitle %} +

      + {% include "searchbox.html" %} +{% endblock %} diff --git a/docs/source/data.rst b/docs/source/data.rst deleted file mode 100644 index c2eaba4669..0000000000 --- a/docs/source/data.rst +++ /dev/null @@ -1,143 +0,0 @@ -.. role:: hidden - :class: hidden-section - -torchtext.data -================= - -The data module provides the following: - -- Ability to define a preprocessing pipeline -- Batching, padding, and numericalizing (including building a vocabulary object) -- Wrapper for dataset splits (train, validation, test) -- Loader for a custom NLP dataset - - -.. automodule:: torchtext.data -.. currentmodule:: torchtext.data - -Dataset, Batch, and Example ---------------------------- - -:hidden:`Dataset` -~~~~~~~~~~~~~~~~~~ - -.. autoclass:: Dataset - :members: - :special-members: __init__ - -:hidden:`TabularDataset` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: TabularDataset - :members: - :special-members: __init__ - -:hidden:`Batch` -~~~~~~~~~~~~~~~ - -.. autoclass:: Batch - :members: - :special-members: __init__ - -:hidden:`Example` -~~~~~~~~~~~~~~~~~ - -.. autoclass:: Example - :members: - :undoc-members: - :special-members: __init__ - -Fields --------------------- - -:hidden:`RawField` -~~~~~~~~~~~~~~~~~~ - -.. autoclass:: RawField - :members: - :special-members: __init__ - -:hidden:`Field` -~~~~~~~~~~~~~~~ - -.. autoclass:: Field - :members: - :special-members: __init__ - -:hidden:`ReversibleField` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: ReversibleField - :members: - :special-members: __init__ - -:hidden:`SubwordField` -~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: SubwordField - :members: - :special-members: __init__ - -:hidden:`NestedField` -~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: NestedField - :members: - :special-members: __init__ - -Iterators --------------------- - -:hidden:`Iterator` -~~~~~~~~~~~~~~~~~~ - -.. autoclass:: Iterator - :members: - :special-members: __init__ - -:hidden:`BucketIterator` -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: BucketIterator - :members: - :special-members: __init__ - -:hidden:`BPTTIterator` -~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: BPTTIterator - :members: - :special-members: __init__ - -Pipeline --------------------- - -:hidden:`Pipeline` -~~~~~~~~~~~~~~~~~~ - -.. autoclass:: Pipeline - :members: - :special-members: __init__ - -Functions ---------------- - -:hidden:`batch` -~~~~~~~~~~~~~~~ - -.. autofunction:: batch - -:hidden:`pool` -~~~~~~~~~~~~~~ - -.. autofunction:: pool - -:hidden:`get_tokenizer` -~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: get_tokenizer - -:hidden:`interleave_keys` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: interleave_keys diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index 6df98d612f..22342d5997 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -3,33 +3,20 @@ torchtext.datasets .. currentmodule:: torchtext.datasets -All datasets are subclasses of :class:`torchtext.data.Dataset`, which -inherits from :class:`torch.utils.data.Dataset` i.e, they have ``split`` and -``iters`` methods implemented. +General use cases are as follows: :: -General use cases are as follows: -Approach 1, ``splits``: :: + # import datasets + from torchtext.datasets import IMDB - # set up fields - TEXT = data.Field(lower=True, include_lengths=True, batch_first=True) - LABEL = data.Field(sequential=False) + train_iter = IMDB(split='train') - # make splits for data - train, test = datasets.IMDB.splits(TEXT, LABEL) - - # build the vocabulary - TEXT.build_vocab(train, vectors=GloVe(name='6B', dim=300)) - LABEL.build_vocab(train) - - # make iterator for splits - train_iter, test_iter = data.BucketIterator.splits( - (train, test), batch_size=3, device=0) - -Approach 2, ``iters``: :: - - # use default configurations - train_iter, test_iter = datasets.IMDB.iters(batch_size=4) + def tokenize(label, line): + return line.split() + + tokens = [] + for line in train_iter: + tokens += tokenize(line) The following datasets are available: @@ -37,66 +24,18 @@ The following datasets are available: :local: -Language Modeling -^^^^^^^^^^^^^^^^^ - -Language modeling datasets are subclasses of ``LanguageModelingDataset`` class. - -.. autoclass:: LanguageModelingDataset - :members: __init__ - - -WikiText-2 -~~~~~~~~~~ - -.. autoclass:: WikiText2 - :members: splits, iters - - -WikiText103 -~~~~~~~~~~~ - -.. autoclass:: WikiText103 - :members: splits, iters - - -PennTreebank -~~~~~~~~~~~~ - -.. autoclass:: PennTreebank - :members: splits, iters - - -Sentiment Analysis -^^^^^^^^^^^^^^^^^^ - -SST -~~~ - -.. autoclass:: SST - :members: __init__, splits, iters - -IMDb -~~~~ - -.. autoclass:: IMDB - :members: __init__, splits, iters - - Text Classification ^^^^^^^^^^^^^^^^^^^ TextClassificationDataset ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. autoclass:: TextClassificationDataset - :members: __init__ - AG_NEWS ~~~~~~~ .. autofunction:: AG_NEWS + SogouNews ~~~~~~~~~ @@ -105,7 +44,7 @@ SogouNews DBpedia ~~~~~~~ -.. autofunction:: DBpedia +.. autofunction:: DBpedia YelpReviewPolarity ~~~~~~~~~~~~~~~~~~ @@ -132,96 +71,88 @@ AmazonReviewFull .. autofunction:: AmazonReviewFull +IMDb +~~~~ -Question Classification -^^^^^^^^^^^^^^^^^^^^^^^ +.. autofunction:: IMDB -TREC -~~~~ -.. autoclass:: TREC - :members: splits, iters +Language Modeling +^^^^^^^^^^^^^^^^^ -Entailment -^^^^^^^^^^ +WikiText-2 +~~~~~~~~~~ -SNLI -~~~~ +.. autofunction:: WikiText2 -.. autoclass:: SNLI - :members: splits, iters +WikiText103 +~~~~~~~~~~~ -MultiNLI -~~~~~~~~ +.. autofunction:: WikiText103 -.. autoclass:: MultiNLI - :members: splits, iters +PennTreebank +~~~~~~~~~~~~ -Machine Translation -^^^^^^^^^^^^^^^^^^^ +.. autofunction:: PennTreebank -Machine translation datasets are subclasses of ``TranslationDataset`` class. -.. autoclass:: TranslationDataset - :members: __init__ +WMTNewsCrawl +~~~~~~~~~~~~ +.. autofunction:: WMTNewsCrawl + + +Machine Translation +^^^^^^^^^^^^^^^^^^^ Multi30k ~~~~~~~~ -.. autoclass:: Multi30k - :members: splits +.. autofunction:: Multi30k -IWSLT -~~~~~ -.. autoclass:: IWSLT - :members: splits +IWSLT2016 +~~~~~~~~~ + +.. autofunction:: IWSLT2016 + +IWSLT2017 +~~~~~~~~~ + +.. autofunction:: IWSLT2017 + WMT14 ~~~~~ -.. autoclass:: WMT14 - :members: splits +.. autofunction:: WMT14 Sequence Tagging ^^^^^^^^^^^^^^^^ -Sequence tagging datasets are subclasses of ``SequenceTaggingDataset`` class. - -.. autoclass:: SequenceTaggingDataset - :members: __init__ - - UDPOS ~~~~~ -.. autoclass:: UDPOS - :members: splits +.. autofunction:: UDPOS CoNLL2000Chunking ~~~~~~~~~~~~~~~~~ -.. autoclass:: CoNLL2000Chunking - :members: splits +.. autofunction:: CoNLL2000Chunking -Question Answering -^^^^^^^^^^^^^^^^^^ +Question Answer +^^^^^^^^^^^^^^^ -BABI20 -~~~~~~ +SQuAD 1.0 +~~~~~~~~~ -.. autoclass:: BABI20 - :members: __init__, splits, iters +.. autofunction:: SQuAD1 -Unsupervised Learning -^^^^^^^^^^^^^^^^^^^^^ -EnWik9 -~~~~~~ +SQuAD 2.0 +~~~~~~~~~ -.. autoclass:: EnWik9 - :members: __init__, __getitem__, __len__, __iter__, get_vocab +.. autofunction:: SQuAD2 diff --git a/docs/source/experimental_datasets.rst b/docs/source/experimental_datasets.rst index 101c3fc442..94eb24661b 100644 --- a/docs/source/experimental_datasets.rst +++ b/docs/source/experimental_datasets.rst @@ -132,11 +132,15 @@ Multi30k .. autofunction:: Multi30k +IWSLT2016 +~~~~~~~~~ -IWSLT -~~~~~ +.. autofunction:: IWSLT2016 + +IWSLT2017 +~~~~~~~~~ -.. autofunction:: IWSLT +.. autofunction:: IWSLT2017 WMT14 diff --git a/docs/source/experimental_datasets_raw.rst b/docs/source/experimental_datasets_raw.rst deleted file mode 100644 index cc898055f7..0000000000 --- a/docs/source/experimental_datasets_raw.rst +++ /dev/null @@ -1,153 +0,0 @@ -torchtext.experimental.datasets.raw -=================================== - -.. currentmodule:: torchtext.experimental.datasets.raw - -General use cases are as follows: :: - - - # import datasets - from torchtext.experimental.datasets.raw import IMDB - - train_iter = IMDB(split='train') - - def tokenize(label, line): - return line.split() - - tokens = [] - for line in train_iter: - tokens += tokenize(line) - -The following datasets are available: - -.. contents:: Datasets - :local: - - -Text Classification -^^^^^^^^^^^^^^^^^^^ - -TextClassificationDataset -~~~~~~~~~~~~~~~~~~~~~~~~~ - -AG_NEWS -~~~~~~~ - -.. autofunction:: AG_NEWS - - -SogouNews -~~~~~~~~~ - -.. autofunction:: SogouNews - -DBpedia -~~~~~~~ - -.. autofunction:: DBpedia - -YelpReviewPolarity -~~~~~~~~~~~~~~~~~~ - -.. autofunction:: YelpReviewPolarity - -YelpReviewFull -~~~~~~~~~~~~~~ - -.. autofunction:: YelpReviewFull - -YahooAnswers -~~~~~~~~~~~~ - -.. autofunction:: YahooAnswers - -AmazonReviewPolarity -~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: AmazonReviewPolarity - -AmazonReviewFull -~~~~~~~~~~~~~~~~ - -.. autofunction:: AmazonReviewFull - -IMDb -~~~~ - -.. autofunction:: IMDB - - -Language Modeling -^^^^^^^^^^^^^^^^^ - -WikiText-2 -~~~~~~~~~~ - -.. autofunction:: WikiText2 - - -WikiText103 -~~~~~~~~~~~ - -.. autofunction:: WikiText103 - - -PennTreebank -~~~~~~~~~~~~ - -.. autofunction:: PennTreebank - - -WMTNewsCrawl -~~~~~~~~~~~~ - -.. autofunction:: WMTNewsCrawl - - -Machine Translation -^^^^^^^^^^^^^^^^^^^ - -Multi30k -~~~~~~~~ - -.. autofunction:: Multi30k - - -IWSLT -~~~~~ - -.. autofunction:: IWSLT - - -WMT14 -~~~~~ - -.. autofunction:: WMT14 - - -Sequence Tagging -^^^^^^^^^^^^^^^^ - -UDPOS -~~~~~ - -.. autofunction:: UDPOS - -CoNLL2000Chunking -~~~~~~~~~~~~~~~~~ - -.. autofunction:: CoNLL2000Chunking - -Question Answer -^^^^^^^^^^^^^^^ - -SQuAD 1.0 -~~~~~~~~~ - -.. autofunction:: SQuAD1 - - -SQuAD 2.0 -~~~~~~~~~ - -.. autofunction:: SQuAD2 diff --git a/docs/source/index.rst b/docs/source/index.rst index fcf0135ec2..704b40a8f7 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -33,13 +33,13 @@ popular datasets for natural language. self nn_modules - data_utils data_functional data_metrics + data_utils + datasets torchtext.vocab torchtext.utils experimental_datasets - experimental_datasets_raw experimental_transforms experimental_vectors experimental_vocab diff --git a/examples/data_pipeline/dataset.py b/examples/data_pipeline/dataset.py index b166ef9e8f..26740163a4 100644 --- a/examples/data_pipeline/dataset.py +++ b/examples/data_pipeline/dataset.py @@ -1,5 +1,5 @@ import torch -from torchtext.experimental.datasets.raw import text_classification as raw +from torchtext.datasets import text_classification as raw class BatchTextClassificationData(torch.utils.data.IterableDataset): diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index d8c6f71f7d..455e5a5128 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -22,7 +22,7 @@ from torchtext.vocab import FastText import argparse -from torchtext.experimental.datasets.raw import text_classification as raw +from torchtext.datasets import text_classification as raw import time from torch.utils.data import DataLoader diff --git a/packaging/pkg_helpers.bash b/packaging/pkg_helpers.bash index e2e411b2ee..8f1e24f1da 100644 --- a/packaging/pkg_helpers.bash +++ b/packaging/pkg_helpers.bash @@ -142,6 +142,7 @@ setup_wheel_python() { 3.6) python_abi=cp36-cp36m ;; 3.7) python_abi=cp37-cp37m ;; 3.8) python_abi=cp38-cp38 ;; + 3.9) python_abi=cp39-cp39 ;; *) echo "Unrecognized PYTHON_VERSION=$PYTHON_VERSION" exit 1 @@ -178,11 +179,12 @@ setup_pip_pytorch_version() { # # You MUST have populated PYTORCH_VERSION_SUFFIX before hand. setup_conda_pytorch_constraint() { + CONDA_CHANNEL_FLAGS=${CONDA_CHANNEL_FLAGS:-} if [[ -z "$PYTORCH_VERSION" ]]; then - export CONDA_CHANNEL_FLAGS="-c pytorch-nightly" + export CONDA_CHANNEL_FLAGS="${CONDA_CHANNEL_FLAGS} -c pytorch-nightly" export PYTORCH_VERSION="$(conda search --json 'pytorch[channel=pytorch-nightly]' | python -c "import sys, json, re; print(re.sub(r'\\+.*$', '', json.load(sys.stdin)['pytorch'][-1]['version']))")" else - export CONDA_CHANNEL_FLAGS="-c pytorch -c pytorch-${UPLOAD_CHANNEL}" + export CONDA_CHANNEL_FLAGS="${CONDA_CHANNEL_FLAGS} -c pytorch -c pytorch-${UPLOAD_CHANNEL}" fi if [[ "$CU_VERSION" == cpu ]]; then export CONDA_PYTORCH_BUILD_CONSTRAINT="- pytorch==$PYTORCH_VERSION${PYTORCH_VERSION_SUFFIX}" diff --git a/test/asset/raw_datasets.json b/test/asset/raw_datasets.json index 17d9b12fae..6ceefe73b7 100644 --- a/test/asset/raw_datasets.json +++ b/test/asset/raw_datasets.json @@ -24,9 +24,12 @@ {"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Zwei junge wei\u00dfe M\u00e4nner sind im Freien in der N\u00e4he vieler B\u00fcsche.\n", "Two young, White males are outside near many bushes.\n"]} {"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Eine Gruppe von M\u00e4nnern l\u00e4dt Baumwolle auf einen Lastwagen\n", "A group of men are loading cotton onto a truck\n"]} {"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Ein Mann mit einem orangefarbenen Hut, der etwas anstarrt.\n", "A man in an orange hat starring at something.\n"]} -{"dataset_name": "IWSLT", "split": "train", "NUM_LINES": 196884, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["David Gallo: Das ist Bill Lange. Ich bin Dave Gallo.\n", "David Gallo: This is Bill Lange. I'm Dave Gallo.\n"]} -{"dataset_name": "IWSLT", "split": "valid", "NUM_LINES": 993, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich 11 Jahre alt war, wurde ich eines Morgens von den Kl\u00e4ngen heller Freude geweckt.\n", "When I was 11, I remember waking up one morning to the sound of joy in my house.\n"]} -{"dataset_name": "IWSLT", "split": "test", "NUM_LINES": 1305, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich in meinen 20ern war, hatte ich meine erste Psychotherapie-Patientin.\n", "When I was in my 20s, I saw my very first psychotherapy client.\n"]} +{"dataset_name": "IWSLT2016", "split": "train", "NUM_LINES": 196884, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["David Gallo: Das ist Bill Lange. Ich bin Dave Gallo.\n", "David Gallo: This is Bill Lange. I'm Dave Gallo.\n"]} +{"dataset_name": "IWSLT2016", "split": "valid", "NUM_LINES": 993, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich 11 Jahre alt war, wurde ich eines Morgens von den Kl\u00e4ngen heller Freude geweckt.\n", "When I was 11, I remember waking up one morning to the sound of joy in my house.\n"]} +{"dataset_name": "IWSLT2016", "split": "test", "NUM_LINES": 1305, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich in meinen 20ern war, hatte ich meine erste Psychotherapie-Patientin.\n", "When I was in my 20s, I saw my very first psychotherapy client.\n"]} +{"dataset_name": "IWSLT2017", "split": "train", "NUM_LINES": 206112, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Vielen Dank, Chris.\n", "Thank you so much, Chris.\n"]} +{"dataset_name": "IWSLT2017", "split": "valid", "NUM_LINES": 888, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Letztes Jahr habe ich diese beiden Folien gezeigt, um zu veranschaulichen, dass die arktische Eiskappe, die für annähernd drei Millionen Jahre die Grösse der unteren 48 Staaten hatte, um 40 Prozent geschrumpft ist.\n","Last year I showed these two slides so that demonstrate that the arctic ice cap, which for most of the last three million years has been the size of the lower 48 states, has shrunk by 40 percent.\n"]} +{"dataset_name": "IWSLT2017", "split": "test", "NUM_LINES": 1568, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Vor einigen Jahren, hier bei TED, stellte Peter Skillman einen Design-Wettbewerb namens \"Die Marshmallow-Herausforderung\" vor.\n","Several years ago here at TED, Peter Skillman introduced a design challenge called the marshmallow challenge.\n"]} {"dataset_name": "WMT14", "split": "train", "NUM_LINES": 4500966, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Wiederaufnahme der Sitzungsperiode\n", "Res@@ um@@ ption of the session\n"]} {"dataset_name": "WMT14", "split": "valid", "NUM_LINES": 3000, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Eine repub@@ li@@ kanische Strategie , um der Wieder@@ wahl von Obama entgegen@@ zu@@ treten\n", "A Republic@@ an strategy to counter the re-@@ election of Obama\n"]} {"dataset_name": "WMT14", "split": "test", "NUM_LINES": 3003, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Gut@@ ach : Noch mehr Sicherheit f\u00fcr Fu\u00dfg\u00e4n@@ ger\n", "Gut@@ ach : Incre@@ ased safety for pedestri@@ ans\n"]} @@ -44,3 +47,4 @@ {"dataset_name": "SQuAD1", "split": "dev", "NUM_LINES": 10570, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": ["Super Bowl 50 was an American football game to determine the champion of the National Football League (NFL) for the 2015 season. The American Football Conference (AFC) champion Denver Broncos defeated the National Football Conference (NFC) champion Carolina Panthers 24\u201310 to earn their third Super Bowl title. The game was played on February 7, 2016, at Levi's Stadium in the San Francisco Bay Area at Santa Clara, California. As this was the 50th Super Bowl, the league emphasized the \"golden anniversary\" with various gold-themed initiatives, as well as temporarily suspending the tradition of naming each Super Bowl game with Roman numerals (under which the game would have been known as \"Super Bowl L\"), so that the logo could prominently feature the Arabic numerals 50.", "Which NFL team represented the AFC at Super Bowl 50?", ["Denver Broncos", "Denver Broncos", "Denver Broncos"], [177, 177, 177]]} {"dataset_name": "SQuAD2", "split": "train", "NUM_LINES": 130319, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": ["Beyonc\u00e9 Giselle Knowles-Carter (/bi\u02d0\u02c8j\u0252nse\u026a/ bee-YON-say) (born September 4, 1981) is an American singer, songwriter, record producer and actress. Born and raised in Houston, Texas, she performed in various singing and dancing competitions as a child, and rose to fame in the late 1990s as lead singer of R&B girl-group Destiny's Child. Managed by her father, Mathew Knowles, the group became one of the world's best-selling girl groups of all time. Their hiatus saw the release of Beyonc\u00e9's debut album, Dangerously in Love (2003), which established her as a solo artist worldwide, earned five Grammy Awards and featured the Billboard Hot 100 number-one singles \"Crazy in Love\" and \"Baby Boy\".", "When did Beyonce start becoming popular?", ["in the late 1990s"], [269]]} {"dataset_name": "SQuAD2", "split": "dev", "NUM_LINES": 11873, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": ["The Normans (Norman: Nourmands; French: Normands; Latin: Normanni) were the people who in the 10th and 11th centuries gave their name to Normandy, a region in France. They were descended from Norse (\"Norman\" comes from \"Norseman\") raiders and pirates from Denmark, Iceland and Norway who, under their leader Rollo, agreed to swear fealty to King Charles III of West Francia. Through generations of assimilation and mixing with the native Frankish and Roman-Gaulish populations, their descendants would gradually merge with the Carolingian-based cultures of West Francia. The distinct cultural and ethnic identity of the Normans emerged initially in the first half of the 10th century, and it continued to evolve over the succeeding centuries.", "In what country is Normandy located?", ["France", "France", "France", "France"], [159, 159, 159, 159]]} +{"dataset_name": "EnWik9", "split": "train", "NUM_LINES": 13147026, "MD5": "3e773f8a1577fda2e27f871ca17f31fd", "URL": "http://mattmahoney.net/dc/enwik9.zip", "first_line": "\n"} diff --git a/test/common/torchtext_test_case.py b/test/common/torchtext_test_case.py index 322eb32292..c456cd705b 100644 --- a/test/common/torchtext_test_case.py +++ b/test/common/torchtext_test_case.py @@ -108,7 +108,7 @@ def make_mock_dataset(self, num_examples=30, num_labels=3): texts = [str(i) for i in range(num_examples)] labels = list(range(num_labels)) * num_repetitions - labels = [str(l) for l in labels[:num_examples]] + labels = [str(line) for line in labels[:num_examples]] dict_dataset = [ {'text': t, 'label': l} for t, l in zip(texts, labels) diff --git a/test/data/test_batch.py b/test/data/test_batch.py deleted file mode 100644 index acf369a6e3..0000000000 --- a/test/data/test_batch.py +++ /dev/null @@ -1,43 +0,0 @@ -import torch -from torchtext.legacy import data - -from ..common.torchtext_test_case import TorchtextTestCase - - -class TestDataset(TorchtextTestCase): - def test_batch_with_missing_field(self): - # smoke test to see if batches with missing attributes are shown properly - with open(self.test_missing_field_dataset_path, "wt") as f: - f.write("text,label\n1,0") - - dst = data.TabularDataset(path=self.test_missing_field_dataset_path, - format="csv", skip_header=True, - fields=[("text", data.Field(use_vocab=False, - sequential=False)), - ("label", None)]) - itr = data.Iterator(dst, batch_size=64) - str(next(itr.__iter__())) - - def test_batch_iter(self): - self.write_test_numerical_features_dataset() - FLOAT = data.Field(use_vocab=False, sequential=False, - dtype=torch.float) - INT = data.Field(use_vocab=False, sequential=False, is_target=True) - TEXT = data.Field(sequential=False) - - dst = data.TabularDataset(path=self.test_numerical_features_dataset_path, - format="tsv", skip_header=False, - fields=[("float", FLOAT), - ("int", INT), - ("text", TEXT)]) - TEXT.build_vocab(dst) - itr = data.Iterator(dst, batch_size=2, device=-1, shuffle=False) - fld_order = [k for k, v in dst.fields.items() if - v is not None and not v.is_target] - batch = next(iter(itr)) - (x1, x2), y = batch - x = (x1, x2)[fld_order.index("float")] - self.assertEqual(y.data[0], 1) - self.assertEqual(y.data[1], 12) - self.assertAlmostEqual(x.data[0], 0.1, places=4) - self.assertAlmostEqual(x.data[1], 0.5, places=4) diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index bdd579df1d..93d0df8145 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -3,6 +3,7 @@ import os import torch import torchtext +import unittest from torchtext.legacy import data from parameterized import parameterized from ..common.torchtext_test_case import TorchtextTestCase @@ -14,7 +15,8 @@ 'AmazonReviewPolarity', 'DBpedia', 'IMDB', - 'IWSLT', + 'IWSLT2016', + 'IWSLT2017', 'SogouNews', 'WMT14', 'YahooAnswers', @@ -81,7 +83,7 @@ def test_wikitext2(self): self.assertEqual(tokens_ids, [2, 286, 503, 700]) # Add test for the subset of the standard datasets - train_iter, valid_iter, test_iter = torchtext.experimental.datasets.raw.WikiText2(split=('train', 'valid', 'test')) + train_iter, valid_iter, test_iter = torchtext.datasets.WikiText2(split=('train', 'valid', 'test')) self._helper_test_func(len(train_iter), 36718, next(train_iter), ' \n') self._helper_test_func(len(valid_iter), 3760, next(valid_iter), ' \n') self._helper_test_func(len(test_iter), 4358, next(test_iter), ' \n') @@ -136,7 +138,7 @@ def test_penntreebank(self): [9919, 9920, 9921, 9922, 9188]) self._helper_test_func(len(test_data), 82114, test_data[30:35], [397, 93, 4, 16, 7]) - train_iter, test_iter = torchtext.experimental.datasets.raw.PennTreebank(split=('train', 'test')) + train_iter, test_iter = torchtext.datasets.PennTreebank(split=('train', 'test')) self._helper_test_func(len(train_iter), 42068, next(train_iter)[:15], ' aer banknote b') self._helper_test_func(len(test_iter), 3761, next(test_iter)[:25], " no it was n't black mond") del train_iter, test_iter @@ -158,7 +160,7 @@ def test_text_classification(self): [2155, 223, 2405, 30, 3010, 2204, 54, 3603, 4930, 2405]) def test_raw_ag_news(self): - train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() + train_iter, test_iter = torchtext.datasets.AG_NEWS() self._helper_test_func(len(train_iter), 120000, next(train_iter)[1][:25], 'Wall St. Bears Claw Back ') self._helper_test_func(len(test_iter), 7600, next(test_iter)[1][:25], 'Fears for T N pension aft') del train_iter, test_iter @@ -175,29 +177,24 @@ def test_raw_text_classification(self, info): if dataset_name == "WMTNewsCrawl": return split = info['split'] - data_iter = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) + data_iter = torchtext.datasets.DATASETS[dataset_name](split=split) self.assertEqual(len(data_iter), info['NUM_LINES']) self.assertEqual(next(data_iter), info['first_line']) if dataset_name == "AG_NEWS": - self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name][split], info['URL']) - self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name][split], info['MD5']) + self.assertEqual(torchtext.datasets.URLS[dataset_name][split], info['URL']) + self.assertEqual(torchtext.datasets.MD5[dataset_name][split], info['MD5']) else: - self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name], info['URL']) - self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name], info['MD5']) + self.assertEqual(torchtext.datasets.URLS[dataset_name], info['URL']) + self.assertEqual(torchtext.datasets.MD5[dataset_name], info['MD5']) del data_iter - def test_num_lines_of_dataset(self): - train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS(offset=10) - _data = [item for item in train_iter] - self.assertEqual(len(_data), 119990) - - @parameterized.expand(list(sorted(torchtext.experimental.datasets.raw.DATASETS.keys()))) + @parameterized.expand(list(sorted(torchtext.datasets.DATASETS.keys()))) def test_raw_datasets_split_argument(self, dataset_name): if dataset_name in GOOGLE_DRIVE_BASED_DATASETS: return - if 'statmt' in torchtext.experimental.datasets.raw.URLS[dataset_name]: + if 'statmt' in torchtext.datasets.URLS[dataset_name]: return - dataset = torchtext.experimental.datasets.raw.DATASETS[dataset_name] + dataset = torchtext.datasets.DATASETS[dataset_name] train1 = dataset(split='train') train2, = dataset(split=('train',)) for d1, d2 in zip(train1, train2): @@ -223,16 +220,8 @@ def test_datasets_split_argument(self, dataset_name): # Exercise default constructor _ = dataset() - def test_offset_dataset(self): - train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS(split=('train', 'test'), - offset=10) - container = [text[:20] for idx, (label, text) in enumerate(train_iter) if idx < 5] - self.assertEqual(container, ['Oil and Economy Clou', 'No Need for OPEC to ', - 'Non-OPEC Nations Sho', 'Google IPO Auction O', - 'Dollar Falls Broadly']) - def test_next_method_dataset(self): - train_iter, test_iter = torchtext.experimental.datasets.raw.AG_NEWS() + train_iter, test_iter = torchtext.datasets.AG_NEWS() for_count = 0 next_count = 0 for line in train_iter: @@ -263,15 +252,43 @@ def test_imdb(self): train_dataset = IMDB(split='train') self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], [13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]) - train_iter, test_iter = torchtext.experimental.datasets.raw.IMDB() + train_iter, test_iter = torchtext.datasets.IMDB() self._helper_test_func(len(train_iter), 25000, next(train_iter)[1][:25], 'I rented I AM CURIOUS-YEL') self._helper_test_func(len(test_iter), 25000, next(test_iter)[1][:25], 'I love sci-fi and am will') del train_iter, test_iter - def test_iwslt(self): - from torchtext.experimental.datasets import IWSLT + @unittest.skip("Depend on Google drive download") + def test_iwslt2017(self): + from torchtext.experimental.datasets import IWSLT2017 + + train_dataset, valid_dataset, test_dataset = IWSLT2017() + + self.assertEqual(len(train_dataset), 206112) + self.assertEqual(len(valid_dataset), 888) + self.assertEqual(len(test_dataset), 1568) + + de_vocab, en_vocab = train_dataset.get_vocab() + + def assert_nth_pair_is_equal(n, expected_sentence_pair): + de_sentence = [de_vocab.itos[index] for index in train_dataset[n][0]] + en_sentence = [en_vocab.itos[index] for index in train_dataset[n][1]] + + expected_de_sentence, expected_en_sentence = expected_sentence_pair - train_dataset, valid_dataset, test_dataset = IWSLT() + self.assertEqual(de_sentence, expected_de_sentence) + self.assertEqual(en_sentence, expected_en_sentence) + + assert_nth_pair_is_equal(0, (['Vielen', 'Dank', ',', 'Chris', '.', '\n'], ['Thank', 'you', 'so', 'much', ',', 'Chris', '.', '\n'])) + assert_nth_pair_is_equal(10, (['und', 'wir', 'fuhren', 'selbst', '.', '\n'], ['Driving', 'ourselves', '.', '\n'])) + assert_nth_pair_is_equal(20, (['Sie', 'sagte', ':', '"', 'Ja', ',', 'das', 'ist', 'Ex-Vizepräsident', 'Al', 'Gore', 'und', 'seine', + 'Frau', 'Tipper', '.', '"', '\n'], ['And', 'she', 'said', '"', 'Yes', ',', 'that', "'s", 'former', + 'Vice', 'President', 'Al', 'Gore', 'and', 'his', 'wife', ',', 'Tipper', '.', '"', '\n'])) + + @unittest.skip("Depend on Google drive download") + def test_iwslt2016(self): + from torchtext.experimental.datasets import IWSLT2016 + + train_dataset, valid_dataset, test_dataset = IWSLT2016() self.assertEqual(len(train_dataset), 196884) self.assertEqual(len(valid_dataset), 993) @@ -299,8 +316,6 @@ def assert_nth_pair_is_equal(n, expected_sentence_pair): 'alle', 'möglichen', 'Funktionsteile', 'hat', '.', '\n'], ['It', "'s", 'one', 'of', 'my', 'favorites', ',', 'because', 'it', "'s", 'got', 'all', 'sorts', 'of', 'working', 'parts', '.', '\n'])) - datafile = os.path.join(self.project_root, ".data", "2016-01.tgz") - conditional_remove(datafile) def test_multi30k(self): from torchtext.experimental.datasets import Multi30k @@ -340,7 +355,7 @@ def test_multi30k(self): [18, 24, 1168, 807, 16, 56, 83, 335, 1338]) # Add test for the subset of the standard datasets - train_iter, valid_iter = torchtext.experimental.datasets.raw.Multi30k(split=('train', 'valid')) + train_iter, valid_iter = torchtext.datasets.Multi30k(split=('train', 'valid')) self._helper_test_func(len(train_iter), 29000, ' '.join(next(train_iter)), ' '.join(['Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n', 'Two young, White males are outside near many bushes.\n'])) @@ -415,7 +430,7 @@ def test_udpos_sequence_tagging(self): self._helper_test_func(len(train_dataset), 12543, (train_dataset[0][0][:10], train_dataset[-1][2][:10]), ([262, 16, 5728, 45, 289, 701, 1160, 4436, 10660, 585], [6, 20, 8, 10, 8, 8, 24, 13, 8, 15])) - train_iter, valid_iter = torchtext.experimental.datasets.raw.UDPOS(split=('train', 'valid')) + train_iter, valid_iter = torchtext.datasets.UDPOS(split=('train', 'valid')) self._helper_test_func(len(train_iter), 12543, ' '.join(next(train_iter)[0][:5]), ' '.join(['Al', '-', 'Zaman', ':', 'American'])) self._helper_test_func(len(valid_iter), 2002, ' '.join(next(valid_iter)[0][:5]), @@ -468,7 +483,7 @@ def test_conll_sequence_tagging(self): [85, 17, 59, 6473, 288, 115, 72, 5, 2294, 2502], [18, 17, 12, 19, 10, 6, 3, 3, 4, 4], [3, 5, 7, 7, 3, 2, 6, 6, 3, 2])) - train_iter, test_iter = torchtext.experimental.datasets.raw.CoNLL2000Chunking() + train_iter, test_iter = torchtext.datasets.CoNLL2000Chunking() self._helper_test_func(len(train_iter), 8936, ' '.join(next(train_iter)[0][:5]), ' '.join(['Confidence', 'in', 'the', 'pound', 'is'])) self._helper_test_func(len(test_iter), 2012, ' '.join(next(test_iter)[0][:5]), @@ -497,7 +512,7 @@ def test_squad1(self): context, question, answers, ans_pos = train_dataset[100] self._helper_test_func(len(train_dataset), 87599, (question[:5], ans_pos[0]), ([7, 24, 86, 52, 2], [72, 72])) - train_iter, dev_iter = torchtext.experimental.datasets.raw.SQuAD1() + train_iter, dev_iter = torchtext.datasets.SQuAD1() self._helper_test_func(len(train_iter), 87599, next(train_iter)[0][:50], 'Architecturally, the school has a Catholic charact') self._helper_test_func(len(dev_iter), 10570, next(dev_iter)[0][:50], @@ -526,7 +541,7 @@ def test_squad2(self): context, question, answers, ans_pos = train_dataset[200] self._helper_test_func(len(train_dataset), 130319, (question[:5], ans_pos[0]), ([84, 50, 1421, 12, 5439], [9, 9])) - train_iter, dev_iter = torchtext.experimental.datasets.raw.SQuAD2() + train_iter, dev_iter = torchtext.datasets.SQuAD2() self._helper_test_func(len(train_iter), 130319, next(train_iter)[0][:50], 'Beyoncé Giselle Knowles-Carter (/biːˈjɒnseɪ/ bee-Y') self._helper_test_func(len(dev_iter), 11873, next(dev_iter)[0][:50], diff --git a/test/data/test_dataset.py b/test/data/test_dataset.py deleted file mode 100644 index 98662eef7c..0000000000 --- a/test/data/test_dataset.py +++ /dev/null @@ -1,479 +0,0 @@ -# -*- coding: utf-8 -*- -import torchtext.legacy.data as data -import os -import sys -import tempfile -import unittest - -import pytest - -from ..common.torchtext_test_case import TorchtextTestCase - - -class TestDataset(TorchtextTestCase): - def test_tabular_simple_data(self): - for data_format in ["csv", "tsv", "json"]: - self.write_test_ppid_dataset(data_format=data_format) - - if data_format == "json": - question_field = data.Field(sequential=True) - label_field = data.Field(sequential=False) - fields = {"question1": ("q1", question_field), - "question2": ("q2", question_field), - "label": ("label", label_field)} - else: - question_field = data.Field(sequential=True) - label_field = data.Field(sequential=False) - fields = [("id", None), ("q1", question_field), - ("q2", question_field), ("label", label_field)] - - dataset = data.TabularDataset( - path=self.test_ppid_dataset_path, format=data_format, fields=fields) - - assert len(dataset) == 3 - - expected_examples = [ - (["When", "do", "you", "use", "シ", "instead", "of", "し?"], - ["When", "do", "you", "use", "\"&\"", - "instead", "of", "\"and\"?"], "0"), - (["Where", "was", "Lincoln", "born?"], - ["Which", "location", "was", "Abraham", "Lincoln", "born?"], "1"), - (["What", "is", "2+2"], ["2+2=?"], "1")] - - # Ensure examples have correct contents / test __getitem__ - for i in range(len(dataset)): - self.assertEqual(dataset[i].q1, expected_examples[i][0]) - self.assertEqual(dataset[i].q2, expected_examples[i][1]) - self.assertEqual(dataset[i].label, expected_examples[i][2]) - - # Test __getattr__ - for i, (q1, q2, label) in enumerate(zip(dataset.q1, dataset.q2, - dataset.label)): - self.assertEqual(q1, expected_examples[i][0]) - self.assertEqual(q2, expected_examples[i][1]) - self.assertEqual(label, expected_examples[i][2]) - - # Test __iter__ - for i, example in enumerate(dataset): - self.assertEqual(example.q1, expected_examples[i][0]) - self.assertEqual(example.q2, expected_examples[i][1]) - self.assertEqual(example.label, expected_examples[i][2]) - - def test_json_valid_and_invalid_nested_key(self): - self.write_test_nested_key_json_dataset() - valid_fields = {'foods.vegetables.name': ('vegs', data.Field()), - 'foods.fruits': ('fruits', data.Field())} - invalid_fields = {'foods.vegetables.color': ('vegs', data.Field())} - - expected_examples = [ - {"fruits": ["Apple", "Banana"], - "vegs": ["Broccoli", "Cabbage"]}, - {"fruits": ["Cherry", "Grape", "Lemon"], - "vegs": ["Cucumber", "Lettuce"]}, - {"fruits": ["Orange", "Pear", "Strawberry"], - "vegs": ["Marrow", "Spinach"]} - ] - dataset = data.TabularDataset( - path=self.test_nested_key_json_dataset_path, - format="json", - fields=valid_fields) - # check results - for example, expect in zip(dataset.examples, expected_examples): - self.assertEqual(example.vegs, expect['vegs']) - self.assertEqual(example.fruits, expect['fruits']) - - with self.assertRaises(ValueError): - data.TabularDataset( - path=self.test_nested_key_json_dataset_path, - format="json", - fields=invalid_fields) - - def test_errors(self): - # Ensure that trying to retrieve a key not in JSON data errors - self.write_test_ppid_dataset(data_format="json") - - question_field = data.Field(sequential=True) - label_field = data.Field(sequential=False) - fields = {"qeustion1": ("q1", question_field), - "question2": ("q2", question_field), - "label": ("label", label_field)} - - with self.assertRaises(ValueError): - data.TabularDataset( - path=self.test_ppid_dataset_path, format="json", fields=fields) - - def test_input_with_newlines_in_text(self): - # Smoke test for ensuring that TabularDataset works with files with newlines - example_with_newlines = [("\"hello \n world\"", "1"), - ("\"there is a \n newline\"", "0"), - ("\"there is no newline\"", "1")] - fields = [("text", data.Field(lower=True)), - ("label", data.Field(sequential=False))] - - for delim in [",", "\t"]: - with open(self.test_newline_dataset_path, "wt") as f: - for line in example_with_newlines: - f.write("{}\n".format(delim.join(line))) - - format_ = "csv" if delim == "," else "tsv" - dataset = data.TabularDataset( - path=self.test_newline_dataset_path, format=format_, fields=fields) - # if the newline is not parsed correctly, this should raise an error - for example in dataset: - self.assert_(hasattr(example, "text")) - self.assert_(hasattr(example, "label")) - - def test_csv_file_with_header(self): - example_with_header = [("text", "label"), - ("HELLO WORLD", "0"), - ("goodbye world", "1")] - - TEXT = data.Field(lower=True, tokenize=lambda x: x.split()) - fields = { - "label": ("label", data.Field(use_vocab=False, - sequential=False)), - "text": ("text", TEXT) - } - - for format_, delim in zip(["csv", "tsv"], [",", "\t"]): - with open(self.test_has_header_dataset_path, "wt") as f: - for line in example_with_header: - f.write("{}\n".format(delim.join(line))) - - # check that an error is raised here if a non-existent field is specified - with self.assertRaises(ValueError): - data.TabularDataset( - path=self.test_has_header_dataset_path, format=format_, - fields={"non_existent": ("label", data.Field())}) - - dataset = data.TabularDataset( - path=self.test_has_header_dataset_path, format=format_, - skip_header=False, fields=fields) - - TEXT.build_vocab(dataset) - - for i, example in enumerate(dataset): - self.assertEqual(example.text, - example_with_header[i + 1][0].lower().split()) - self.assertEqual(example.label, example_with_header[i + 1][1]) - - # check that the vocabulary is built correctly (#225) - expected_freqs = {"hello": 1, "world": 2, "goodbye": 1, "text": 0} - for k, v in expected_freqs.items(): - self.assertEqual(TEXT.vocab.freqs[k], v) - - data_iter = data.Iterator(dataset, batch_size=1, - sort_within_batch=False, repeat=False) - next(data_iter.__iter__()) - - @unittest.skipIf(sys.platform == "win32", "FIXME: tempfile could not be opened twice on Windows") - def test_csv_dataset_quotechar(self): - # Based on issue #349 - example_data = [("text", "label"), - ('" hello world', "0"), - ('goodbye " world', "1"), - ('this is a pen " ', "0")] - - with tempfile.NamedTemporaryFile(dir=self.test_dir) as f: - for example in example_data: - f.write("{}\n".format(",".join(example)).encode("latin-1")) - - TEXT = data.Field(lower=True, tokenize=lambda x: x.split()) - fields = { - "label": ("label", data.Field(use_vocab=False, - sequential=False)), - "text": ("text", TEXT) - } - - f.seek(0) - - dataset = data.TabularDataset( - path=f.name, format="csv", - skip_header=False, fields=fields, - csv_reader_params={"quotechar": None}) - - TEXT.build_vocab(dataset) - - self.assertEqual(len(dataset), len(example_data) - 1) - - for i, example in enumerate(dataset): - self.assertEqual(example.text, - example_data[i + 1][0].lower().split()) - self.assertEqual(example.label, example_data[i + 1][1]) - - def test_dataset_split_arguments(self): - num_examples, num_labels = 30, 3 - self.write_test_splitting_dataset(num_examples=num_examples, - num_labels=num_labels) - text_field = data.Field() - label_field = data.LabelField() - fields = [('text', text_field), ('label', label_field)] - - dataset = data.TabularDataset( - path=self.test_dataset_splitting_path, format="csv", fields=fields) - - # Test default split ratio (0.7) - expected_train_size = 21 - expected_test_size = 9 - - train, test = dataset.split() - assert len(train) == expected_train_size - assert len(test) == expected_test_size - - # Test array arguments with same ratio - split_ratio = [0.7, 0.3] - train, test = dataset.split(split_ratio=split_ratio) - assert len(train) == expected_train_size - assert len(test) == expected_test_size - - # Add validation set - split_ratio = [0.6, 0.3, 0.1] - expected_train_size = 18 - expected_valid_size = 3 - expected_test_size = 9 - - train, valid, test = dataset.split(split_ratio=split_ratio) - assert len(train) == expected_train_size - assert len(valid) == expected_valid_size - assert len(test) == expected_test_size - - # Test ratio normalization - split_ratio = [6, 3, 1] - train, valid, test = dataset.split(split_ratio=split_ratio) - assert len(train) == expected_train_size - assert len(valid) == expected_valid_size - assert len(test) == expected_test_size - - # Test only two splits returned for too small valid split size - split_ratio = [0.66, 0.33, 0.01] - expected_length = 2 - splits = dataset.split(split_ratio=split_ratio) - assert len(splits) == expected_length - - # Test invalid arguments - split_ratio = 1.1 - with pytest.raises(AssertionError): - dataset.split(split_ratio=split_ratio) - - split_ratio = -1. - with pytest.raises(AssertionError): - dataset.split(split_ratio=split_ratio) - - split_ratio = [0.7] - with pytest.raises(AssertionError): - dataset.split(split_ratio=split_ratio) - - split_ratio = [1, 2, 3, 4] - with pytest.raises(AssertionError): - dataset.split(split_ratio=split_ratio) - - split_ratio = "string" - with pytest.raises(ValueError): - dataset.split(split_ratio=split_ratio) - - def test_stratified_dataset_split(self): - num_examples, num_labels = 30, 3 - self.write_test_splitting_dataset(num_examples=num_examples, - num_labels=num_labels) - text_field = data.Field() - label_field = data.LabelField() - fields = [('text', text_field), ('label', label_field)] - - dataset = data.TabularDataset( - path=self.test_dataset_splitting_path, format="csv", fields=fields) - - # Default split ratio - expected_train_size = 21 - expected_test_size = 9 - - train, test = dataset.split(stratified=True) - assert len(train) == expected_train_size - assert len(test) == expected_test_size - - # Test array arguments with same ratio - split_ratio = [0.7, 0.3] - train, test = dataset.split(split_ratio=split_ratio, stratified=True) - assert len(train) == expected_train_size - assert len(test) == expected_test_size - - # Test strata_field argument - train, test = dataset.split(split_ratio=split_ratio, stratified=True, - strata_field='label') - assert len(train) == expected_train_size - assert len(test) == expected_test_size - - # Test invalid field name - strata_field = 'dummy' - with pytest.raises(ValueError): - dataset.split(split_ratio=split_ratio, stratified=True, - strata_field=strata_field) - - # Test uneven stratify sizes - num_examples, num_labels = 28, 3 - self.write_test_splitting_dataset(num_examples=num_examples, - num_labels=num_labels) - # 10 examples for class 1 and 9 examples for classes 2,3 - dataset = data.TabularDataset( - path=self.test_dataset_splitting_path, format="csv", fields=fields) - - expected_train_size = 7 + 6 + 6 - expected_test_size = 3 + 3 + 3 - train, test = dataset.split(split_ratio=split_ratio, stratified=True) - assert len(train) == expected_train_size - assert len(test) == expected_test_size - - split_ratio = [0.7, 0.3] - train, test = dataset.split(split_ratio=split_ratio, stratified=True) - assert len(train) == expected_train_size - assert len(test) == expected_test_size - - # Add validation set - split_ratio = [0.6, 0.3, 0.1] - expected_train_size = 6 + 5 + 5 - expected_valid_size = 1 + 1 + 1 - expected_test_size = 3 + 3 + 3 - train, valid, test = dataset.split(split_ratio=split_ratio, stratified=True) - assert len(train) == expected_train_size - assert len(valid) == expected_valid_size - assert len(test) == expected_test_size - - def test_filter(self): - # Create test examples - sentence11 = [["who", "is", "there"]] - sentence12 = [["bernardo", "is", "there"]] - label1 = [1] - sentence21 = [["nay", "answer", "me"]] - sentence22 = [["stand", "unfold", "yourself"]] - label2 = [0] - sentence31 = [["is", "Horatio", "there"]] - sentence32 = [["a", "piece", "of", "him"]] - label3 = [0] - - example1_values = sentence11 + sentence12 + label1 - example2_values = sentence21 + sentence22 + label2 - example3_values = sentence31 + sentence32 + label3 - - # Test filter remove words from single field only - dataset, text_field = filter_init( - example1_values, - example2_values, - example3_values - ) - - text_field.vocab.stoi.pop("there") - text_field.vocab.stoi.pop("bernardo") - - dataset.filter_examples(["text1"]) - - assert dataset[0].text1 == ["who", "is"] - assert dataset[0].text2 == ["bernardo", "is", "there"] - assert dataset[0].label == 1 - - assert dataset[1].text1 == ["nay", "answer", "me"] - assert dataset[1].text2 == ["stand", "unfold", "yourself"] - assert dataset[1].label == 0 - - assert dataset[2].text1 == ["is", "Horatio"] - assert dataset[2].text2 == ["a", "piece", "of", "him"] - assert dataset[2].label == 0 - - # Test filter remove words from multiple fields - dataset, text_field = filter_init( - example1_values, - example2_values, - example3_values - ) - - text_field.vocab.stoi.pop("there") - text_field.vocab.stoi.pop("bernardo") - - dataset.filter_examples(["text1", "text2"]) - - assert dataset[0].text1 == ["who", "is"] - assert dataset[0].text2 == ["is"] - assert dataset[0].label == 1 - - assert dataset[1].text1 == ["nay", "answer", "me"] - assert dataset[1].text2 == ["stand", "unfold", "yourself"] - assert dataset[1].label == 0 - - assert dataset[2].text1 == ["is", "Horatio"] - assert dataset[2].text2 == ["a", "piece", "of", "him"] - assert dataset[2].label == 0 - - # Test filter remove all words in example - dataset, text_field = filter_init( - example1_values, - example2_values, - example3_values - ) - - text_field.vocab.stoi.pop("who") - text_field.vocab.stoi.pop("is") - text_field.vocab.stoi.pop("there") - - dataset.filter_examples(["text1", "text2"]) - - assert dataset[0].text1 == [] - assert dataset[0].text2 == ["bernardo"] - assert dataset[0].label == 1 - - assert dataset[1].text1 == ["nay", "answer", "me"] - assert dataset[1].text2 == ["stand", "unfold", "yourself"] - assert dataset[1].label == 0 - - assert dataset[2].text1 == ["Horatio"] - assert dataset[2].text2 == ["a", "piece", "of", "him"] - assert dataset[2].label == 0 - - def test_gz_extraction(self): - # tar.gz file contains train.txt and test.txt - tgz = (b'\x1f\x8b\x08\x00\x1e\xcc\xd5Z\x00\x03\xed\xd1;\n\x800\x10E' - b'\xd1,%+\x90\xc9G\xb3\x1e\x0b\x0b\x1b\x03q\x04\x97\xef\xa7' - b'\xb0\xb0P,R\x08\xf74o`\x9aa\x9e\x96~\x9c\x1a]\xd5\xd4#\xbb' - b'\x94\xd2\x99\xbb{\x9e\xb3\x0b\xbekC\x8c\x12\x9c\x11\xe7b\x10c' - b'\xa5\xe2M\x97e\xd6\xbeXkJ\xce\x8f?x\xdb\xff\x94\x0e\xb3V\xae' - b'\xff[\xffQ\x8e\xfe}\xf2\xf4\x0f\x00\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00O6\x1c\xc6\xbd\x89\x00(\x00\x00') - - # .gz file contains dummy.txt - gz = (b'\x1f\x8b\x08\x08W\xce\xd5Z\x00\x03dummy.txt\x00\x0bq\r\x0e\x01' - b'\x00\xb8\x93\xea\xee\x04\x00\x00\x00') - - # Create both files - with open(os.path.join(self.test_dir, 'dummy.tar.gz'), 'wb') as fp: - fp.write(tgz) - - with open(os.path.join(self.test_dir, 'dummy.txt.gz'), 'wb') as fp: - fp.write(gz) - - # Set the urls in a dummy class - class DummyDataset(data.Dataset): - urls = ['dummy.tar.gz', 'dummy.txt.gz'] - name = '' - dirname = '' - - # Run extraction - DummyDataset.download(self.test_dir, check='') - - # Check if files were extracted correctly - assert os.path.isfile(os.path.join(self.test_dir, 'dummy.txt')) - assert os.path.isfile(os.path.join(self.test_dir, 'train.txt')) - assert os.path.isfile(os.path.join(self.test_dir, 'test.txt')) - - -def filter_init(ex_val1, ex_val2, ex_val3): - text_field = data.Field(sequential=True) - label_field = data.Field(sequential=False) - fields = [("text1", text_field), ("text2", text_field), - ("label", label_field)] - - example1 = data.Example.fromlist(ex_val1, fields) - example2 = data.Example.fromlist(ex_val2, fields) - example3 = data.Example.fromlist(ex_val3, fields) - examples = [example1, example2, example3] - - dataset = data.Dataset(examples, fields) - text_field.build_vocab(dataset) - - return dataset, text_field diff --git a/test/data/test_subword.py b/test/data/test_subword.py deleted file mode 100644 index 83aec7df0f..0000000000 --- a/test/data/test_subword.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# Note that all the tests in this module require dataset (either network access or cached) -import unittest - -from torchtext.legacy import data -from torchtext.legacy.datasets import TREC - - -class TestSubword(unittest.TestCase): - def test_subword_trec(self): - TEXT = data.SubwordField() - LABEL = data.Field(sequential=False) - RAW = data.Field(sequential=False, use_vocab=False) - raw, _ = TREC.splits(RAW, LABEL) - cooked, _ = TREC.splits(TEXT, LABEL) - LABEL.build_vocab(cooked) - TEXT.build_vocab(cooked, max_size=100) - TEXT.segment(cooked) - print(cooked[0].text) - batch = next(iter(data.Iterator(cooked, 1, shuffle=False))) - self.assertEqual(TEXT.reverse(batch.text.data)[0], raw[0].text) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/experimental/test_with_asset.py b/test/experimental/test_with_asset.py index f900fb6752..a9be86d81b 100644 --- a/test/experimental/test_with_asset.py +++ b/test/experimental/test_with_asset.py @@ -62,7 +62,7 @@ def test_wikitext103(self): self.assertEqual(tokens_ids, [2, 320, 437, 687]) # Add test for the subset of the standard datasets - train_dataset, test_dataset = torchtext.experimental.datasets.raw.WikiText103(split=('train', 'test')) + train_dataset, test_dataset = torchtext.datasets.WikiText103(split=('train', 'test')) self._helper_test_func(len(train_dataset), 1801350, next(iter(train_dataset)), ' \n') self._helper_test_func(len(test_dataset), 4358, next(iter(test_dataset)), ' \n') train_dataset, test_dataset = WikiText103(vocab=builtin_vocab, split=('train', 'test')) diff --git a/test/test_build.py b/test/test_build.py index 37d47a6937..fe4cb51cb6 100644 --- a/test/test_build.py +++ b/test/test_build.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 """Tests that requires external resources (Network access to fetch dataset)""" import os +import unittest from collections import Counter import torch @@ -294,6 +295,7 @@ def test_extend(self): self.assertEqual(vectors[v.stoi['']], torch.zeros(300)) + @unittest.skip("Download temp. slow.") def test_vectors_custom_cache(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) vector_cache = os.path.join('/tmp', 'vector_cache') diff --git a/test/test_utils.py b/test/test_utils.py index 1f9f75369c..f44945f58c 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # Note that all the tests in this module require dataset (either network access or cached) import os +import unittest from torchtext import utils from .common.torchtext_test_case import TorchtextTestCase from test.common.assets import get_asset_path @@ -16,7 +17,7 @@ class TestUtils(TorchtextTestCase): def test_download_extract_tar(self): # create root directory for downloading data - root = '.data' + root = os.path.abspath('.data') if not os.path.exists(root): os.makedirs(root) @@ -46,7 +47,7 @@ def test_download_extract_tar(self): def test_download_extract_gz(self): # create root directory for downloading data - root = '.data' + root = os.path.abspath('.data') if not os.path.exists(root): os.makedirs(root) @@ -74,7 +75,7 @@ def test_download_extract_gz(self): def test_download_extract_zip(self): # create root directory for downloading data - root = '.data' + root = os.path.abspath('.data') if not os.path.exists(root): os.makedirs(root) @@ -109,10 +110,10 @@ def test_download_extract_zip(self): def test_no_download(self): asset_name = 'glove.840B.300d.zip' asset_path = get_asset_path(asset_name) - root = '.data' + root = os.path.abspath('.data') if not os.path.exists(root): os.makedirs(root) - data_path = os.path.join('.data', asset_name) + data_path = os.path.abspath(os.path.join('.data', asset_name)) shutil.copy(asset_path, data_path) file_path = utils.download_from_url('fakedownload/glove.840B.300d.zip') self.assertEqual(file_path, data_path) @@ -120,7 +121,7 @@ def test_no_download(self): def test_download_extract_to_path(self): # create root directory for downloading data - root = '.data' + root = os.path.abspath('.data') if not os.path.exists(root): os.makedirs(root) @@ -153,9 +154,10 @@ def test_download_extract_to_path(self): conditional_remove(f) conditional_remove(archive_path) + @unittest.skip("Download temp. slow.") def test_extract_non_tar_zip(self): # create root directory for downloading data - root = '.data' + root = os.path.abspath('.data') if not os.path.exists(root): os.makedirs(root) diff --git a/torchtext/data/__init__.py b/torchtext/data/__init__.py index 9d3483f65b..e403cd8483 100644 --- a/torchtext/data/__init__.py +++ b/torchtext/data/__init__.py @@ -1,10 +1,4 @@ -from .batch import Batch -from .dataset import Dataset, TabularDataset -from .example import Example -from .field import RawField, Field, ReversibleField, SubwordField, NestedField, LabelField -from .iterator import BucketIterator, Iterator, BPTTIterator from .metrics import bleu_score -from .pipeline import Pipeline from .utils import get_tokenizer, interleave_keys from .functional import generate_sp_model, \ load_sp_model, \ @@ -12,16 +6,13 @@ sentencepiece_tokenizer, custom_replace, simple_space_split, \ numericalize_tokens_from_iterator -__all__ = ["Batch", - "Dataset", "TabularDataset", - "Example", - "RawField", "Field", "ReversibleField", "SubwordField", "NestedField", - "LabelField", - "BucketIterator", "Iterator", "BPTTIterator", - "bleu_score", - "Pipeline", +from ..legacy.data import Batch + +__all__ = ["bleu_score", "get_tokenizer", "interleave_keys", "generate_sp_model", "load_sp_model", "sentencepiece_numericalizer", "sentencepiece_tokenizer", "custom_replace", "simple_space_split", - "numericalize_tokens_from_iterator"] + "numericalize_tokens_from_iterator", + "Batch" #tmp compatability hack for old lightning +] diff --git a/torchtext/data/batch.py b/torchtext/data/batch.py deleted file mode 100644 index 0cdae1ec86..0000000000 --- a/torchtext/data/batch.py +++ /dev/null @@ -1,9 +0,0 @@ -import warnings - - -class Batch(object): - def __init__(self, data=None, dataset=None, device=None): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning diff --git a/torchtext/data/dataset.py b/torchtext/data/dataset.py deleted file mode 100644 index defd6e565f..0000000000 --- a/torchtext/data/dataset.py +++ /dev/null @@ -1,19 +0,0 @@ -import torch.utils.data -import warnings - - -class Dataset(torch.utils.data.Dataset): - def __init__(self, examples, fields, filter_pred=None): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class TabularDataset(Dataset): - def __init__(self, path, format, fields, skip_header=False, - csv_reader_params={}, **kwargs): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning diff --git a/torchtext/data/datasets_utils.py b/torchtext/data/datasets_utils.py new file mode 100644 index 0000000000..637bb737bd --- /dev/null +++ b/torchtext/data/datasets_utils.py @@ -0,0 +1,210 @@ +import functools +import inspect +import os +import torch +from torchtext.utils import validate_file +from torchtext.utils import download_from_url +from torchtext.utils import extract_archive + +""" +These functions and classes are meant solely for use in torchtext.datasets and not +for public consumption yet. +""" + + +def check_default_set(split, target_select, dataset_name): + # Check whether given object split is either a tuple of strings or string + # and represents a valid selection of options given by the tuple of strings + # target_select. + if isinstance(split, str): + split = (split,) + if isinstance(target_select, str): + target_select = (target_select,) + if not isinstance(split, tuple): + raise ValueError("Internal error: Expected split to be of type tuple.") + if not set(split).issubset(set(target_select)): + raise TypeError('Given selection {} of splits is not supported for dataset {}. Please choose from {}.'.format( + split, dataset_name, target_select)) + return split + + +def wrap_datasets(datasets, split): + # Wrap return value for _setup_datasets functions to support singular values instead + # of tuples when split is a string. + if isinstance(split, str): + if len(datasets) != 1: + raise ValueError("Internal error: Expected number of datasets is not 1.") + return datasets[0] + return datasets + + +def find_match(match, lst): + """ + Searches list of strings and returns first entry that partially or fully + contains the given string match. + """ + for element in lst: + if match in element: + return element + return None + + +def dataset_docstring_header(fn, num_lines=None): + """ + Returns docstring for a dataset based on function arguments. + + Assumes function signature of form (root='.data', split=, **kwargs) + """ + argspec = inspect.getfullargspec(fn) + if not (argspec.args[0] == "root" and + argspec.args[1] == "split"): + raise ValueError("Internal Error: Given function {} did not adhere to standard signature.".format(fn)) + default_split = argspec.defaults[1] + + if not (isinstance(default_split, tuple) or isinstance(default_split, str)): + raise ValueError("default_split type expected to be of string or tuple but got {}".format(type(default_split))) + + header_s = fn.__name__ + " dataset\n" + + if isinstance(default_split, tuple): + header_s += "\nSeparately returns the {} split".format("/".join(default_split)) + + if isinstance(default_split, str): + header_s += "\nOnly returns the {} split".format(default_split) + + if num_lines is not None: + header_s += "\n\nNumber of lines per split:" + for k, v in num_lines.items(): + header_s += "\n {}: {}\n".format(k, v) + + args_s = "\nArgs:" + args_s += "\n root: Directory where the datasets are saved." + args_s += "\n Default: .data" + + if isinstance(default_split, tuple): + args_s += "\n split: split or splits to be returned. Can be a string or tuple of strings." + args_s += "\n Default: {}""".format(str(default_split)) + + if isinstance(default_split, str): + args_s += "\n split: Only {default_split} is available." + args_s += "\n Default: {default_split}.format(default_split=default_split)" + + return "\n".join([header_s, args_s]) + "\n" + + +def add_docstring_header(docstring=None, num_lines=None): + def docstring_decorator(fn): + old_doc = fn.__doc__ + fn.__doc__ = dataset_docstring_header(fn, num_lines) + if docstring is not None: + fn.__doc__ += docstring + if old_doc is not None: + fn.__doc__ += old_doc + return fn + return docstring_decorator + + +def _wrap_split_argument(fn, splits): + """ + Wraps given function of specific signature to extend behavior of split + to support individual strings. The given function is expected to have a split + kwarg that accepts tuples of strings, e.g. ('train', 'valid') and the returned + function will have a split argument that also accepts strings, e.g. 'train', which + are then turned single entry tuples. Furthermore, the return value of the wrapped + function is unpacked if split is only a single string to enable behavior such as + + train = AG_NEWS(split='train') + train, valid = AG_NEWS(split=('train', 'valid')) + """ + + argspec = inspect.getfullargspec(fn) + if not (argspec.args[0] == "root" and + argspec.args[1] == "split" and + argspec.varargs is None and + argspec.varkw is None and + len(argspec.kwonlyargs) == 0 and + len(argspec.annotations) == 0 + ): + raise ValueError("Internal Error: Given function {} did not adhere to standard signature.".format(fn)) + + @functools.wraps(fn) + def new_fn(root='.data', split=splits, **kwargs): + result = [] + for item in check_default_set(split, splits, fn.__name__): + result.append(fn(root, item, **kwargs)) + return wrap_datasets(tuple(result), split) + + new_sig = inspect.signature(new_fn) + new_sig_params = new_sig.parameters + new_params = [] + new_params.append(new_sig_params['root'].replace(default='.data')) + new_params.append(new_sig_params['split'].replace(default=splits)) + new_params += [entry[1] for entry in list(new_sig_params.items())[2:]] + new_sig = new_sig.replace(parameters=tuple(new_params)) + new_fn.__signature__ = new_sig + + return new_fn + + +def wrap_split_argument(splits): + def new_fn(fn): + return _wrap_split_argument(fn, splits) + return new_fn + + +def download_extract_validate(root, url, url_md5, downloaded_file, extracted_file, extracted_file_md5, + hash_type="sha256"): + root = os.path.abspath(root) + downloaded_file = os.path.abspath(downloaded_file) + extracted_file = os.path.abspath(extracted_file) + if os.path.exists(extracted_file): + with open(os.path.join(root, extracted_file), 'rb') as f: + if validate_file(f, extracted_file_md5, hash_type): + return extracted_file + + dataset_tar = download_from_url(url, path=os.path.join(root, downloaded_file), + hash_value=url_md5, hash_type=hash_type) + extracted_files = extract_archive(dataset_tar) + assert extracted_file == find_match(extracted_file, extracted_files) + return extracted_file + + +class RawTextIterableDataset(torch.utils.data.IterableDataset): + """Defines an abstraction for raw text iterable datasets. + """ + + def __init__(self, description, full_num_lines, iterator): + """Initiate text-classification dataset. + """ + super(RawTextIterableDataset, self).__init__() + self.description = description + self.full_num_lines = full_num_lines + self._iterator = iterator + self.num_lines = full_num_lines + self.current_pos = None + + def __iter__(self): + return self + + def __next__(self): + if self.current_pos == self.num_lines - 1: + raise StopIteration + item = next(self._iterator) + if self.current_pos is None: + self.current_pos = 0 + else: + self.current_pos += 1 + return item + + def __len__(self): + return self.num_lines + + def pos(self): + """ + Returns current position of the iterator. This returns None + if the iterator hasn't been used yet. + """ + return self.current_pos + + def __str__(self): + return self.description diff --git a/torchtext/data/example.py b/torchtext/data/example.py deleted file mode 100644 index e7d11f445d..0000000000 --- a/torchtext/data/example.py +++ /dev/null @@ -1,38 +0,0 @@ -import warnings - - -class Example(object): - @classmethod - def fromJSON(cls, data, fields): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - @classmethod - def fromdict(cls, data, fields): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - @classmethod - def fromCSV(cls, data, fields, field_to_index=None): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - @classmethod - def fromlist(cls, data, fields): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - @classmethod - def fromtree(cls, data, fields, subtrees=False): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning diff --git a/torchtext/data/field.py b/torchtext/data/field.py deleted file mode 100644 index 09830605a7..0000000000 --- a/torchtext/data/field.py +++ /dev/null @@ -1,61 +0,0 @@ -# coding: utf8 -import torch -import warnings - - -class RawField(object): - def __init__(self, preprocessing=None, postprocessing=None, is_target=False): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class Field(RawField): - def __init__(self, sequential=True, use_vocab=True, init_token=None, - eos_token=None, fix_length=None, dtype=torch.long, - preprocessing=None, postprocessing=None, lower=False, - tokenize=None, tokenizer_language='en', include_lengths=False, - batch_first=False, pad_token="", unk_token="", - pad_first=False, truncate_first=False, stop_words=None, - is_target=False): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class ReversibleField(Field): - def __init__(self, **kwargs): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class SubwordField(ReversibleField): - def __init__(self, **kwargs): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class NestedField(Field): - def __init__(self, nesting_field, use_vocab=True, init_token=None, eos_token=None, - fix_length=None, dtype=torch.long, preprocessing=None, - postprocessing=None, tokenize=None, tokenizer_language='en', - include_lengths=False, pad_token='', - pad_first=False, truncate_first=False): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class LabelField(Field): - def __init__(self, **kwargs): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py deleted file mode 100644 index e1ff1ab93c..0000000000 --- a/torchtext/data/iterator.py +++ /dev/null @@ -1,31 +0,0 @@ -import logging -import warnings - -logger = logging.getLogger(__name__) - - -class Iterator(object): - def __init__(self, dataset, batch_size, sort_key=None, device=None, - batch_size_fn=None, train=True, - repeat=False, shuffle=None, sort=None, - sort_within_batch=None): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class BPTTIterator(Iterator): - def __init__(self, dataset, batch_size, bptt_len, **kwargs): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning - - -class BucketIterator(Iterator): - def create_batches(self): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning diff --git a/torchtext/data/pipeline.py b/torchtext/data/pipeline.py deleted file mode 100644 index 78f826c82c..0000000000 --- a/torchtext/data/pipeline.py +++ /dev/null @@ -1,6 +0,0 @@ -class Pipeline(object): - def __init__(self, convert_token=None): - warnings.warn('{} class has '.format(self.__class__.__name__) + - 'been retired and moved to torchtext.legacy. Please ' + - 'import from torchtext.legacy.data if you still want it.', UserWarning) - raise ImportWarning diff --git a/torchtext/datasets/__init__.py b/torchtext/datasets/__init__.py index e69de29bb2..a53c273aee 100644 --- a/torchtext/datasets/__init__.py +++ b/torchtext/datasets/__init__.py @@ -0,0 +1,60 @@ +import importlib +from .ag_news import AG_NEWS +from .amazonreviewfull import AmazonReviewFull +from .amazonreviewpolarity import AmazonReviewPolarity +from .conll2000chunking import CoNLL2000Chunking +from .dbpedia import DBpedia +from .enwik9 import EnWik9 +from .imdb import IMDB +from .iwslt2016 import IWSLT2016 +from .iwslt2017 import IWSLT2017 +from .multi30k import Multi30k +from .penntreebank import PennTreebank +from .sogounews import SogouNews +from .squad1 import SQuAD1 +from .squad2 import SQuAD2 +from .udpos import UDPOS +from .wikitext103 import WikiText103 +from .wikitext2 import WikiText2 +from .wmt14 import WMT14 +from .wmtnewscrawl import WMTNewsCrawl +from .yahooanswers import YahooAnswers +from .yelpreviewfull import YelpReviewFull +from .yelpreviewpolarity import YelpReviewPolarity + +DATASETS = { + 'AG_NEWS': AG_NEWS, + 'AmazonReviewFull': AmazonReviewFull, + 'AmazonReviewPolarity': AmazonReviewPolarity, + 'CoNLL2000Chunking': CoNLL2000Chunking, + 'DBpedia': DBpedia, + 'EnWik9': EnWik9, + 'IMDB': IMDB, + 'IWSLT2016': IWSLT2016, + 'IWSLT2017': IWSLT2017, + 'Multi30k': Multi30k, + 'PennTreebank': PennTreebank, + 'SQuAD1': SQuAD1, + 'SQuAD2': SQuAD2, + 'SogouNews': SogouNews, + 'UDPOS': UDPOS, + 'WMT14': WMT14, + 'WMTNewsCrawl': WMTNewsCrawl, + 'WikiText103': WikiText103, + 'WikiText2': WikiText2, + 'YahooAnswers': YahooAnswers, + 'YelpReviewFull': YelpReviewFull, + 'YelpReviewPolarity': YelpReviewPolarity +} + +URLS = {} +NUM_LINES = {} +MD5 = {} +for dataset in DATASETS: + dataset_module_path = "torchtext.datasets." + dataset.lower() + dataset_module = importlib.import_module(dataset_module_path) + URLS[dataset] = dataset_module.URL + NUM_LINES[dataset] = dataset_module.NUM_LINES + MD5[dataset] = dataset_module.MD5 + +__all__ = sorted(list(map(str, DATASETS.keys()))) diff --git a/torchtext/datasets/ag_news.py b/torchtext/datasets/ag_news.py new file mode 100644 index 0000000000..e108ebcc35 --- /dev/null +++ b/torchtext/datasets/ag_news.py @@ -0,0 +1,38 @@ +from torchtext.utils import download_from_url, unicode_csv_reader +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +import os +import io + +URL = { + 'train': "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", + 'test': "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv", +} + +MD5 = { + 'train': "b1a00f826fdfbd249f79597b59e1dc12", + 'test': "d52ea96a97a2d943681189a97654912d", +} + +NUM_LINES = { + 'train': 120000, + 'test': 7600, +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def AG_NEWS(root, split): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + + path = download_from_url(URL[split], root=root, + path=os.path.join(root, split + ".csv"), + hash_value=MD5[split], + hash_type='md5') + return RawTextIterableDataset("AG_NEWS", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/amazonreviewfull.py b/torchtext/datasets/amazonreviewfull.py new file mode 100644 index 0000000000..70395fd267 --- /dev/null +++ b/torchtext/datasets/amazonreviewfull.py @@ -0,0 +1,44 @@ +from torchtext.utils import unicode_csv_reader +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import download_extract_validate +import io +import logging + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA' + +MD5 = '57d28bd5d930e772930baddf36641c7c' + +NUM_LINES = { + 'train': 3000000, + 'test': 650000, +} + +_PATH = 'amazon_review_full_csv.tar.gz' + +_EXTRACTED_FILES = { + 'train': 'amazon_review_full_csv/train.csv', + 'test': 'amazon_review_full_csv/test.csv' +} + +_EXTRACTED_FILES_MD5 = { + 'train': "31b268b09fd794e0ca5a1f59a0358677", + 'test': "0f1e78ab60f625f2a30eab6810ef987c" +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def AmazonReviewFull(root, split): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + + path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[split], + _EXTRACTED_FILES_MD5[split], hash_type="md5") + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset("AmazonReviewFull", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/amazonreviewpolarity.py b/torchtext/datasets/amazonreviewpolarity.py new file mode 100644 index 0000000000..49555b5d9c --- /dev/null +++ b/torchtext/datasets/amazonreviewpolarity.py @@ -0,0 +1,43 @@ +from torchtext.utils import unicode_csv_reader +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import download_extract_validate +import io +import logging + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM' + +MD5 = 'fe39f8b653cada45afd5792e0f0e8f9b' + +NUM_LINES = { + 'train': 3600000, + 'test': 400000, +} + +_PATH = 'amazon_review_polarity_csv.tar.gz' + +_EXTRACTED_FILES = { + 'train': 'amazon_review_polarity_csv/train.csv', + 'test': 'amazon_review_polarity_csv/test.csv' +} + +_EXTRACTED_FILES_MD5 = { + 'train': "520937107c39a2d1d1f66cd410e9ed9e", + 'test': "f4c8bded2ecbde5f996b675db6228f16" +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def AmazonReviewPolarity(root, split): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[split], + _EXTRACTED_FILES_MD5[split], hash_type="md5") + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset("AmazonReviewPolarity", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/conll2000chunking.py b/torchtext/datasets/conll2000chunking.py new file mode 100644 index 0000000000..71680a5a67 --- /dev/null +++ b/torchtext/datasets/conll2000chunking.py @@ -0,0 +1,62 @@ +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import download_extract_validate +import os +import logging + +URL = { + 'train': "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", + 'test': "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz", +} + +MD5 = { + 'train': "6969c2903a1f19a83569db643e43dcc8", + 'test': "a916e1c2d83eb3004b38fc6fcd628939", +} + +NUM_LINES = { + 'train': 8936, + 'test': 2012, +} + +_EXTRACTED_FILES = { + 'train': 'train.txt', + 'test': 'test.txt' +} + +_EXTRACTED_FILES_MD5 = { + 'train': "2e2f24e90e20fcb910ab2251b5ed8cd0", + 'test': "56944df34be553b72a2a634e539a0951" +} + + +def _create_data_from_iob(data_path, separator): + with open(data_path, encoding="utf-8") as input_file: + columns = [] + for line in input_file: + line = line.strip() + if line == "": + if columns: + yield columns + columns = [] + else: + for i, column in enumerate(line.split(separator)): + if len(columns) < i + 1: + columns.append([]) + columns[i].append(column) + if len(columns) > 0: + yield columns + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def CoNLL2000Chunking(root, split): + # Create a dataset specific subfolder to deal with generic download filenames + root = os.path.join(root, 'conll2000chunking') + path = os.path.join(root, split + ".txt.gz") + data_filename = download_extract_validate(root, URL[split], MD5[split], path, os.path.join(root, _EXTRACTED_FILES[split]), + _EXTRACTED_FILES_MD5[split], hash_type="md5") + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset("CoNLL2000Chunking", NUM_LINES[split], + _create_data_from_iob(data_filename, " ")) diff --git a/torchtext/experimental/datasets/raw/dbpedia.py b/torchtext/datasets/dbpedia.py similarity index 53% rename from torchtext/experimental/datasets/raw/dbpedia.py rename to torchtext/datasets/dbpedia.py index 256a402903..16be98897f 100644 --- a/torchtext/experimental/datasets/raw/dbpedia.py +++ b/torchtext/datasets/dbpedia.py @@ -1,8 +1,8 @@ from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import find_match import os import io @@ -18,9 +18,9 @@ _PATH = 'dbpedia_csv.tar.gz' -@wrap_split_argument -@add_docstring_header() -def DBpedia(root='.data', split=('train', 'test'), offset=0): +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def DBpedia(root, split): def _create_data_from_csv(data_path): with io.open(data_path, encoding="utf8") as f: reader = unicode_csv_reader(f) @@ -31,9 +31,6 @@ def _create_data_from_csv(data_path): hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("DBpedia", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets + path = find_match(split + '.csv', extracted_files) + return RawTextIterableDataset("DBpedia", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/enwik9.py b/torchtext/datasets/enwik9.py new file mode 100644 index 0000000000..cd3de45723 --- /dev/null +++ b/torchtext/datasets/enwik9.py @@ -0,0 +1,25 @@ +import logging +from torchtext.utils import download_from_url, extract_archive +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +import io + +URL = 'http://mattmahoney.net/dc/enwik9.zip' + +MD5 = '3e773f8a1577fda2e27f871ca17f31fd' + +NUM_LINES = { + 'train': 13147026 +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train',)) +def EnWik9(root, split): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + path = extracted_files[0] + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset('EnWik9', + NUM_LINES[split], iter(io.open(path, encoding="utf8"))) diff --git a/torchtext/experimental/datasets/raw/imdb.py b/torchtext/datasets/imdb.py similarity index 59% rename from torchtext/experimental/datasets/raw/imdb.py rename to torchtext/datasets/imdb.py index 2cde9a7658..42e843094f 100644 --- a/torchtext/experimental/datasets/raw/imdb.py +++ b/torchtext/datasets/imdb.py @@ -1,7 +1,7 @@ from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header import io URL = 'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz' @@ -16,9 +16,9 @@ _PATH = 'aclImdb_v1.tar.gz' -@wrap_split_argument -@add_docstring_header() -def IMDB(root='.data', split=('train', 'test'), offset=0): +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def IMDB(root, split): def generate_imdb_data(key, extracted_files): for fname in extracted_files: if 'urls' in fname: @@ -30,8 +30,5 @@ def generate_imdb_data(key, extracted_files): dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - datasets = [] - for item in split: - iterator = generate_imdb_data(item, extracted_files) - datasets.append(RawTextIterableDataset("IMDB", NUM_LINES[item], iterator, offset=offset)) - return datasets + iterator = generate_imdb_data(split, extracted_files) + return RawTextIterableDataset("IMDB", NUM_LINES[split], iterator) diff --git a/torchtext/datasets/iwslt2016.py b/torchtext/datasets/iwslt2016.py new file mode 100644 index 0000000000..3d1c598b62 --- /dev/null +++ b/torchtext/datasets/iwslt2016.py @@ -0,0 +1,331 @@ +import os +import io +import codecs +import xml.etree.ElementTree as ET +from torchtext.utils import (download_from_url, extract_archive) +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument + + +SUPPORTED_DATASETS = { + 'URL': 'https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8', + '_PATH': '2016-01.tgz', + 'MD5': 'c393ed3fc2a1b0f004b3331043f615ae', + 'valid_test': ['dev2010', 'tst2010', 'tst2011', 'tst2012', 'tst2013', 'tst2014'], + 'language_pair': { + 'en': ['ar', 'de', 'fr', 'cs'], + 'ar': ['en'], + 'fr': ['en'], + 'de': ['en'], + 'cs': ['en'], + }, + 'year': 16, + +} + +URL = SUPPORTED_DATASETS['URL'] +MD5 = SUPPORTED_DATASETS['MD5'] + +NUM_LINES = { + 'train': { + 'train': { + ('en', 'ar'): 224126, + ('en', 'de'): 196884, + ('en', 'fr'): 220400, + ('en', 'cs'): 114390, + ('ar', 'en'): 224126, + ('fr', 'en'): 220400, + ('de', 'en'): 196884, + ('cs', 'en'): 114390 + } + }, + 'valid': { + 'dev2010': { + ('en', 'ar'): 887, + ('en', 'de'): 887, + ('en', 'fr'): 887, + ('en', 'cs'): 480, + ('ar', 'en'): 887, + ('fr', 'en'): 887, + ('de', 'en'): 887, + ('cs', 'en'): 480 + }, + 'tst2010': { + ('en', 'ar'): 1569, + ('en', 'de'): 1565, + ('en', 'fr'): 1664, + ('en', 'cs'): 1511, + ('ar', 'en'): 1569, + ('fr', 'en'): 1664, + ('de', 'en'): 1565, + ('cs', 'en'): 1511 + }, + 'tst2011': { + ('en', 'ar'): 1199, + ('en', 'de'): 1433, + ('en', 'fr'): 818, + ('en', 'cs'): 1013, + ('ar', 'en'): 1199, + ('fr', 'en'): 818, + ('de', 'en'): 1433, + ('cs', 'en'): 1013 + }, + 'tst2012': { + ('en', 'ar'): 1702, + ('en', 'de'): 1700, + ('en', 'fr'): 1124, + ('en', 'cs'): 1385, + ('ar', 'en'): 1702, + ('fr', 'en'): 1124, + ('de', 'en'): 1700, + ('cs', 'en'): 1385 + }, + 'tst2013': { + ('en', 'ar'): 1169, + ('en', 'de'): 993, + ('en', 'fr'): 1026, + ('en', 'cs'): 1327, + ('ar', 'en'): 1169, + ('fr', 'en'): 1026, + ('de', 'en'): 993, + ('cs', 'en'): 1327 + }, + 'tst2014': { + ('en', 'ar'): 1107, + ('en', 'de'): 1305, + ('en', 'fr'): 1305, + ('ar', 'en'): 1107, + ('fr', 'en'): 1305, + ('de', 'en'): 1305 + } + }, + 'test': { + 'dev2010': { + ('en', 'ar'): 887, + ('en', 'de'): 887, + ('en', 'fr'): 887, + ('en', 'cs'): 480, + ('ar', 'en'): 887, + ('fr', 'en'): 887, + ('de', 'en'): 887, + ('cs', 'en'): 480 + }, + 'tst2010': { + ('en', 'ar'): 1569, + ('en', 'de'): 1565, + ('en', 'fr'): 1664, + ('en', 'cs'): 1511, + ('ar', 'en'): 1569, + ('fr', 'en'): 1664, + ('de', 'en'): 1565, + ('cs', 'en'): 1511 + }, + 'tst2011': { + ('en', 'ar'): 1199, + ('en', 'de'): 1433, + ('en', 'fr'): 818, + ('en', 'cs'): 1013, + ('ar', 'en'): 1199, + ('fr', 'en'): 818, + ('de', 'en'): 1433, + ('cs', 'en'): 1013 + }, + 'tst2012': { + ('en', 'ar'): 1702, + ('en', 'de'): 1700, + ('en', 'fr'): 1124, + ('en', 'cs'): 1385, + ('ar', 'en'): 1702, + ('fr', 'en'): 1124, + ('de', 'en'): 1700, + ('cs', 'en'): 1385 + }, + 'tst2013': { + ('en', 'ar'): 1169, + ('en', 'de'): 993, + ('en', 'fr'): 1026, + ('en', 'cs'): 1327, + ('ar', 'en'): 1169, + ('fr', 'en'): 1026, + ('de', 'en'): 993, + ('cs', 'en'): 1327 + }, + 'tst2014': { + ('en', 'ar'): 1107, + ('en', 'de'): 1305, + ('en', 'fr'): 1305, + ('ar', 'en'): 1107, + ('fr', 'en'): 1305, + ('de', 'en'): 1305 + } + } +} + +SET_NOT_EXISTS = { + ('en', 'ar'): [], + ('en', 'de'): [], + ('en', 'fr'): [], + ('en', 'cs'): ['tst2014'], + ('ar', 'en'): [], + ('fr', 'en'): [], + ('de', 'en'): [], + ('cs', 'en'): ['tst2014'] +} + + +def _read_text_iterator(path): + with io.open(path, encoding="utf8") as f: + for row in f: + yield row + + +def _clean_xml_file(f_xml): + f_txt = os.path.splitext(f_xml)[0] + with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: + root = ET.parse(f_xml).getroot()[0] + for doc in root.findall('doc'): + for e in doc.findall('seg'): + fd_txt.write(e.text.strip() + '\n') + + +def _clean_tags_file(f_orig): + xml_tags = [ + '>> from torchtext.experimental.datasets.raw import Multi30k - >>> train_dataset, valid_dataset, test_dataset = Multi30k() - - The available dataset include: - test_2016_flickr.cs - test_2016_flickr.de - test_2016_flickr.en - test_2016_flickr.fr - test_2017_flickr.de - test_2017_flickr.en - test_2017_flickr.fr - test_2017_mscoco.de - test_2017_mscoco.en - test_2017_mscoco.fr - test_2018_flickr.en - train.cs - train.de - train.en - train.fr - val.cs - val.de - val.en - val.fr - test_2016.1.de - test_2016.1.en - test_2016.2.de - test_2016.2.en - test_2016.3.de - test_2016.3.en - test_2016.4.de - test_2016.4.en - test_2016.5.de - test_2016.5.en - train.1.de - train.1.en - train.2.de - train.2.en - train.3.de - train.3.en - train.4.de - train.4.en - train.5.de - train.5.en - val.1.de - val.1.en - val.2.de - val.2.en - val.3.de - val.3.en - val.4.de - val.4.en - val.5.de - val.5.en - """ if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ and not isinstance(test_filenames, tuple): raise ValueError("All filenames must be tuples") @@ -228,16 +161,11 @@ def Multi30k(root='.data', split=('train', 'valid', 'test'), offset=0, raise FileNotFoundError( "Files are not found for data type {}".format(key)) - datasets = [] - for key in split: - src_data_iter = _read_text_iterator(data_filenames[key][0]) - tgt_data_iter = _read_text_iterator(data_filenames[key][1]) - - def _iter(src_data_iter, tgt_data_iter): - for item in zip(src_data_iter, tgt_data_iter): - yield item + src_data_iter = _read_text_iterator(data_filenames[split][0]) + tgt_data_iter = _read_text_iterator(data_filenames[split][1]) - datasets.append( - RawTextIterableDataset("Multi30k", NUM_LINES[key], _iter(src_data_iter, tgt_data_iter), offset=offset)) + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item - return datasets + return RawTextIterableDataset("Multi30k", NUM_LINES[split], _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/datasets/penntreebank.py b/torchtext/datasets/penntreebank.py new file mode 100644 index 0000000000..3c23f0202d --- /dev/null +++ b/torchtext/datasets/penntreebank.py @@ -0,0 +1,36 @@ +import logging +from torchtext.utils import download_from_url +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +import io + +URL = { + 'train': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", + 'test': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", + 'valid': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt", +} + +MD5 = { + 'train': "f26c4b92c5fdc7b3f8c7cdcb991d8420", + 'valid': "aa0affc06ff7c36e977d7cd49e3839bf", + 'test': "8b80168b89c18661a38ef683c0dc3721", +} + +NUM_LINES = { + 'train': 42068, + 'valid': 3370, + 'test': 3761, +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'valid', 'test')) +def PennTreebank(root, split): + path = download_from_url(URL[split], + root=root, hash_value=MD5[split], + hash_type='md5') + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset('PennTreebank', + NUM_LINES[split], + iter(io.open(path, encoding="utf8"))) diff --git a/torchtext/datasets/sogounews.py b/torchtext/datasets/sogounews.py new file mode 100644 index 0000000000..5db30f8fd1 --- /dev/null +++ b/torchtext/datasets/sogounews.py @@ -0,0 +1,43 @@ +from torchtext.utils import unicode_csv_reader +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import download_extract_validate +import io +import logging + +URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE' + +MD5 = '0c1700ba70b73f964dd8de569d3fd03e' + +NUM_LINES = { + 'train': 450000, + 'test': 60000, +} + +_PATH = 'sogou_news_csv.tar.gz' + +_EXTRACTED_FILES = { + 'train': 'sogou_news_csv/train.csv', + 'test': 'sogou_news_csv/test.csv' +} + +_EXTRACTED_FILES_MD5 = { + 'train': "f36156164e6eac2feda0e30ad857eef0", + 'test': "59e493c41cee050329446d8c45615b38" +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def SogouNews(root, split): + def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[split], + _EXTRACTED_FILES_MD5[split], hash_type="md5") + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset("SogouNews", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/experimental/datasets/raw/squad1.py b/torchtext/datasets/squad1.py similarity index 63% rename from torchtext/experimental/datasets/raw/squad1.py rename to torchtext/datasets/squad1.py index 97962c42ec..24e4a6b1a4 100644 --- a/torchtext/experimental/datasets/raw/squad1.py +++ b/torchtext/datasets/squad1.py @@ -1,8 +1,8 @@ from torchtext.utils import download_from_url import json -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header URL = { 'train': "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", @@ -36,10 +36,9 @@ def _create_data_from_json(data_path): yield (_context, _question, _answers, _answer_start) -@wrap_split_argument -@add_docstring_header() -def SQuAD1(root='.data', split=('train', 'dev'), offset=0): - extracted_files = {key: download_from_url(URL[key], root=root, - hash_value=MD5[key], hash_type='md5') for key in split} - return [RawTextIterableDataset('SQuAD1', NUM_LINES[item], - _create_data_from_json(extracted_files[item]), offset=offset) for item in split] +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'dev')) +def SQuAD1(root, split): + extracted_files = download_from_url(URL[split], root=root, hash_value=MD5[split], hash_type='md5') + return RawTextIterableDataset('SQuAD1', NUM_LINES[split], + _create_data_from_json(extracted_files)) diff --git a/torchtext/experimental/datasets/raw/squad2.py b/torchtext/datasets/squad2.py similarity index 63% rename from torchtext/experimental/datasets/raw/squad2.py rename to torchtext/datasets/squad2.py index a61e305429..9e24beded3 100644 --- a/torchtext/experimental/datasets/raw/squad2.py +++ b/torchtext/datasets/squad2.py @@ -1,8 +1,8 @@ from torchtext.utils import download_from_url import json -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header URL = { 'train': "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", @@ -36,10 +36,9 @@ def _create_data_from_json(data_path): yield (_context, _question, _answers, _answer_start) -@wrap_split_argument -@add_docstring_header() -def SQuAD2(root='.data', split=('train', 'dev'), offset=0): - extracted_files = {key: download_from_url(URL[key], root=root, - hash_value=MD5[key], hash_type='md5') for key in split} - return [RawTextIterableDataset('SQuAD2', NUM_LINES[item], - _create_data_from_json(extracted_files[item]), offset=offset) for item in split] +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'dev')) +def SQuAD2(root, split): + extracted_files = download_from_url(URL[split], root=root, hash_value=MD5[split], hash_type='md5') + return RawTextIterableDataset('SQuAD2', NUM_LINES[split], + _create_data_from_json(extracted_files)) diff --git a/torchtext/datasets/udpos.py b/torchtext/datasets/udpos.py new file mode 100644 index 0000000000..1942e5ecbd --- /dev/null +++ b/torchtext/datasets/udpos.py @@ -0,0 +1,46 @@ +from torchtext.utils import download_from_url, extract_archive +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import find_match + +URL = 'https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip' + +MD5 = 'bdcac7c52d934656bae1699541424545' + +NUM_LINES = { + 'train': 12543, + 'valid': 2002, + 'test': 2077, +} + + +def _create_data_from_iob(data_path, separator="\t"): + with open(data_path, encoding="utf-8") as input_file: + columns = [] + for line in input_file: + line = line.strip() + if line == "": + if columns: + yield columns + columns = [] + else: + for i, column in enumerate(line.split(separator)): + if len(columns) < i + 1: + columns.append([]) + columns[i].append(column) + if len(columns) > 0: + yield columns + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'valid', 'test')) +def UDPOS(root, split): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + if split == 'valid': + path = find_match("dev.txt", extracted_files) + else: + path = find_match(split + ".txt", extracted_files) + return RawTextIterableDataset("UDPOS", NUM_LINES[split], + _create_data_from_iob(path)) diff --git a/torchtext/datasets/wikitext103.py b/torchtext/datasets/wikitext103.py new file mode 100644 index 0000000000..0222357036 --- /dev/null +++ b/torchtext/datasets/wikitext103.py @@ -0,0 +1,29 @@ +import logging +from torchtext.utils import download_from_url, extract_archive +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import find_match +import io + +URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip' + +MD5 = '9ddaacaf6af0710eda8c456decff7832' + +NUM_LINES = { + 'train': 1801350, + 'valid': 3760, + 'test': 4358, +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'valid', 'test')) +def WikiText103(root, split): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + path = find_match(split, extracted_files) + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset('WikiText103', + NUM_LINES[split], iter(io.open(path, encoding="utf8"))) diff --git a/torchtext/datasets/wikitext2.py b/torchtext/datasets/wikitext2.py new file mode 100644 index 0000000000..76e1047ab0 --- /dev/null +++ b/torchtext/datasets/wikitext2.py @@ -0,0 +1,28 @@ +import logging +from torchtext.utils import download_from_url, extract_archive +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import find_match +import io + +URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip' + +MD5 = '542ccefacc6c27f945fb54453812b3cd' + +NUM_LINES = { + 'train': 36718, + 'valid': 3760, + 'test': 4358, +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'valid', 'test')) +def WikiText2(root, split): + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') + extracted_files = extract_archive(dataset_tar) + path = find_match(split, extracted_files) + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset('WikiText2', + NUM_LINES[split], iter(io.open(path, encoding="utf8"))) diff --git a/torchtext/experimental/datasets/raw/wmt14.py b/torchtext/datasets/wmt14.py similarity index 83% rename from torchtext/experimental/datasets/raw/wmt14.py rename to torchtext/datasets/wmt14.py index f610df417a..1215558123 100644 --- a/torchtext/experimental/datasets/raw/wmt14.py +++ b/torchtext/datasets/wmt14.py @@ -3,9 +3,9 @@ import codecs import xml.etree.ElementTree as ET from torchtext.utils import (download_from_url, extract_archive) -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header URL = 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8' @@ -43,13 +43,13 @@ def _clean_tags_file(f_orig): f_txt = f_orig.replace('.tags', '') with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt, \ io.open(f_orig, mode='r', encoding='utf-8') as fd_orig: - for l in fd_orig: - if not any(tag in l for tag in xml_tags): + for line in fd_orig: + if not any(tag in line for tag in xml_tags): # TODO: Fix utf-8 next line mark # fd_txt.write(l.strip() + '\n') # fd_txt.write(l.strip() + u"\u0085") # fd_txt.write(l.lstrip()) - fd_txt.write(l.strip() + '\n') + fd_txt.write(line.strip() + '\n') def _construct_filenames(filename, languages): @@ -68,9 +68,9 @@ def _construct_filepaths(paths, src_filename, tgt_filename): return (src_path, tgt_path) -@wrap_split_argument -@add_docstring_header() -def WMT14(root='.data', split=('train', 'valid', 'test'), offset=0, +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'valid', 'test')) +def WMT14(root, split, train_filenames=('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en'), valid_filenames=('newstest2013.tok.bpe.32000.de', @@ -84,10 +84,6 @@ def WMT14(root='.data', split=('train', 'valid', 'test'), offset=0, test_filenames: the source and target filenames for test. Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') - Examples: - >>> from torchtext.experimental.datasets.raw import WMT14 - >>> train_dataset, valid_dataset, test_dataset = WMT14() - The available datasets include: newstest2016.en newstest2016.de @@ -173,16 +169,11 @@ def WMT14(root='.data', split=('train', 'valid', 'test'), offset=0, raise FileNotFoundError( "Files are not found for data type {}".format(key)) - datasets = [] - for key in split: - src_data_iter = _read_text_iterator(data_filenames[key][0]) - tgt_data_iter = _read_text_iterator(data_filenames[key][1]) - - def _iter(src_data_iter, tgt_data_iter): - for item in zip(src_data_iter, tgt_data_iter): - yield item + src_data_iter = _read_text_iterator(data_filenames[split][0]) + tgt_data_iter = _read_text_iterator(data_filenames[split][1]) - datasets.append( - RawTextIterableDataset("WMT14", NUM_LINES[key], _iter(src_data_iter, tgt_data_iter), offset=offset)) + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item - return datasets + return RawTextIterableDataset("WMT14", NUM_LINES[split], _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/datasets/wmtnewscrawl.py b/torchtext/datasets/wmtnewscrawl.py new file mode 100644 index 0000000000..709ca393c3 --- /dev/null +++ b/torchtext/datasets/wmtnewscrawl.py @@ -0,0 +1,55 @@ +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import download_extract_validate +import io +import logging + +URL = 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' + +MD5 = 'c70da2ba79db33fb0fc9119cbad16260' + +NUM_LINES = { + 'train': 17676013, +} + +_PATH = "training-monolingual-news-2010.tgz" + +_AVAILABLE_YEARS = [2010] +_AVAILABLE_LANGUAGES = [ + "cs", + "en", + "fr", + "es", + "de" +] + +_EXTRACTED_FILES = { + "cs": "training-monolingual/news.2010.cs.shuffled", + "de": "training-monolingual/news.2010.de.shuffled", + "en": "training-monolingual/news.2010.en.shuffled", + "es": "training-monolingual/news.2010.es.shuffled", + "fr": "training-monolingual/news.2010.fr.shuffled" +} + +_EXTRACTED_FILES_MD5 = { + "cs": "b60fdbf95a2e97bae3a7d04cc81df925", + "de": "e59a0f0c6eeeb2113c0da1873a2e1035", + "en": "234a50914d87158754815a0bd86d7b9d", + "es": "aee3d773a0c054c5ac313a42d08b7020", + "fr": "066d671533f78bfe139cf7052574fd5a" +} + + +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train',)) +def WMTNewsCrawl(root, split, year=2010, language='en'): + if year not in _AVAILABLE_YEARS: + raise ValueError("{} not available. Please choose from years {}".format(year, _AVAILABLE_YEARS)) + if language not in _AVAILABLE_LANGUAGES: + raise ValueError("{} not available. Please choose from languages {}".format(language, _AVAILABLE_LANGUAGES)) + path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[language], + _EXTRACTED_FILES_MD5[language], hash_type="md5") + logging.info('Creating {} data'.format(split)) + return RawTextIterableDataset("WMTNewsCrawl", + NUM_LINES[split], iter(io.open(path, encoding="utf8"))) diff --git a/torchtext/experimental/datasets/raw/yahooanswers.py b/torchtext/datasets/yahooanswers.py similarity index 53% rename from torchtext/experimental/datasets/raw/yahooanswers.py rename to torchtext/datasets/yahooanswers.py index 563c6008e2..8388eaf7fd 100644 --- a/torchtext/experimental/datasets/raw/yahooanswers.py +++ b/torchtext/datasets/yahooanswers.py @@ -1,8 +1,8 @@ from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import find_match import os import io @@ -18,9 +18,9 @@ _PATH = 'yahoo_answers_csv.tar.gz' -@wrap_split_argument -@add_docstring_header() -def YahooAnswers(root='.data', split=('train', 'test'), offset=0): +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def YahooAnswers(root, split): def _create_data_from_csv(data_path): with io.open(data_path, encoding="utf8") as f: reader = unicode_csv_reader(f) @@ -31,9 +31,6 @@ def _create_data_from_csv(data_path): hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("YahooAnswers", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets + path = find_match(split + '.csv', extracted_files) + return RawTextIterableDataset("YahooAnswers", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/experimental/datasets/raw/yelpreviewfull.py b/torchtext/datasets/yelpreviewfull.py similarity index 53% rename from torchtext/experimental/datasets/raw/yelpreviewfull.py rename to torchtext/datasets/yelpreviewfull.py index eca3648fbd..da0f7accc2 100644 --- a/torchtext/experimental/datasets/raw/yelpreviewfull.py +++ b/torchtext/datasets/yelpreviewfull.py @@ -1,8 +1,8 @@ from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import find_match import os import io @@ -18,9 +18,9 @@ _PATH = 'yelp_review_full_csv.tar.gz' -@wrap_split_argument -@add_docstring_header() -def YelpReviewFull(root='.data', split=('train', 'test'), offset=0): +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def YelpReviewFull(root, split): def _create_data_from_csv(data_path): with io.open(data_path, encoding="utf8") as f: reader = unicode_csv_reader(f) @@ -31,9 +31,6 @@ def _create_data_from_csv(data_path): hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("YelpReviewFull", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets + path = find_match(split + '.csv', extracted_files) + return RawTextIterableDataset("YelpReviewFull", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/experimental/datasets/raw/yelpreviewpolarity.py b/torchtext/datasets/yelpreviewpolarity.py similarity index 52% rename from torchtext/experimental/datasets/raw/yelpreviewpolarity.py rename to torchtext/datasets/yelpreviewpolarity.py index 22e82618a7..4d621459c6 100644 --- a/torchtext/experimental/datasets/raw/yelpreviewpolarity.py +++ b/torchtext/datasets/yelpreviewpolarity.py @@ -1,8 +1,8 @@ from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match +from torchtext.data.datasets_utils import RawTextIterableDataset +from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import find_match import os import io @@ -18,9 +18,9 @@ _PATH = 'yelp_review_polarity_csv.tar.gz' -@wrap_split_argument -@add_docstring_header() -def YelpReviewPolarity(root='.data', split=('train', 'test'), offset=0): +@add_docstring_header(num_lines=NUM_LINES) +@wrap_split_argument(('train', 'test')) +def YelpReviewPolarity(root, split): def _create_data_from_csv(data_path): with io.open(data_path, encoding="utf8") as f: reader = unicode_csv_reader(f) @@ -31,9 +31,6 @@ def _create_data_from_csv(data_path): hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("YelpReviewPolarity", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets + path = find_match(split + '.csv', extracted_files) + return RawTextIterableDataset("YelpReviewPolarity", NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/experimental/datasets/__init__.py b/torchtext/experimental/datasets/__init__.py index bf2eca3416..0574c3f2cd 100644 --- a/torchtext/experimental/datasets/__init__.py +++ b/torchtext/experimental/datasets/__init__.py @@ -4,7 +4,7 @@ AmazonReviewPolarity, AmazonReviewFull, IMDB from .text_classification import TextClassificationDataset # NOQA: F401 from .sequence_tagging import SequenceTaggingDataset, UDPOS, CoNLL2000Chunking # NOQA: F401 -from .translation import TranslationDataset, Multi30k, IWSLT, WMT14 # NOQA: F401 +from .translation import TranslationDataset, Multi30k, IWSLT2016, IWSLT2017, WMT14 # NOQA: F401 from .question_answer import QuestionAnswerDataset, SQuAD1, SQuAD2 # NOQA: F401 @@ -24,7 +24,8 @@ 'UDPOS': UDPOS, 'CoNLL2000Chunking': CoNLL2000Chunking, 'Multi30k': Multi30k, - 'IWSLT': IWSLT, + 'IWSLT2016': IWSLT2016, + 'IWSLT2017': IWSLT2017, 'WMT14': WMT14, 'SQuAD1': SQuAD1, 'SQuAD2': SQuAD2} diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index fb575e16f6..cef17be4c4 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -2,9 +2,9 @@ import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets import raw -from torchtext.experimental.datasets.raw.common import check_default_set -from torchtext.experimental.datasets.raw.common import wrap_datasets +from torchtext import datasets as raw +from torchtext.data.datasets_utils import check_default_set +from torchtext.data.datasets_utils import wrap_datasets logger_ = logging.getLogger(__name__) diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index 14e601e328..b232791828 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -2,9 +2,9 @@ import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets import raw -from torchtext.experimental.datasets.raw.common import check_default_set -from torchtext.experimental.datasets.raw.common import wrap_datasets +from torchtext import datasets as raw +from torchtext.data.datasets_utils import check_default_set +from torchtext.data.datasets_utils import wrap_datasets from torchtext.experimental.functional import ( totensor, vocab_func, diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py deleted file mode 100644 index bee58c74ec..0000000000 --- a/torchtext/experimental/datasets/raw/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -import importlib -from .ag_news import AG_NEWS -from .amazonreviewfull import AmazonReviewFull -from .amazonreviewpolarity import AmazonReviewPolarity -from .conll2000chunking import CoNLL2000Chunking -from .dbpedia import DBpedia -from .imdb import IMDB -from .iwslt import IWSLT -from .multi30k import Multi30k -from .penntreebank import PennTreebank -from .sogounews import SogouNews -from .squad1 import SQuAD1 -from .squad2 import SQuAD2 -from .udpos import UDPOS -from .wikitext103 import WikiText103 -from .wikitext2 import WikiText2 -from .wmt14 import WMT14 -from .wmtnewscrawl import WMTNewsCrawl -from .yahooanswers import YahooAnswers -from .yelpreviewfull import YelpReviewFull -from .yelpreviewpolarity import YelpReviewPolarity - -DATASETS = { - 'AG_NEWS': AG_NEWS, - 'AmazonReviewFull': AmazonReviewFull, - 'AmazonReviewPolarity': AmazonReviewPolarity, - 'CoNLL2000Chunking': CoNLL2000Chunking, - 'DBpedia': DBpedia, - 'IMDB': IMDB, - 'IWSLT': IWSLT, - 'Multi30k': Multi30k, - 'PennTreebank': PennTreebank, - 'SQuAD1': SQuAD1, - 'SQuAD2': SQuAD2, - 'SogouNews': SogouNews, - 'UDPOS': UDPOS, - 'WMT14': WMT14, - 'WMTNewsCrawl': WMTNewsCrawl, - 'WikiText103': WikiText103, - 'WikiText2': WikiText2, - 'YahooAnswers': YahooAnswers, - 'YelpReviewFull': YelpReviewFull, - 'YelpReviewPolarity': YelpReviewPolarity -} - -URLS = {} -NUM_LINES = {} -MD5 = {} -for dataset in DATASETS: - dataset_module_path = "torchtext.experimental.datasets.raw." + dataset.lower() - dataset_module = importlib.import_module(dataset_module_path) - URLS[dataset] = dataset_module.URL - NUM_LINES[dataset] = dataset_module.NUM_LINES - MD5[dataset] = dataset_module.MD5 - -__all__ = sorted(list(map(str, DATASETS.keys()))) diff --git a/torchtext/experimental/datasets/raw/ag_news.py b/torchtext/experimental/datasets/raw/ag_news.py deleted file mode 100644 index 91843f5206..0000000000 --- a/torchtext/experimental/datasets/raw/ag_news.py +++ /dev/null @@ -1,44 +0,0 @@ -from torchtext.utils import download_from_url, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import os -import io - -URL = { - 'train': "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", - 'test': "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv", -} - -MD5 = { - 'train': "b1a00f826fdfbd249f79597b59e1dc12", - 'test': "d52ea96a97a2d943681189a97654912d", -} - -NUM_LINES = { - 'train': 120000, - 'test': 7600, -} - - -@wrap_split_argument -@add_docstring_header() -def AG_NEWS(root='.data', split=('train', 'test'), offset=0): - - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - - extracted_files = [download_from_url(URL[item], root=root, - path=os.path.join(root, item + ".csv"), - hash_value=MD5[item], - hash_type='md5') for item in ('train', 'test')] - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("AG_NEWS", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets diff --git a/torchtext/experimental/datasets/raw/amazonreviewfull.py b/torchtext/experimental/datasets/raw/amazonreviewfull.py deleted file mode 100644 index 7bbe72ba95..0000000000 --- a/torchtext/experimental/datasets/raw/amazonreviewfull.py +++ /dev/null @@ -1,39 +0,0 @@ -from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import os -import io - -URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA' - -MD5 = '57d28bd5d930e772930baddf36641c7c' - -NUM_LINES = { - 'train': 3000000, - 'test': 650000, -} - -_PATH = 'amazon_review_full_csv.tar.gz' - - -@wrap_split_argument -@add_docstring_header() -def AmazonReviewFull(root='.data', split=('train', 'test'), offset=0): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - dataset_tar = download_from_url(URL, root=root, - path=os.path.join(root, _PATH), - hash_value=MD5, hash_type='md5') - extracted_files = extract_archive(dataset_tar) - - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("AmazonReviewFull", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets diff --git a/torchtext/experimental/datasets/raw/amazonreviewpolarity.py b/torchtext/experimental/datasets/raw/amazonreviewpolarity.py deleted file mode 100644 index 36d4583c2f..0000000000 --- a/torchtext/experimental/datasets/raw/amazonreviewpolarity.py +++ /dev/null @@ -1,39 +0,0 @@ -from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import os -import io - -URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM' - -MD5 = 'fe39f8b653cada45afd5792e0f0e8f9b' - -NUM_LINES = { - 'train': 3600000, - 'test': 400000, -} - -_PATH = 'amazon_review_polarity_csv.tar.gz' - - -@wrap_split_argument -@add_docstring_header() -def AmazonReviewPolarity(root='.data', split=('train', 'test'), offset=0): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - dataset_tar = download_from_url(URL, root=root, - path=os.path.join(root, _PATH), - hash_value=MD5, hash_type='md5') - extracted_files = extract_archive(dataset_tar) - - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("AmazonReviewPolarity", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets diff --git a/torchtext/experimental/datasets/raw/common.py b/torchtext/experimental/datasets/raw/common.py deleted file mode 100644 index 51a334385a..0000000000 --- a/torchtext/experimental/datasets/raw/common.py +++ /dev/null @@ -1,180 +0,0 @@ -import torch -import inspect -import functools - - -def check_default_set(split, target_select, dataset_name): - # Check whether given object split is either a tuple of strings or string - # and represents a valid selection of options given by the tuple of strings - # target_select. - if isinstance(split, str): - split = (split,) - if isinstance(target_select, str): - target_select = (target_select,) - if not isinstance(split, tuple): - raise ValueError("Internal error: Expected split to be of type tuple.") - if not set(split).issubset(set(target_select)): - raise TypeError('Given selection {} of splits is not supported for dataset {}. Please choose from {}.'.format( - split, dataset_name, target_select)) - return split - - -def wrap_datasets(datasets, split): - # Wrap return value for _setup_datasets functions to support singular values instead - # of tuples when split is a string. - if isinstance(split, str): - if len(datasets) != 1: - raise ValueError("Internal error: Expected number of datasets is not 1.") - return datasets[0] - return datasets - - -def find_match(match, lst): - """ - Searches list of strings and returns first entry that partially or fully - contains the given string match. - """ - for element in lst: - if match in element: - return element - return None - - -def dataset_docstring_header(fn): - """ - Returns docstring for a dataset based on function arguments. - - Assumes function signature of form (root='.data', split=, offset=0, **kwargs) - """ - argspec = inspect.getfullargspec(fn) - if not (argspec.args[0] == "root" and - argspec.args[1] == "split" and - argspec.args[2] == "offset"): - raise ValueError("Internal Error: Given function {} did not adhere to standard signature.".format(fn)) - default_split = argspec.defaults[1] - - if isinstance(default_split, tuple): - example_subset = default_split[:2] - if len(default_split) < 3: - example_subset = (default_split[1],) - return """{} dataset - - Separately returns the {} split - - Args: - root: Directory where the datasets are saved. - Default: ".data" - split: split or splits to be returned. Can be a string or tuple of strings. - By default, all three datasets are generated. Users - could also choose any subset of them, for example {} or just 'train'. - Default: {} - offset: the number of the starting line. - Default: 0 - """.format(fn.__name__, "/".join(default_split), str(example_subset), str(default_split)) - - if isinstance(default_split, str): - return """{} dataset - - Only returns the {default_split} split - - Args: - root: Directory where the datasets are saved. - Default: ".data" - split: Only {default_split} is available. - Default: {default_split} - offset: the number of the starting line. - Default: 0""".format(fn.__name__, default_split=default_split) - - raise ValueError("default_split type expected to be of string or tuple but got {}".format(type(default_split))) - - -def add_docstring_header(): - def docstring_decorator(fn): - fn.__doc__ = dataset_docstring_header(fn) + fn.__doc__ if fn.__doc__ else "" - return fn - return docstring_decorator - - -def wrap_split_argument(fn): - """ - Wraps given function of specific signature to extend behavior of split - to support individual strings. The given function is expected to have a split - kwarg that accepts tuples of strings, e.g. ('train', 'valid') and the returned - function will have a split argument that also accepts strings, e.g. 'train', which - are then turned single entry tuples. Furthermore, the return value of the wrapped - function is unpacked if split is only a single string to enable behavior such as - - train = AG_NEWS(split='train') - train, valid = AG_NEWS(split=('train', 'valid')) - """ - - argspec = inspect.getfullargspec(fn) - if not (argspec.args[0] == "root" and - argspec.args[1] == "split" and - argspec.args[2] == "offset" and - argspec.defaults[0] == ".data" and - argspec.defaults[2] == 0 and - argspec.varargs is None and - argspec.varkw is None and - len(argspec.kwonlyargs) == 0 and - argspec.kwonlydefaults is None and - len(argspec.annotations) == 0 - ): - raise ValueError("Internal Error: Given function {} did not adhere to standard signature.".format(fn)) - - # functools.wraps only forwards __module__, __name__, etc - # (see https://docs.python.org/3/library/functools.html#functools.update_wrapper) - # but not default values of arguments. The wrapped function fn is assumed to have - # keyword arguments with default values only, so only a dictionary of default - # values is needed to support that behavior for new_fn as well. - fn_kwargs_dict = {} - for arg, default in zip(argspec.args[3:], argspec.defaults[3:]): - fn_kwargs_dict[arg] = default - - @functools.wraps(fn) - def new_fn(root='.data', split=argspec.defaults[1], offset=0, **kwargs): - for arg in fn_kwargs_dict: - if arg not in kwargs: - kwargs[arg] = fn_kwargs_dict[arg] - kwargs["root"] = root - kwargs["offset"] = offset - kwargs["split"] = check_default_set(split, argspec.defaults[1], fn.__name__) - result = fn(**kwargs) - return wrap_datasets(tuple(result), split) - - return new_fn - - -class RawTextIterableDataset(torch.utils.data.IterableDataset): - """Defines an abstraction for raw text iterable datasets. - """ - - def __init__(self, name, full_num_lines, iterator, offset=0): - """Initiate text-classification dataset. - """ - super(RawTextIterableDataset, self).__init__() - self.name = name - self.full_num_lines = full_num_lines - self._iterator = iterator - self.start = offset - if offset < 0: - raise ValueError("Given offset must be non-negative, got {} instead.".format(offset)) - self.num_lines = full_num_lines - offset - - def __iter__(self): - for i, item in enumerate(self._iterator): - if i < self.start: - continue - if self.num_lines and i >= (self.start + self.num_lines): - break - yield item - - def __next__(self): - item = next(self._iterator) - return item - - def __len__(self): - return self.num_lines - - def get_iterator(self): - return self._iterator diff --git a/torchtext/experimental/datasets/raw/conll2000chunking.py b/torchtext/experimental/datasets/raw/conll2000chunking.py deleted file mode 100644 index 2980708952..0000000000 --- a/torchtext/experimental/datasets/raw/conll2000chunking.py +++ /dev/null @@ -1,64 +0,0 @@ -from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header - -URL = { - 'train': "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", - 'test': "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz", -} - -MD5 = { - 'train': "6969c2903a1f19a83569db643e43dcc8", - 'test': "a916e1c2d83eb3004b38fc6fcd628939", -} - -NUM_LINES = { - 'train': 8936, - 'test': 2012, -} - - -def _create_data_from_iob(data_path, separator="\t"): - with open(data_path, encoding="utf-8") as input_file: - columns = [] - for line in input_file: - line = line.strip() - if line == "": - if columns: - yield columns - columns = [] - else: - for i, column in enumerate(line.split(separator)): - if len(columns) < i + 1: - columns.append([]) - columns[i].append(column) - if len(columns) > 0: - yield columns - - -def _construct_filepath(paths, file_suffix): - if file_suffix: - path = None - for p in paths: - path = p if p.endswith(file_suffix) else path - return path - return None - - -@wrap_split_argument -@add_docstring_header() -def CoNLL2000Chunking(root='.data', split=('train', 'test'), offset=0): - extracted_files = [] - for name, item in URL.items(): - dataset_tar = download_from_url(item, root=root, hash_value=MD5[name], hash_type='md5') - extracted_files.extend(extract_archive(dataset_tar)) - - data_filenames = { - "train": _construct_filepath(extracted_files, "train.txt"), - "valid": _construct_filepath(extracted_files, "dev.txt"), - "test": _construct_filepath(extracted_files, "test.txt") - } - return [RawTextIterableDataset("CoNLL2000Chunking", NUM_LINES[item], - _create_data_from_iob(data_filenames[item], " "), offset=offset) - if data_filenames[item] is not None else None for item in split] diff --git a/torchtext/experimental/datasets/raw/iwslt.py b/torchtext/experimental/datasets/raw/iwslt.py deleted file mode 100644 index a0fd4e6a5f..0000000000 --- a/torchtext/experimental/datasets/raw/iwslt.py +++ /dev/null @@ -1,287 +0,0 @@ -import os -import io -import codecs -import xml.etree.ElementTree as ET -from torchtext.utils import (download_from_url, extract_archive) -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header - -URL = 'https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8' - -_PATH = '2016-01.tgz' - -MD5 = 'c393ed3fc2a1b0f004b3331043f615ae' - -NUM_LINES = { - 'train': 196884, - 'valid': 993, - 'test': 1305, -} - - -def _read_text_iterator(path): - with io.open(path, encoding="utf8") as f: - for row in f: - yield row - - -def _clean_xml_file(f_xml): - f_txt = os.path.splitext(f_xml)[0] - with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: - root = ET.parse(f_xml).getroot()[0] - for doc in root.findall('doc'): - for e in doc.findall('seg'): - fd_txt.write(e.text.strip() + '\n') - - -def _clean_tags_file(f_orig): - xml_tags = [ - '>> from torchtext.experimental.datasets.raw import IWSLT - >>> train_dataset, valid_dataset, test_dataset = IWSLT() - - The available datasets include: - IWSLT16.TED.dev2010.ar-en.ar - IWSLT16.TED.dev2010.ar-en.en - IWSLT16.TED.dev2010.cs-en.cs - IWSLT16.TED.dev2010.cs-en.en - IWSLT16.TED.dev2010.de-en.de - IWSLT16.TED.dev2010.de-en.en - IWSLT16.TED.dev2010.en-ar.ar - IWSLT16.TED.dev2010.en-ar.en - IWSLT16.TED.dev2010.en-cs.cs - IWSLT16.TED.dev2010.en-cs.en - IWSLT16.TED.dev2010.en-de.de - IWSLT16.TED.dev2010.en-de.en - IWSLT16.TED.dev2010.en-fr.en - IWSLT16.TED.dev2010.en-fr.fr - IWSLT16.TED.dev2010.fr-en.en - IWSLT16.TED.dev2010.fr-en.fr - IWSLT16.TED.tst2010.ar-en.ar - IWSLT16.TED.tst2010.ar-en.en - IWSLT16.TED.tst2010.cs-en.cs - IWSLT16.TED.tst2010.cs-en.en - IWSLT16.TED.tst2010.de-en.de - IWSLT16.TED.tst2010.de-en.en - IWSLT16.TED.tst2010.en-ar.ar - IWSLT16.TED.tst2010.en-ar.en - IWSLT16.TED.tst2010.en-cs.cs - IWSLT16.TED.tst2010.en-cs.en - IWSLT16.TED.tst2010.en-de.de - IWSLT16.TED.tst2010.en-de.en - IWSLT16.TED.tst2010.en-fr.en - IWSLT16.TED.tst2010.en-fr.fr - IWSLT16.TED.tst2010.fr-en.en - IWSLT16.TED.tst2010.fr-en.fr - IWSLT16.TED.tst2011.ar-en.ar - IWSLT16.TED.tst2011.ar-en.en - IWSLT16.TED.tst2011.cs-en.cs - IWSLT16.TED.tst2011.cs-en.en - IWSLT16.TED.tst2011.de-en.de - IWSLT16.TED.tst2011.de-en.en - IWSLT16.TED.tst2011.en-ar.ar - IWSLT16.TED.tst2011.en-ar.en - IWSLT16.TED.tst2011.en-cs.cs - IWSLT16.TED.tst2011.en-cs.en - IWSLT16.TED.tst2011.en-de.de - IWSLT16.TED.tst2011.en-de.en - IWSLT16.TED.tst2011.en-fr.en - IWSLT16.TED.tst2011.en-fr.fr - IWSLT16.TED.tst2011.fr-en.en - IWSLT16.TED.tst2011.fr-en.fr - IWSLT16.TED.tst2012.ar-en.ar - IWSLT16.TED.tst2012.ar-en.en - IWSLT16.TED.tst2012.cs-en.cs - IWSLT16.TED.tst2012.cs-en.en - IWSLT16.TED.tst2012.de-en.de - IWSLT16.TED.tst2012.de-en.en - IWSLT16.TED.tst2012.en-ar.ar - IWSLT16.TED.tst2012.en-ar.en - IWSLT16.TED.tst2012.en-cs.cs - IWSLT16.TED.tst2012.en-cs.en - IWSLT16.TED.tst2012.en-de.de - IWSLT16.TED.tst2012.en-de.en - IWSLT16.TED.tst2012.en-fr.en - IWSLT16.TED.tst2012.en-fr.fr - IWSLT16.TED.tst2012.fr-en.en - IWSLT16.TED.tst2012.fr-en.fr - IWSLT16.TED.tst2013.ar-en.ar - IWSLT16.TED.tst2013.ar-en.en - IWSLT16.TED.tst2013.cs-en.cs - IWSLT16.TED.tst2013.cs-en.en - IWSLT16.TED.tst2013.de-en.de - IWSLT16.TED.tst2013.de-en.en - IWSLT16.TED.tst2013.en-ar.ar - IWSLT16.TED.tst2013.en-ar.en - IWSLT16.TED.tst2013.en-cs.cs - IWSLT16.TED.tst2013.en-cs.en - IWSLT16.TED.tst2013.en-de.de - IWSLT16.TED.tst2013.en-de.en - IWSLT16.TED.tst2013.en-fr.en - IWSLT16.TED.tst2013.en-fr.fr - IWSLT16.TED.tst2013.fr-en.en - IWSLT16.TED.tst2013.fr-en.fr - IWSLT16.TED.tst2014.ar-en.ar - IWSLT16.TED.tst2014.ar-en.en - IWSLT16.TED.tst2014.de-en.de - IWSLT16.TED.tst2014.de-en.en - IWSLT16.TED.tst2014.en-ar.ar - IWSLT16.TED.tst2014.en-ar.en - IWSLT16.TED.tst2014.en-de.de - IWSLT16.TED.tst2014.en-de.en - IWSLT16.TED.tst2014.en-fr.en - IWSLT16.TED.tst2014.en-fr.fr - IWSLT16.TED.tst2014.fr-en.en - IWSLT16.TED.tst2014.fr-en.fr - IWSLT16.TEDX.dev2012.de-en.de - IWSLT16.TEDX.dev2012.de-en.en - IWSLT16.TEDX.tst2013.de-en.de - IWSLT16.TEDX.tst2013.de-en.en - IWSLT16.TEDX.tst2014.de-en.de - IWSLT16.TEDX.tst2014.de-en.en - train.ar - train.ar-en.ar - train.ar-en.en - train.cs - train.cs-en.cs - train.cs-en.en - train.de - train.de-en.de - train.de-en.en - train.en - train.en-ar.ar - train.en-ar.en - train.en-cs.cs - train.en-cs.en - train.en-de.de - train.en-de.en - train.en-fr.en - train.en-fr.fr - train.fr - train.fr-en.en - train.fr-en.fr - train.tags.ar-en.ar - train.tags.ar-en.en - train.tags.cs-en.cs - train.tags.cs-en.en - train.tags.de-en.de - train.tags.de-en.en - train.tags.en-ar.ar - train.tags.en-ar.en - train.tags.en-cs.cs - train.tags.en-cs.en - train.tags.en-de.de - train.tags.en-de.en - train.tags.en-fr.en - train.tags.en-fr.fr - train.tags.fr-en.en - train.tags.fr-en.fr - """ - if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ - and not isinstance(test_filenames, tuple): - raise ValueError("All filenames must be tuples") - src_train, tgt_train = train_filenames - src_eval, tgt_eval = valid_filenames - src_test, tgt_test = test_filenames - - dataset_tar = download_from_url(URL, root=root, hash_value=MD5, path=os.path.join(root, _PATH), hash_type='md5') - extracted_files = extract_archive(dataset_tar) - - extracted_files = [] # list of paths to the extracted files - dataset_tar = download_from_url(URL, root=root, hash_value=MD5, - path=os.path.join(root, _PATH), hash_type='md5') - extracted_dataset_tar = extract_archive(dataset_tar) - # IWSLT dataset's url downloads a multilingual tgz. - # We need to take an extra step to pick out the specific language pair from it. - src_language = train_filenames[0].split(".")[-1] - tgt_language = train_filenames[1].split(".")[-1] - languages = "-".join([src_language, tgt_language]) - iwslt_tar = '.data/2016-01/texts/{}/{}/{}.tgz' - iwslt_tar = iwslt_tar.format( - src_language, tgt_language, languages) - extracted_dataset_tar = extract_archive(iwslt_tar) - extracted_files.extend(extracted_dataset_tar) - - # Clean the xml and tag file in the archives - file_archives = [] - for fname in extracted_files: - if 'xml' in fname: - _clean_xml_file(fname) - file_archives.append(os.path.splitext(fname)[0]) - elif "tags" in fname: - _clean_tags_file(fname) - file_archives.append(fname.replace('.tags', '')) - else: - file_archives.append(fname) - - data_filenames = { - "train": _construct_filepaths(file_archives, src_train, tgt_train), - "valid": _construct_filepaths(file_archives, src_eval, tgt_eval), - "test": _construct_filepaths(file_archives, src_test, tgt_test) - } - - for key in data_filenames.keys(): - if len(data_filenames[key]) == 0 or data_filenames[key] is None: - raise FileNotFoundError( - "Files are not found for data type {}".format(key)) - - datasets = [] - for key in split: - src_data_iter = _read_text_iterator(data_filenames[key][0]) - tgt_data_iter = _read_text_iterator(data_filenames[key][1]) - - def _iter(src_data_iter, tgt_data_iter): - for item in zip(src_data_iter, tgt_data_iter): - yield item - - datasets.append( - RawTextIterableDataset("IWSLT", NUM_LINES[key], _iter(src_data_iter, tgt_data_iter), offset=offset)) - - return datasets diff --git a/torchtext/experimental/datasets/raw/language_modeling.py b/torchtext/experimental/datasets/raw/language_modeling.py deleted file mode 100644 index c9bf90f216..0000000000 --- a/torchtext/experimental/datasets/raw/language_modeling.py +++ /dev/null @@ -1,176 +0,0 @@ -import logging -import io -from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import check_default_set - -URLS = { - 'WikiText2': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip', - 'WikiText103': - 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip', - 'PennTreebank': - ['https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt', - 'https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt'], - 'WMTNewsCrawl': 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' -} - - -def _setup_datasets(dataset_name, root, split, year, language, offset): - split = check_default_set(split, ('train', 'test', 'valid')) - if isinstance(split, str): - split = [split] - if not set(split).issubset(set(('train', 'test', 'valid'))): - raise TypeError('split is not supported!') - - if dataset_name == 'PennTreebank': - extracted_files = [] - select_to_index = {'train': 0, 'test': 1, 'valid': 2} - extracted_files = [download_from_url(URLS['PennTreebank'][select_to_index[key]], - root=root, hash_value=MD5['PennTreebank'][key], - hash_type='md5') for key in split] - elif dataset_name == 'WMTNewsCrawl': - if not (split == ['train'] or set(split).issubset(set(('train',)))): - raise ValueError("WMTNewsCrawl only creates a training dataset. " - "split should be 'train' " - "or ('train',), got {}.".format(split)) - dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5['WMTNewsCrawl'], hash_type='md5') - extracted_files = extract_archive(dataset_tar) - file_name = 'news.{}.{}.shuffled'.format(year, language) - extracted_files = [f for f in extracted_files if file_name in f] - else: - dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5[dataset_name], hash_type='md5') - extracted_files = extract_archive(dataset_tar) - - _path = {} - for item in split: - for fname in extracted_files: - if item in fname: - _path[item] = fname - - data = {} - for item in _path.keys(): - logging.info('Creating {} data'.format(item)) - data[item] = iter(io.open(_path[item], encoding="utf8")) - - return tuple(RawTextIterableDataset(dataset_name, - NUM_LINES[dataset_name][item], data[item], offset=offset) for item in split) - - -def WikiText2(root='.data', split=('train', 'valid', 'test'), offset=0): - """ Defines WikiText2 datasets. - - Create language modeling dataset: WikiText2 - Separately returns the train/test/valid set - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'valid, 'test') - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - offset: the number of the starting line. Default: 0 - - Examples: - >>> from torchtext.experimental.raw.datasets import WikiText2 - >>> train_dataset, valid_dataset, test_dataset = WikiText2() - >>> valid_dataset, = WikiText2(split='valid') - - """ - - return _setup_datasets("WikiText2", root, split, None, None, offset) - - -def WikiText103(root='.data', split=('train', 'valid', 'test'), offset=0): - """ Defines WikiText103 datasets. - - Create language modeling dataset: WikiText103 - Separately returns the train/test/valid set - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: the returned datasets. Default: ('train', 'valid','test') - By default, all the three datasets (train, test, valid) are generated. Users - could also choose any one or two of them, for example ('train', 'test'). - If 'train' is not in the tuple, an vocab object should be provided which will - be used to process valid and/or test data. - offset: the number of the starting line. Default: 0 - - Examples: - >>> from torchtext.experimental.datasets.raw import WikiText103 - >>> train_dataset, valid_dataset, test_dataset = WikiText103() - >>> valid_dataset, = WikiText103(split='valid') - """ - - return _setup_datasets("WikiText103", root, split, None, None, offset) - - -def PennTreebank(root='.data', split=('train', 'valid', 'test'), offset=0): - """ Defines PennTreebank datasets. - - Create language modeling dataset: PennTreebank - Separately returns the train/test/valid set - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets - (Default: ('train', 'test','valid')) - By default, all the three datasets ('train', 'valid', 'test') are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test - data. - offset: the number of the starting line. Default: 0 - - Examples: - >>> from torchtext.experimental.datasets.raw import PennTreebank - >>> train_dataset, valid_dataset, test_dataset = PennTreebank() - >>> valid_dataset, = PennTreebank(split='valid') - - """ - - return _setup_datasets("PennTreebank", root, split, None, None, offset) - - -def WMTNewsCrawl(root='.data', split=('train'), year=2010, language='en', offset=0): - """ Defines WMT News Crawl. - - Create language modeling dataset: WMTNewsCrawl - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. - (Default: 'train') - year: the year of the dataset (Default: 2010) - language: the language of the dataset (Default: 'en') - offset: the number of the starting line. Default: 0 - - Note: WMTNewsCrawl provides datasets based on the year and language instead of train/valid/test. - """ - - return _setup_datasets("WMTNewsCrawl", root, split, year, language, offset) - - -DATASETS = { - 'WikiText2': WikiText2, - 'WikiText103': WikiText103, - 'PennTreebank': PennTreebank, - 'WMTNewsCrawl': WMTNewsCrawl -} -NUM_LINES = { - 'WikiText2': {'train': 36718, 'valid': 3760, 'test': 4358}, - 'WikiText103': {'train': 1801350, 'valid': 3760, 'test': 4358}, - 'PennTreebank': {'train': 42068, 'valid': 3370, 'test': 3761}, - 'WMTNewsCrawl': {'train': 17676013} -} -MD5 = { - 'WikiText2': '542ccefacc6c27f945fb54453812b3cd', - 'WikiText103': '9ddaacaf6af0710eda8c456decff7832', - 'PennTreebank': {'train': 'f26c4b92c5fdc7b3f8c7cdcb991d8420', - 'valid': 'aa0affc06ff7c36e977d7cd49e3839bf', - 'test': '8b80168b89c18661a38ef683c0dc3721'}, - 'WMTNewsCrawl': '64150a352f3abe890a87f6c6838524a6' -} diff --git a/torchtext/experimental/datasets/raw/penntreebank.py b/torchtext/experimental/datasets/raw/penntreebank.py deleted file mode 100644 index f2b50dc7af..0000000000 --- a/torchtext/experimental/datasets/raw/penntreebank.py +++ /dev/null @@ -1,43 +0,0 @@ -import logging -from torchtext.utils import download_from_url -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import io - -URL = { - 'train': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", - 'test': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", - 'valid': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt", -} - -MD5 = { - 'train': "f26c4b92c5fdc7b3f8c7cdcb991d8420", - 'valid': "aa0affc06ff7c36e977d7cd49e3839bf", - 'test': "8b80168b89c18661a38ef683c0dc3721", -} - -NUM_LINES = { - 'train': 42068, - 'valid': 3370, - 'test': 3761, -} - - -@wrap_split_argument -@add_docstring_header() -def PennTreebank(root='.data', split=('train', 'valid', 'test'), offset=0): - extracted_files = [download_from_url(URL[key], - root=root, hash_value=MD5[key], - hash_type='md5') for key in split] - datasets = [] - for item in split: - path = find_match(item, extracted_files) - logging.info('Creating {} data'.format(item)) - datasets.append(RawTextIterableDataset('PennTreebank', - NUM_LINES[item], - iter(io.open(path, encoding="utf8")), - offset=offset)) - - return datasets diff --git a/torchtext/experimental/datasets/raw/question_answer.py b/torchtext/experimental/datasets/raw/question_answer.py deleted file mode 100644 index 937e58af24..0000000000 --- a/torchtext/experimental/datasets/raw/question_answer.py +++ /dev/null @@ -1,101 +0,0 @@ -from torchtext.utils import download_from_url -import json -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import check_default_set - -URLS = { - 'SQuAD1': - {'train': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json', - 'dev': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json'}, - 'SQuAD2': - {'train': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json', - 'dev': 'https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json'} -} - - -def _create_data_from_json(data_path): - with open(data_path) as json_file: - raw_json_data = json.load(json_file)['data'] - for layer1 in raw_json_data: - for layer2 in layer1['paragraphs']: - for layer3 in layer2['qas']: - _context, _question = layer2['context'], layer3['question'] - _answers = [item['text'] for item in layer3['answers']] - _answer_start = [item['answer_start'] for item in layer3['answers']] - if len(_answers) == 0: - _answers = [""] - _answer_start = [-1] - # yield the raw data in the order of context, question, answers, answer_start - yield (_context, _question, _answers, _answer_start) - - -def _setup_datasets(dataset_name, root, split, offset): - split = check_default_set(split, ('train', 'dev')) - extracted_files = {key: download_from_url(URLS[dataset_name][key], root=root, - hash_value=MD5[dataset_name][key], hash_type='md5') for key in split} - return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_json(extracted_files[item]), offset=offset) for item in split) - - -def SQuAD1(root='.data', split=('train', 'dev'), offset=0): - """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD1.0. - The iterator yields a tuple of (raw context, raw question, a list of raw answer, - a list of answer positions in the raw context). - For example, ('Architecturally, the school has a Catholic character. Atop the ...', - 'To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?', - ['Saint Bernadette Soubirous'], - [515]) - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets (Default: ('train', 'dev')) - By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, - for example ('train', 'dev') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train_dataset, dev_dataset = torchtext.experimental.datasets.raw.SQuAD1() - >>> for idx, (context, question, answer, ans_pos) in enumerate(train_dataset): - >>> print(idx, (context, question, answer, ans_pos)) - """ - - return _setup_datasets("SQuAD1", root, split, offset) - - -def SQuAD2(root='.data', split=('train', 'dev'), offset=0): - """ A dataset iterator yields the data of Stanford Question Answering dataset - SQuAD2.0. - The iterator yields a tuple of (raw context, raw question, a list of raw answer, - a list of answer positions in the raw context). - For example, ('Beyoncé Giselle Knowles-Carter (/biːˈjɒnseɪ/ bee-YON-say) (born September 4, 1981) is an ...', - 'When did Beyonce start becoming popular?', - ['in the late 1990s'], - [269]) - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets (Default: ('train', 'dev')) - By default, both datasets (train, dev) are generated. Users could also choose any one or two of them, - for example ('train', 'dev') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train_dataset, dev_dataset = torchtext.experimental.datasets.raw.SQuAD2() - >>> for idx, (context, question, answer, ans_pos) in enumerate(train_dataset): - >>> print(idx, (context, question, answer, ans_pos)) - """ - - return _setup_datasets("SQuAD2", root, split, offset) - - -DATASETS = { - 'SQuAD1': SQuAD1, - 'SQuAD2': SQuAD2 -} -NUM_LINES = { - 'SQuAD1': {'train': 87599, 'dev': 10570}, - 'SQuAD2': {'train': 130319, 'dev': 11873} -} -MD5 = { - 'SQuAD1': {'train': '981b29407e0affa3b1b156f72073b945', 'dev': '3e85deb501d4e538b6bc56f786231552'}, - 'SQuAD2': {'train': '62108c273c268d70893182d5cf8df740', 'dev': '246adae8b7002f8679c027697b0b7cf8'} -} diff --git a/torchtext/experimental/datasets/raw/sequence_tagging.py b/torchtext/experimental/datasets/raw/sequence_tagging.py deleted file mode 100644 index 2c59946d69..0000000000 --- a/torchtext/experimental/datasets/raw/sequence_tagging.py +++ /dev/null @@ -1,117 +0,0 @@ -from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import check_default_set - -URLS = { - "UDPOS": - 'https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip', - "CoNLL2000Chunking": { - 'train': 'https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz', - 'test': 'https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz' - } -} - - -def _create_data_from_iob(data_path, separator="\t"): - with open(data_path, encoding="utf-8") as input_file: - columns = [] - for line in input_file: - line = line.strip() - if line == "": - if columns: - yield columns - columns = [] - else: - for i, column in enumerate(line.split(separator)): - if len(columns) < i + 1: - columns.append([]) - columns[i].append(column) - if len(columns) > 0: - yield columns - - -def _construct_filepath(paths, file_suffix): - if file_suffix: - path = None - for p in paths: - path = p if p.endswith(file_suffix) else path - return path - return None - - -def _setup_datasets(dataset_name, separator, root, split, offset): - split = check_default_set(split, target_select=('train', 'valid', 'test')) - extracted_files = [] - if isinstance(URLS[dataset_name], dict): - for name, item in URLS[dataset_name].items(): - dataset_tar = download_from_url(item, root=root, hash_value=MD5[dataset_name][name], hash_type='md5') - extracted_files.extend(extract_archive(dataset_tar)) - elif isinstance(URLS[dataset_name], str): - dataset_tar = download_from_url(URLS[dataset_name], root=root, hash_value=MD5[dataset_name], hash_type='md5') - extracted_files.extend(extract_archive(dataset_tar)) - else: - raise ValueError( - "URLS for {} has to be in a form of dictionary or string".format( - dataset_name)) - - data_filenames = { - "train": _construct_filepath(extracted_files, "train.txt"), - "valid": _construct_filepath(extracted_files, "dev.txt"), - "test": _construct_filepath(extracted_files, "test.txt") - } - return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_iob(data_filenames[item], separator), offset=offset) - if data_filenames[item] is not None else None for item in split) - - -def UDPOS(root=".data", split=('train', 'valid', 'test'), offset=0): - """ Universal Dependencies English Web Treebank - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets (Default: ('train', 'valid', 'test')) - By default, all the datasets (train, valid, test) are generated. - Users could also choose any one or two of them, - for example ('train', 'valid', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> from torchtext.experimental.datasets.raw import UDPOS - >>> train_dataset, valid_dataset, test_dataset = UDPOS() - """ - return _setup_datasets("UDPOS", "\t", root, split, offset) - - -def CoNLL2000Chunking(root=".data", split=('train', 'test'), offset=0): - """ CoNLL 2000 Chunking Dataset - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets (Default: ('train', 'test')) - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> from torchtext.experimental.datasets.raw import CoNLL2000Chunking - >>> train_dataset, test_dataset = CoNLL2000Chunking() - """ - return _setup_datasets("CoNLL2000Chunking", " ", root, split, offset) - - -DATASETS = { - "UDPOS": UDPOS, - "CoNLL2000Chunking": CoNLL2000Chunking -} -NUM_LINES = { - "UDPOS": {'train': 12543, 'valid': 2002, 'test': 2077}, - "CoNLL2000Chunking": {'train': 8936, 'test': 2012} -} -MD5 = { - "UDPOS": 'bdcac7c52d934656bae1699541424545', - "CoNLL2000Chunking": {'train': '6969c2903a1f19a83569db643e43dcc8', 'test': 'a916e1c2d83eb3004b38fc6fcd628939'} -} diff --git a/torchtext/experimental/datasets/raw/sogounews.py b/torchtext/experimental/datasets/raw/sogounews.py deleted file mode 100644 index 51565443aa..0000000000 --- a/torchtext/experimental/datasets/raw/sogounews.py +++ /dev/null @@ -1,39 +0,0 @@ -from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import os -import io - -URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE' - -MD5 = '0c1700ba70b73f964dd8de569d3fd03e' - -NUM_LINES = { - 'train': 450000, - 'test': 60000, -} - -_PATH = 'sogou_news_csv.tar.gz' - - -@wrap_split_argument -@add_docstring_header() -def SogouNews(root='.data', split=('train', 'test'), offset=0): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - dataset_tar = download_from_url(URL, root=root, - path=os.path.join(root, _PATH), - hash_value=MD5, hash_type='md5') - extracted_files = extract_archive(dataset_tar) - - datasets = [] - for item in split: - path = find_match(item + '.csv', extracted_files) - datasets.append(RawTextIterableDataset("SogouNews", NUM_LINES[item], - _create_data_from_csv(path), offset=offset)) - return datasets diff --git a/torchtext/experimental/datasets/raw/text_classification.py b/torchtext/experimental/datasets/raw/text_classification.py deleted file mode 100644 index a4fa4dfa19..0000000000 --- a/torchtext/experimental/datasets/raw/text_classification.py +++ /dev/null @@ -1,293 +0,0 @@ -import io -from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import check_default_set - -URLS = { - 'AG_NEWS': - {'train': 'https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv', - 'test': 'https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv'}, - 'SogouNews': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE', - 'DBpedia': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k', - 'YelpReviewPolarity': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg', - 'YelpReviewFull': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0', - 'YahooAnswers': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU', - 'AmazonReviewPolarity': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM', - 'AmazonReviewFull': - 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA', - 'IMDB': - 'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz' -} - - -def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - - -def _setup_datasets(dataset_name, root, split, offset): - split = check_default_set(split, target_select=('train', 'test')) - if dataset_name == 'AG_NEWS': - extracted_files = [download_from_url(URLS[dataset_name][item], root=root, - hash_value=MD5['AG_NEWS'][item], - hash_type='md5') for item in ('train', 'test')] - else: - dataset_tar = download_from_url(URLS[dataset_name], root=root, - hash_value=MD5[dataset_name], hash_type='md5') - extracted_files = extract_archive(dataset_tar) - - cvs_path = {} - for fname in extracted_files: - if fname.endswith('train.csv'): - cvs_path['train'] = fname - if fname.endswith('test.csv'): - cvs_path['test'] = fname - return tuple(RawTextIterableDataset(dataset_name, NUM_LINES[dataset_name][item], - _create_data_from_csv(cvs_path[item]), offset=offset) for item in split) - - -def AG_NEWS(root='.data', split=('train', 'test'), offset=0): - """ Defines AG_NEWS datasets. - - Create supervised learning dataset: AG_NEWS - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.AG_NEWS() - """ - - return _setup_datasets("AG_NEWS", root, split, offset) - - -def SogouNews(root='.data', split=('train', 'test'), offset=0): - """ Defines SogouNews datasets. - - Create supervised learning dataset: SogouNews - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.SogouNews() - """ - - return _setup_datasets("SogouNews", root, split, offset) - - -def DBpedia(root='.data', split=('train', 'test'), offset=0): - """ Defines DBpedia datasets. - - Create supervised learning dataset: DBpedia - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.DBpedia() - """ - - return _setup_datasets("DBpedia", root, split, offset) - - -def YelpReviewPolarity(root='.data', split=('train', 'test'), offset=0): - """ Defines YelpReviewPolarity datasets. - - Create supervised learning dataset: YelpReviewPolarity - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.YelpReviewPolarity() - """ - - return _setup_datasets("YelpReviewPolarity", root, split, offset) - - -def YelpReviewFull(root='.data', split=('train', 'test'), offset=0): - """ Defines YelpReviewFull datasets. - - Create supervised learning dataset: YelpReviewFull - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.YelpReviewFull() - """ - - return _setup_datasets("YelpReviewFull", root, split, offset) - - -def YahooAnswers(root='.data', split=('train', 'test'), offset=0): - """ Defines YahooAnswers datasets. - - Create supervised learning dataset: YahooAnswers - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.YahooAnswers() - """ - - return _setup_datasets("YahooAnswers", root, split, offset) - - -def AmazonReviewPolarity(root='.data', split=('train', 'test'), offset=0): - """ Defines AmazonReviewPolarity datasets. - - Create supervised learning dataset: AmazonReviewPolarity - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewPolarity() - """ - - return _setup_datasets("AmazonReviewPolarity", root, split, offset) - - -def AmazonReviewFull(root='.data', split=('train', 'test'), offset=0): - """ Defines AmazonReviewFull datasets. - - Create supervised learning dataset: AmazonReviewFull - - Separately returns the training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.AmazonReviewFull() - """ - - return _setup_datasets("AmazonReviewFull", root, split, offset) - - -def generate_imdb_data(key, extracted_files): - for fname in extracted_files: - if 'urls' in fname: - continue - elif key in fname and ('pos' in fname or 'neg' in fname): - with io.open(fname, encoding="utf8") as f: - label = 'pos' if 'pos' in fname else 'neg' - yield label, f.read() - - -def IMDB(root='.data', split=('train', 'test'), offset=0): - """ Defines raw IMDB datasets. - - Create supervised learning dataset: IMDB - - Separately returns the raw training and test dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: a string or tuple for the returned datasets. Default: ('train', 'test') - By default, both datasets (train, test) are generated. Users could also choose any one or two of them, - for example ('train', 'test') or just a string 'train'. - offset: the number of the starting line. Default: 0 - - Examples: - >>> train, test = torchtext.experimental.datasets.raw.IMDB() - """ - split = check_default_set(split, target_select=('train', 'test')) - dataset_tar = download_from_url(URLS['IMDB'], root=root, - hash_value=MD5['IMDB'], hash_type='md5') - extracted_files = extract_archive(dataset_tar) - return tuple(RawTextIterableDataset("IMDB", NUM_LINES["IMDB"][item], - generate_imdb_data(item, - extracted_files), offset=offset) for item in split) - - -DATASETS = { - 'AG_NEWS': AG_NEWS, - 'SogouNews': SogouNews, - 'DBpedia': DBpedia, - 'YelpReviewPolarity': YelpReviewPolarity, - 'YelpReviewFull': YelpReviewFull, - 'YahooAnswers': YahooAnswers, - 'AmazonReviewPolarity': AmazonReviewPolarity, - 'AmazonReviewFull': AmazonReviewFull, - 'IMDB': IMDB -} -NUM_LINES = { - 'AG_NEWS': {'train': 120000, 'test': 7600}, - 'SogouNews': {'train': 450000, 'test': 60000}, - 'DBpedia': {'train': 560000, 'test': 70000}, - 'YelpReviewPolarity': {'train': 560000, 'test': 38000}, - 'YelpReviewFull': {'train': 650000, 'test': 50000}, - 'YahooAnswers': {'train': 1400000, 'test': 60000}, - 'AmazonReviewPolarity': {'train': 3600000, 'test': 400000}, - 'AmazonReviewFull': {'train': 3000000, 'test': 650000}, - 'IMDB': {'train': 25000, 'test': 25000} -} -MD5 = { - 'AG_NEWS': {'train': 'b1a00f826fdfbd249f79597b59e1dc12', 'test': 'd52ea96a97a2d943681189a97654912d'}, - 'SogouNews': '0c1700ba70b73f964dd8de569d3fd03e', - 'DBpedia': 'dca7b1ae12b1091090db52aa7ec5ca64', - 'YelpReviewPolarity': '620c8ae4bd5a150b730f1ba9a7c6a4d3', - 'YelpReviewFull': 'f7ddfafed1033f68ec72b9267863af6c', - 'YahooAnswers': 'f3f9899b997a42beb24157e62e3eea8d', - 'AmazonReviewPolarity': 'fe39f8b653cada45afd5792e0f0e8f9b', - 'AmazonReviewFull': '57d28bd5d930e772930baddf36641c7c', - 'IMDB': '7c2ac02c03563afcf9b574c7e56c153a' -} diff --git a/torchtext/experimental/datasets/raw/translation.py b/torchtext/experimental/datasets/raw/translation.py deleted file mode 100644 index 9cc10706c3..0000000000 --- a/torchtext/experimental/datasets/raw/translation.py +++ /dev/null @@ -1,583 +0,0 @@ -import os -import io -import codecs -import xml.etree.ElementTree as ET -from collections import defaultdict -from torchtext.utils import (download_from_url, extract_archive) -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import check_default_set - -URLS = { - 'Multi30k': [ - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", - "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz" - ], - 'WMT14': - 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8', - 'IWSLT': - 'https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8' -} - - -def _read_text_iterator(path): - with io.open(path, encoding="utf8") as f: - for row in f: - yield row - - -def _clean_xml_file(f_xml): - f_txt = os.path.splitext(f_xml)[0] - with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: - root = ET.parse(f_xml).getroot()[0] - for doc in root.findall('doc'): - for e in doc.findall('seg'): - fd_txt.write(e.text.strip() + '\n') - - -def _clean_tags_file(f_orig): - xml_tags = [ - '>> from torchtext.experimental.datasets.raw import Multi30k - >>> train_dataset, valid_dataset, test_dataset = Multi30k() - """ - return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, split, root, offset) - - -def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), - valid_filenames=('IWSLT16.TED.tst2013.de-en.de', - 'IWSLT16.TED.tst2013.de-en.en'), - test_filenames=('IWSLT16.TED.tst2014.de-en.de', - 'IWSLT16.TED.tst2014.de-en.en'), - split=('train', 'valid', 'test'), root='.data', offset=0): - """ Define translation datasets: IWSLT - Separately returns train/valid/test datasets - The available datasets include: - IWSLT16.TED.dev2010.ar-en.ar - IWSLT16.TED.dev2010.ar-en.en - IWSLT16.TED.dev2010.cs-en.cs - IWSLT16.TED.dev2010.cs-en.en - IWSLT16.TED.dev2010.de-en.de - IWSLT16.TED.dev2010.de-en.en - IWSLT16.TED.dev2010.en-ar.ar - IWSLT16.TED.dev2010.en-ar.en - IWSLT16.TED.dev2010.en-cs.cs - IWSLT16.TED.dev2010.en-cs.en - IWSLT16.TED.dev2010.en-de.de - IWSLT16.TED.dev2010.en-de.en - IWSLT16.TED.dev2010.en-fr.en - IWSLT16.TED.dev2010.en-fr.fr - IWSLT16.TED.dev2010.fr-en.en - IWSLT16.TED.dev2010.fr-en.fr - IWSLT16.TED.tst2010.ar-en.ar - IWSLT16.TED.tst2010.ar-en.en - IWSLT16.TED.tst2010.cs-en.cs - IWSLT16.TED.tst2010.cs-en.en - IWSLT16.TED.tst2010.de-en.de - IWSLT16.TED.tst2010.de-en.en - IWSLT16.TED.tst2010.en-ar.ar - IWSLT16.TED.tst2010.en-ar.en - IWSLT16.TED.tst2010.en-cs.cs - IWSLT16.TED.tst2010.en-cs.en - IWSLT16.TED.tst2010.en-de.de - IWSLT16.TED.tst2010.en-de.en - IWSLT16.TED.tst2010.en-fr.en - IWSLT16.TED.tst2010.en-fr.fr - IWSLT16.TED.tst2010.fr-en.en - IWSLT16.TED.tst2010.fr-en.fr - IWSLT16.TED.tst2011.ar-en.ar - IWSLT16.TED.tst2011.ar-en.en - IWSLT16.TED.tst2011.cs-en.cs - IWSLT16.TED.tst2011.cs-en.en - IWSLT16.TED.tst2011.de-en.de - IWSLT16.TED.tst2011.de-en.en - IWSLT16.TED.tst2011.en-ar.ar - IWSLT16.TED.tst2011.en-ar.en - IWSLT16.TED.tst2011.en-cs.cs - IWSLT16.TED.tst2011.en-cs.en - IWSLT16.TED.tst2011.en-de.de - IWSLT16.TED.tst2011.en-de.en - IWSLT16.TED.tst2011.en-fr.en - IWSLT16.TED.tst2011.en-fr.fr - IWSLT16.TED.tst2011.fr-en.en - IWSLT16.TED.tst2011.fr-en.fr - IWSLT16.TED.tst2012.ar-en.ar - IWSLT16.TED.tst2012.ar-en.en - IWSLT16.TED.tst2012.cs-en.cs - IWSLT16.TED.tst2012.cs-en.en - IWSLT16.TED.tst2012.de-en.de - IWSLT16.TED.tst2012.de-en.en - IWSLT16.TED.tst2012.en-ar.ar - IWSLT16.TED.tst2012.en-ar.en - IWSLT16.TED.tst2012.en-cs.cs - IWSLT16.TED.tst2012.en-cs.en - IWSLT16.TED.tst2012.en-de.de - IWSLT16.TED.tst2012.en-de.en - IWSLT16.TED.tst2012.en-fr.en - IWSLT16.TED.tst2012.en-fr.fr - IWSLT16.TED.tst2012.fr-en.en - IWSLT16.TED.tst2012.fr-en.fr - IWSLT16.TED.tst2013.ar-en.ar - IWSLT16.TED.tst2013.ar-en.en - IWSLT16.TED.tst2013.cs-en.cs - IWSLT16.TED.tst2013.cs-en.en - IWSLT16.TED.tst2013.de-en.de - IWSLT16.TED.tst2013.de-en.en - IWSLT16.TED.tst2013.en-ar.ar - IWSLT16.TED.tst2013.en-ar.en - IWSLT16.TED.tst2013.en-cs.cs - IWSLT16.TED.tst2013.en-cs.en - IWSLT16.TED.tst2013.en-de.de - IWSLT16.TED.tst2013.en-de.en - IWSLT16.TED.tst2013.en-fr.en - IWSLT16.TED.tst2013.en-fr.fr - IWSLT16.TED.tst2013.fr-en.en - IWSLT16.TED.tst2013.fr-en.fr - IWSLT16.TED.tst2014.ar-en.ar - IWSLT16.TED.tst2014.ar-en.en - IWSLT16.TED.tst2014.de-en.de - IWSLT16.TED.tst2014.de-en.en - IWSLT16.TED.tst2014.en-ar.ar - IWSLT16.TED.tst2014.en-ar.en - IWSLT16.TED.tst2014.en-de.de - IWSLT16.TED.tst2014.en-de.en - IWSLT16.TED.tst2014.en-fr.en - IWSLT16.TED.tst2014.en-fr.fr - IWSLT16.TED.tst2014.fr-en.en - IWSLT16.TED.tst2014.fr-en.fr - IWSLT16.TEDX.dev2012.de-en.de - IWSLT16.TEDX.dev2012.de-en.en - IWSLT16.TEDX.tst2013.de-en.de - IWSLT16.TEDX.tst2013.de-en.en - IWSLT16.TEDX.tst2014.de-en.de - IWSLT16.TEDX.tst2014.de-en.en - train.ar - train.ar-en.ar - train.ar-en.en - train.cs - train.cs-en.cs - train.cs-en.en - train.de - train.de-en.de - train.de-en.en - train.en - train.en-ar.ar - train.en-ar.en - train.en-cs.cs - train.en-cs.en - train.en-de.de - train.en-de.en - train.en-fr.en - train.en-fr.fr - train.fr - train.fr-en.en - train.fr-en.fr - train.tags.ar-en.ar - train.tags.ar-en.en - train.tags.cs-en.cs - train.tags.cs-en.en - train.tags.de-en.de - train.tags.de-en.en - train.tags.en-ar.ar - train.tags.en-ar.en - train.tags.en-cs.cs - train.tags.en-cs.en - train.tags.en-de.de - train.tags.en-de.en - train.tags.en-fr.en - train.tags.en-fr.fr - train.tags.fr-en.en - train.tags.fr-en.fr - - Args: - train_filenames: the source and target filenames for training. - Default: ('train.de-en.de', 'train.de-en.en') - valid_filenames: the source and target filenames for valid. - Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') - test_filenames: the source and target filenames for test. - Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') - split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') - By default, all the three datasets (train, valid, test) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test data. - root: Directory where the datasets are saved. Default: ".data" - offset: the number of the starting line. Default: 0 - - Examples: - >>> from torchtext.experimental.datasets.raw import IWSLT - >>> train_dataset, valid_dataset, test_dataset = IWSLT() - """ - return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, split, root, offset) - - -def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', - 'train.tok.clean.bpe.32000.en'), - valid_filenames=('newstest2013.tok.bpe.32000.de', - 'newstest2013.tok.bpe.32000.en'), - test_filenames=('newstest2014.tok.bpe.32000.de', - 'newstest2014.tok.bpe.32000.en'), - split=('train', 'valid', 'test'), root='.data', offset=0): - """ Define translation datasets: WMT14 - Separately returns train/valid/test datasets - The available datasets include: - newstest2016.en - newstest2016.de - newstest2015.en - newstest2015.de - newstest2014.en - newstest2014.de - newstest2013.en - newstest2013.de - newstest2012.en - newstest2012.de - newstest2011.tok.de - newstest2011.en - newstest2011.de - newstest2010.tok.de - newstest2010.en - newstest2010.de - newstest2009.tok.de - newstest2009.en - newstest2009.de - newstest2016.tok.de - newstest2015.tok.de - newstest2014.tok.de - newstest2013.tok.de - newstest2012.tok.de - newstest2010.tok.en - newstest2009.tok.en - newstest2015.tok.en - newstest2014.tok.en - newstest2013.tok.en - newstest2012.tok.en - newstest2011.tok.en - newstest2016.tok.en - newstest2009.tok.bpe.32000.en - newstest2011.tok.bpe.32000.en - newstest2010.tok.bpe.32000.en - newstest2013.tok.bpe.32000.en - newstest2012.tok.bpe.32000.en - newstest2015.tok.bpe.32000.en - newstest2014.tok.bpe.32000.en - newstest2016.tok.bpe.32000.en - train.tok.clean.bpe.32000.en - newstest2009.tok.bpe.32000.de - newstest2010.tok.bpe.32000.de - newstest2011.tok.bpe.32000.de - newstest2013.tok.bpe.32000.de - newstest2012.tok.bpe.32000.de - newstest2014.tok.bpe.32000.de - newstest2016.tok.bpe.32000.de - newstest2015.tok.bpe.32000.de - train.tok.clean.bpe.32000.de - - Args: - train_filenames: the source and target filenames for training. - Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') - valid_filenames: the source and target filenames for valid. - Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') - test_filenames: the source and target filenames for test. - Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') - split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') - By default, all the three datasets (train, valid, test) are generated. Users - could also choose any one or two of them, for example ('train', 'test') or - just a string 'train'. If 'train' is not in the tuple or string, a vocab - object should be provided which will be used to process valid and/or test data. - root: Directory where the datasets are saved. Default: ".data" - offset: the number of the starting line. Default: 0 - - Examples: - >>> from torchtext.experimental.datasets.raw import WMT14 - >>> train_dataset, valid_dataset, test_dataset = WMT14() - """ - return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, split, root, offset) - - -DATASETS = { - 'Multi30k': Multi30k, - 'IWSLT': IWSLT, - 'WMT14': WMT14 -} -NUM_LINES = { - 'Multi30k': {'train': 29000, 'valid': 1014, 'test': 1000}, - 'IWSLT': {'train': 196884, 'valid': 993, 'test': 1305}, - 'WMT14': {'train': 4500966, 'valid': 3000, 'test': 3003} -} -MD5 = { - 'Multi30k': ['3104872229daa1bef3b401d44dd2220b', - 'efd67d314d98489b716b145475101932', - 'ff2c0fcb4893a13bd73414306bc250ae', - '08dc7cd4a662f31718412de95ca9bfe3', - '6a8d5c87f6ae19e3d35681aa6fd16571', - '005396bac545d880abe6f00bbb7dbbb4', - 'cb09af7d2b501f9112f2d6a59fa1360d', - 'e8cd6ec2bc8a11fc846fa48a46e3d0bb', - 'a7b684e0edbef1d4a23660c8e8e743fd', - '4995d10954a804d3cdfd907b9fd093e8', - 'a152878809942757a55ce087073486b8', - 'd9a5fc268917725a2b0efce3a0cc8607', - '81ff90b99829c0cd4b1b587d394afd39', - '0065d13af80720a55ca8153d126e6627', - '6cb767741dcad3931f966fefbc05203f', - '83cdc082f646b769095615384cf5c0ca', - '6e0e229eb049e3fc99a1ef02fb2d5f91', - '2b69aa9253948ac9f67e94917272dd40', - '93fc564584b7e5ba410c761ea5a1c682', - 'ac0c72653c140dd96707212a1baa4278', - 'eec05227daba4bb8f3f8f25b1cb335f4', - '6dfb42cae4e4fd9a3c40e62ff5398a55', - '9318fa08c0c0b96114eadb10eb2fc633', - 'ece8cec6b87bf00dd12607f3062dae4c', - '088ec0765fa213a0eb937a62adfd4996', - '9a7e7b2dcc33135a32cd621c3b37d2d8', - '5f7c8d0be0ac739856b47d32a9434998', - '7d5ef0f069ee2d74dc2fdc6b46cd47fa', - '713ed720636622a54546d5f14f88b00f', - '62f36422bfab90fb42a560546b704009', - 'cbf5bfc2147706f228d288e1b18bf4af', - '540da4566bb6dd35fdbc720218b742b7', - 'bdfe4222f4692ccaa1e3389460f0890e', - '613eb4a3f0c2b13f0871ced946851b0e', - '0e1ee2b4145795bd180b193424db204b', - 'd848fe0ae8b9447209fb49c5c31cb3d2', - '1cff688d1aadef7fdb22e9ad27d6fd2c', - 'abc13b4042f4fef1cdff6de3b6c53b71', - '3e10289959d0059952511c31df3c7550', - 'b26486ede1d4436d5acf6e38c65bb44d', - 'df57faf5f00d434d2559c021ef55f1aa', - '16165248083beacebfe18866d5f4f0ae', - '9077a5127480cc799116384de501bd70', - '7180780822d4b600eb81c1ccf171c230', - 'c1f697c3b6dfb7305349db34e26b45fc', - '8edb43c90cae66ec762748a968089b99', - 'acb5ea26a577ceccfae6337181c31716', - '873a377a348713d3ab84db1fb57cdede', - '680816e0938fea5cf5331444bc09a4cf'], - 'IWSLT': 'c393ed3fc2a1b0f004b3331043f615ae', - 'WMT14': '874ab6bbfe9c21ec987ed1b9347f95ec' -} diff --git a/torchtext/experimental/datasets/raw/udpos.py b/torchtext/experimental/datasets/raw/udpos.py deleted file mode 100644 index a7e3a8e0ea..0000000000 --- a/torchtext/experimental/datasets/raw/udpos.py +++ /dev/null @@ -1,57 +0,0 @@ -from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header - -URL = 'https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip' - -MD5 = 'bdcac7c52d934656bae1699541424545' - -NUM_LINES = { - 'train': 12543, - 'valid': 2002, - 'test': 2077, -} - - -def _create_data_from_iob(data_path, separator="\t"): - with open(data_path, encoding="utf-8") as input_file: - columns = [] - for line in input_file: - line = line.strip() - if line == "": - if columns: - yield columns - columns = [] - else: - for i, column in enumerate(line.split(separator)): - if len(columns) < i + 1: - columns.append([]) - columns[i].append(column) - if len(columns) > 0: - yield columns - - -def _construct_filepath(paths, file_suffix): - if file_suffix: - path = None - for p in paths: - path = p if p.endswith(file_suffix) else path - return path - return None - - -@wrap_split_argument -@add_docstring_header() -def UDPOS(root='.data', split=('train', 'valid', 'test'), offset=0): - dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') - extracted_files = extract_archive(dataset_tar) - - data_filenames = { - "train": _construct_filepath(extracted_files, "train.txt"), - "valid": _construct_filepath(extracted_files, "dev.txt"), - "test": _construct_filepath(extracted_files, "test.txt") - } - return [RawTextIterableDataset("UDPOS", NUM_LINES[item], - _create_data_from_iob(data_filenames[item]), offset=offset) - if data_filenames[item] is not None else None for item in split] diff --git a/torchtext/experimental/datasets/raw/wikitext103.py b/torchtext/experimental/datasets/raw/wikitext103.py deleted file mode 100644 index ea75f1efe6..0000000000 --- a/torchtext/experimental/datasets/raw/wikitext103.py +++ /dev/null @@ -1,31 +0,0 @@ -import logging -from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import io - -URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip' - -MD5 = '9ddaacaf6af0710eda8c456decff7832' - -NUM_LINES = { - 'train': 1801350, - 'valid': 3760, - 'test': 4358, -} - - -@wrap_split_argument -@add_docstring_header() -def WikiText103(root='.data', split=('train', 'valid', 'test'), offset=0): - dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') - extracted_files = extract_archive(dataset_tar) - datasets = [] - for item in split: - path = find_match(item, extracted_files) - logging.info('Creating {} data'.format(item)) - datasets.append(RawTextIterableDataset('WikiText103', - NUM_LINES[item], iter(io.open(path, encoding="utf8")), offset=offset)) - return datasets diff --git a/torchtext/experimental/datasets/raw/wikitext2.py b/torchtext/experimental/datasets/raw/wikitext2.py deleted file mode 100644 index a6f9a02a9c..0000000000 --- a/torchtext/experimental/datasets/raw/wikitext2.py +++ /dev/null @@ -1,31 +0,0 @@ -import logging -from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import io - -URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip' - -MD5 = '542ccefacc6c27f945fb54453812b3cd' - -NUM_LINES = { - 'train': 36718, - 'valid': 3760, - 'test': 4358, -} - - -@wrap_split_argument -@add_docstring_header() -def WikiText2(root='.data', split=('train', 'valid', 'test'), offset=0): - dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') - extracted_files = extract_archive(dataset_tar) - datasets = [] - for item in split: - path = find_match(item, extracted_files) - logging.info('Creating {} data'.format(item)) - datasets.append(RawTextIterableDataset('WikiText2', - NUM_LINES[item], iter(io.open(path, encoding="utf8")), offset=offset)) - return datasets diff --git a/torchtext/experimental/datasets/raw/wmtnewscrawl.py b/torchtext/experimental/datasets/raw/wmtnewscrawl.py deleted file mode 100644 index 6c16c6dee3..0000000000 --- a/torchtext/experimental/datasets/raw/wmtnewscrawl.py +++ /dev/null @@ -1,32 +0,0 @@ -import logging -from torchtext.utils import download_from_url, extract_archive -from torchtext.experimental.datasets.raw.common import RawTextIterableDataset -from torchtext.experimental.datasets.raw.common import wrap_split_argument -from torchtext.experimental.datasets.raw.common import add_docstring_header -from torchtext.experimental.datasets.raw.common import find_match -import io - -URL = 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' - -MD5 = 'c70da2ba79db33fb0fc9119cbad16260' - -NUM_LINES = { - 'train': 17676013, -} - - -@wrap_split_argument -@add_docstring_header() -def WMTNewsCrawl(root='.data', split='train', offset=0): - dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') - extracted_files = extract_archive(dataset_tar) - file_name = 'news.{}.{}.shuffled'.format(year, language) - extracted_files = [f for f in extracted_files if file_name in f] - - datasets = [] - for item in split: - path = find_match(item, extracted_files) - logging.info('Creating {} data'.format(item)) - datasets.append(RawTextIterableDataset('WMTNewsCrawl', - NUM_LINES[item], iter(io.open(path, encoding="utf8")), offset=offset)) - return datasets diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index fe64e67bc4..06148dabd3 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -1,8 +1,8 @@ import torch import logging -from torchtext.experimental.datasets.raw.common import check_default_set -from torchtext.experimental.datasets.raw.common import wrap_datasets -from torchtext.experimental.datasets import raw +from torchtext.data.datasets_utils import check_default_set +from torchtext.data.datasets_utils import wrap_datasets +from torchtext import datasets as raw from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.functional import ( vocab_func, diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index 01a5e29557..d04833fd9b 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -2,9 +2,9 @@ import logging from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator -from torchtext.experimental.datasets import raw -from torchtext.experimental.datasets.raw.common import check_default_set -from torchtext.experimental.datasets.raw.common import wrap_datasets +from torchtext import datasets as raw +from torchtext.data.datasets_utils import check_default_set +from torchtext.data.datasets_utils import wrap_datasets from torchtext.experimental.functional import ( vocab_func, totensor, diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index ce7077be6c..859a6f352a 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -1,8 +1,8 @@ import torch import logging -from torchtext.experimental.datasets.raw.common import check_default_set -from torchtext.experimental.datasets.raw.common import wrap_datasets -from torchtext.experimental.datasets import raw +from torchtext.data.datasets_utils import check_default_set +from torchtext.data.datasets_utils import wrap_datasets +from torchtext import datasets as raw from torchtext.vocab import Vocab, build_vocab_from_iterator from torchtext.data.utils import get_tokenizer from ..functional import vocab_func, totensor, sequential_transforms @@ -18,8 +18,7 @@ def apply_transforms(data): def _setup_datasets(dataset_name, - train_filenames, valid_filenames, test_filenames, - split_, root, vocab, tokenizer): + split_, root, vocab, tokenizer, **kwargs): split = check_default_set(split_, ('train', 'valid', 'test'), dataset_name) src_vocab, tgt_vocab = vocab if tokenizer is None: @@ -35,10 +34,8 @@ def _setup_datasets(dataset_name, raise ValueError( "tokenizer must be an instance of tuple with length two" "or None") - raw_datasets = raw.DATASETS[dataset_name](train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames, - split=split, root=root) + + raw_datasets = raw.DATASETS[dataset_name](split=split, root=root, **kwargs) raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} src_text_vocab_transform = sequential_transforms(src_tokenizer) tgt_text_vocab_transform = sequential_transforms(tgt_tokenizer) @@ -90,7 +87,8 @@ class TranslationDataset(torch.utils.data.Dataset): - Multi30k - WMT14 - - IWSLT + - IWSLT2016 + - IWSLT2017 """ def __init__(self, data, vocab, transforms): @@ -226,31 +224,88 @@ def Multi30k(train_filenames=("train.de", "train.en"), >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] """ + return _setup_datasets("Multi30k", split, root, vocab, tokenizer, + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames) + + +def IWSLT2017(language_pair=('de', 'en'), + split=('train', 'valid', 'test'), + root='.data', + vocab=(None, None), + tokenizer=None): + """ Define translation datasets: IWSLT2017 + Separately returns train/valid/test datasets - return _setup_datasets("Multi30k", train_filenames, valid_filenames, test_filenames, - split, root, vocab, tokenizer) + The available datasets include following: + **Language pairs**: [('en', 'nl'), ('en', 'de'), ('en', 'it'), ('en', 'ro'), ('ro', 'de'), + ('ro', 'en'), ('ro', 'nl'), ('ro', 'it'), ('de', 'ro'), ('de', 'en'), + ('de', 'nl'), ('de', 'it'), ('it', 'en'), ('it', 'nl'), ('it', 'de'), + ('it', 'ro'), ('nl', 'de'), ('nl', 'en'), ('nl', 'it'), ('nl', 'ro')] -def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), - valid_filenames=('IWSLT16.TED.tst2013.de-en.de', - 'IWSLT16.TED.tst2013.de-en.en'), - test_filenames=('IWSLT16.TED.tst2014.de-en.de', - 'IWSLT16.TED.tst2014.de-en.en'), - split=('train', 'valid', 'test'), - root='.data', - vocab=(None, None), - tokenizer=None): - """ Define translation datasets: IWSLT + For additional details refer to source website: https://wit3.fbk.eu/2017-01 + + Args: + language_pair: tuple or list of two elements: src and tgt language + split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') + By default, all the three datasets (train, valid, test) are generated. Users + could also choose any one or two of them, for example ('train', 'test') or + just a string 'train'. If 'train' is not in the tuple or string, a vocab + object should be provided which will be used to process valid and/or test data. + root: Directory where the datasets are saved. Default: ".data" + vocab: Source and target Vocabulary objects used for dataset. If None, it + will generate a new vocabulary based on the train data set. It has to be + in a form of tuple. + Default: (None, None) + tokenizer: the tokenizer used to preprocess source and target raw text data. + It has to be in a form of tuple. + Default: (get_tokenizer("spacy", language='de_core_news_sm'), + get_tokenizer("spacy", language='en_core_web_sm')) + + Examples: + >>> from torchtext.experimental.datasets import IWSLT + >>> from torchtext.data.utils import get_tokenizer + >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> tgt_tokenizer = get_tokenizer("basic_english") + >>> train_dataset, valid_dataset, test_dataset = IWSLT(tokenizer=(src_tokenizer, + tgt_tokenizer)) + >>> src_vocab, tgt_vocab = train_dataset.get_vocab() + >>> src_data, tgt_data = train_dataset[10] + """ + + if not isinstance(language_pair, list) and not isinstance(language_pair, tuple): + raise ValueError("language_pair must be list or tuple") + + assert (len(language_pair) == 2), 'language_pair must contain only 2 elements' + + return _setup_datasets("IWSLT2017", split, root, vocab, tokenizer, language_pair=language_pair) + + +def IWSLT2016(language_pair=('de', 'en'), + valid_set='tst2013', + test_set='tst2014', + split=('train', 'valid', 'test'), + root='.data', + vocab=(None, None), + tokenizer=None): + """ Define translation datasets: IWSLT2016 Separately returns train/valid/test datasets - The available datasets include: + + The available datasets include following: + + **Language pairs**: [('en', 'ar'), ('en', 'de'), ('en', 'fr'), ('en', 'cs'), ('ar', 'en'), + ('fr', 'en'), ('de', 'en'), ('cs', 'en')] + + **valid/test sets**: ['dev2010', 'tst2010', 'tst2011', 'tst2012', 'tst2013', 'tst2014'] + + For additional details refer to source website: https://wit3.fbk.eu/2016-01 Args: - train_filenames: the source and target filenames for training. - Default: ('train.de-en.de', 'train.de-en.en') - valid_filenames: the source and target filenames for valid. - Default: ('IWSLT16.TED.tst2013.de-en.de', 'IWSLT16.TED.tst2013.de-en.en') - test_filenames: the source and target filenames for test. - Default: ('IWSLT16.TED.tst2014.de-en.de', 'IWSLT16.TED.tst2014.de-en.en') + language_pair: tuple or list of two elements: src and tgt language + valid_set: a string to identify validation set. + test_set: a string to identify test set. split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -266,143 +321,6 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), Default: (get_tokenizer("spacy", language='de_core_news_sm'), get_tokenizer("spacy", language='en_core_web_sm')) - The available datasets include: - - IWSLT16.TED.dev2010.ar-en.ar - IWSLT16.TED.dev2010.ar-en.en - IWSLT16.TED.dev2010.cs-en.cs - IWSLT16.TED.dev2010.cs-en.en - IWSLT16.TED.dev2010.de-en.de - IWSLT16.TED.dev2010.de-en.en - IWSLT16.TED.dev2010.en-ar.ar - IWSLT16.TED.dev2010.en-ar.en - IWSLT16.TED.dev2010.en-cs.cs - IWSLT16.TED.dev2010.en-cs.en - IWSLT16.TED.dev2010.en-de.de - IWSLT16.TED.dev2010.en-de.en - IWSLT16.TED.dev2010.en-fr.en - IWSLT16.TED.dev2010.en-fr.fr - IWSLT16.TED.dev2010.fr-en.en - IWSLT16.TED.dev2010.fr-en.fr - IWSLT16.TED.tst2010.ar-en.ar - IWSLT16.TED.tst2010.ar-en.en - IWSLT16.TED.tst2010.cs-en.cs - IWSLT16.TED.tst2010.cs-en.en - IWSLT16.TED.tst2010.de-en.de - IWSLT16.TED.tst2010.de-en.en - IWSLT16.TED.tst2010.en-ar.ar - IWSLT16.TED.tst2010.en-ar.en - IWSLT16.TED.tst2010.en-cs.cs - IWSLT16.TED.tst2010.en-cs.en - IWSLT16.TED.tst2010.en-de.de - IWSLT16.TED.tst2010.en-de.en - IWSLT16.TED.tst2010.en-fr.en - IWSLT16.TED.tst2010.en-fr.fr - IWSLT16.TED.tst2010.fr-en.en - IWSLT16.TED.tst2010.fr-en.fr - IWSLT16.TED.tst2011.ar-en.ar - IWSLT16.TED.tst2011.ar-en.en - IWSLT16.TED.tst2011.cs-en.cs - IWSLT16.TED.tst2011.cs-en.en - IWSLT16.TED.tst2011.de-en.de - IWSLT16.TED.tst2011.de-en.en - IWSLT16.TED.tst2011.en-ar.ar - IWSLT16.TED.tst2011.en-ar.en - IWSLT16.TED.tst2011.en-cs.cs - IWSLT16.TED.tst2011.en-cs.en - IWSLT16.TED.tst2011.en-de.de - IWSLT16.TED.tst2011.en-de.en - IWSLT16.TED.tst2011.en-fr.en - IWSLT16.TED.tst2011.en-fr.fr - IWSLT16.TED.tst2011.fr-en.en - IWSLT16.TED.tst2011.fr-en.fr - IWSLT16.TED.tst2012.ar-en.ar - IWSLT16.TED.tst2012.ar-en.en - IWSLT16.TED.tst2012.cs-en.cs - IWSLT16.TED.tst2012.cs-en.en - IWSLT16.TED.tst2012.de-en.de - IWSLT16.TED.tst2012.de-en.en - IWSLT16.TED.tst2012.en-ar.ar - IWSLT16.TED.tst2012.en-ar.en - IWSLT16.TED.tst2012.en-cs.cs - IWSLT16.TED.tst2012.en-cs.en - IWSLT16.TED.tst2012.en-de.de - IWSLT16.TED.tst2012.en-de.en - IWSLT16.TED.tst2012.en-fr.en - IWSLT16.TED.tst2012.en-fr.fr - IWSLT16.TED.tst2012.fr-en.en - IWSLT16.TED.tst2012.fr-en.fr - IWSLT16.TED.tst2013.ar-en.ar - IWSLT16.TED.tst2013.ar-en.en - IWSLT16.TED.tst2013.cs-en.cs - IWSLT16.TED.tst2013.cs-en.en - IWSLT16.TED.tst2013.de-en.de - IWSLT16.TED.tst2013.de-en.en - IWSLT16.TED.tst2013.en-ar.ar - IWSLT16.TED.tst2013.en-ar.en - IWSLT16.TED.tst2013.en-cs.cs - IWSLT16.TED.tst2013.en-cs.en - IWSLT16.TED.tst2013.en-de.de - IWSLT16.TED.tst2013.en-de.en - IWSLT16.TED.tst2013.en-fr.en - IWSLT16.TED.tst2013.en-fr.fr - IWSLT16.TED.tst2013.fr-en.en - IWSLT16.TED.tst2013.fr-en.fr - IWSLT16.TED.tst2014.ar-en.ar - IWSLT16.TED.tst2014.ar-en.en - IWSLT16.TED.tst2014.de-en.de - IWSLT16.TED.tst2014.de-en.en - IWSLT16.TED.tst2014.en-ar.ar - IWSLT16.TED.tst2014.en-ar.en - IWSLT16.TED.tst2014.en-de.de - IWSLT16.TED.tst2014.en-de.en - IWSLT16.TED.tst2014.en-fr.en - IWSLT16.TED.tst2014.en-fr.fr - IWSLT16.TED.tst2014.fr-en.en - IWSLT16.TED.tst2014.fr-en.fr - IWSLT16.TEDX.dev2012.de-en.de - IWSLT16.TEDX.dev2012.de-en.en - IWSLT16.TEDX.tst2013.de-en.de - IWSLT16.TEDX.tst2013.de-en.en - IWSLT16.TEDX.tst2014.de-en.de - IWSLT16.TEDX.tst2014.de-en.en - train.ar - train.ar-en.ar - train.ar-en.en - train.cs - train.cs-en.cs - train.cs-en.en - train.de - train.de-en.de - train.de-en.en - train.en - train.en-ar.ar - train.en-ar.en - train.en-cs.cs - train.en-cs.en - train.en-de.de - train.en-de.en - train.en-fr.en - train.en-fr.fr - train.fr - train.fr-en.en - train.fr-en.fr - train.tags.ar-en.ar - train.tags.ar-en.en - train.tags.cs-en.cs - train.tags.cs-en.en - train.tags.de-en.de - train.tags.de-en.en - train.tags.en-ar.ar - train.tags.en-ar.en - train.tags.en-cs.cs - train.tags.en-cs.en - train.tags.en-de.de - train.tags.en-de.en - train.tags.en-fr.en - train.tags.en-fr.fr - train.tags.fr-en.en - train.tags.fr-en.fr Examples: >>> from torchtext.experimental.datasets import IWSLT @@ -415,8 +333,12 @@ def IWSLT(train_filenames=('train.de-en.de', 'train.de-en.en'), >>> src_data, tgt_data = train_dataset[10] """ - return _setup_datasets("IWSLT", train_filenames, valid_filenames, test_filenames, - split, root, vocab, tokenizer) + if not isinstance(language_pair, list) and not isinstance(language_pair, tuple): + raise ValueError("language_pair must be list or tuple") + + assert (len(language_pair) == 2), 'language_pair must contain only 2 elements' + + return _setup_datasets("IWSLT2016", split, root, vocab, tokenizer, language_pair=language_pair, valid_set=valid_set, test_set=test_set) def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', @@ -517,8 +439,10 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', >>> src_data, tgt_data = train_dataset[10] """ - return _setup_datasets("WMT14", train_filenames, valid_filenames, test_filenames, - split, root, vocab, tokenizer) + return _setup_datasets("WMT14", split, root, vocab, tokenizer, + train_filenames=train_filenames, + valid_filenames=valid_filenames, + test_filenames=test_filenames) -DATASETS = {'Multi30k': Multi30k, 'IWSLT': IWSLT, 'WMT14': WMT14} +DATASETS = {'Multi30k': Multi30k, 'IWSLT2016': IWSLT2016, 'IWSLT2017': IWSLT2017, 'WMT14': WMT14} diff --git a/torchtext/legacy/__init__.py b/torchtext/legacy/__init__.py index 686bf47f2b..f9eeec6e10 100644 --- a/torchtext/legacy/__init__.py +++ b/torchtext/legacy/__init__.py @@ -1,6 +1,11 @@ from . import data +from .. import nn # Not in the legacy folder from . import datasets - +from .. import utils # Not in the legacy folder +from .. import vocab # Not in the legacy folder __all__ = ['data', - 'datasets'] + 'nn', + 'datasets', + 'utils', + 'vocab'] diff --git a/torchtext/legacy/data/__init__.py b/torchtext/legacy/data/__init__.py index aa8150ede1..45c57f06c5 100644 --- a/torchtext/legacy/data/__init__.py +++ b/torchtext/legacy/data/__init__.py @@ -4,6 +4,14 @@ from .iterator import (batch, BucketIterator, Iterator, BPTTIterator, pool) from .pipeline import Pipeline from .dataset import Dataset, TabularDataset +# Those are not in the legacy folder. +from ...data.metrics import bleu_score +from ...data.utils import get_tokenizer, interleave_keys +from ...data.functional import generate_sp_model, \ + load_sp_model, \ + sentencepiece_numericalizer, \ + sentencepiece_tokenizer, custom_replace, simple_space_split, \ + numericalize_tokens_from_iterator __all__ = ["Batch", "Example", @@ -11,4 +19,10 @@ "LabelField", "batch", "BucketIterator", "Iterator", "BPTTIterator", "pool", "Pipeline", - "Dataset", "TabularDataset"] + "Dataset", "TabularDataset", + "bleu_score", + "get_tokenizer", "interleave_keys", + "generate_sp_model", "load_sp_model", + "sentencepiece_numericalizer", "sentencepiece_tokenizer", + "custom_replace", "simple_space_split", + "numericalize_tokens_from_iterator"] diff --git a/torchtext/utils.py b/torchtext/utils.py index 41d794fbd1..f1115e95fb 100644 --- a/torchtext/utils.py +++ b/torchtext/utils.py @@ -53,6 +53,10 @@ def download_from_url(url, path=None, root='.data', overwrite=False, hash_value= >>> '.data/validation.tar.gz' """ + if path is not None: + path = os.path.abspath(path) + root = os.path.abspath(root) + def _check_hash(path): if hash_value: logging.info('Validating hash {} matches hash of {}'.format(hash_value, path)) @@ -219,6 +223,7 @@ def extract_archive(from_path, to_path=None, overwrite=False): if not overwrite: continue tar.extract(file_, to_path) + logging.info('Finished extracting tar file {}.'.format(from_path)) return files elif from_path.endswith('.zip'): @@ -235,9 +240,11 @@ def extract_archive(from_path, to_path=None, overwrite=False): continue zfile.extract(file_, to_path) files = [f for f in files if os.path.isfile(f)] + logging.info('Finished extracting zip file {}.'.format(from_path)) return files elif from_path.endswith('.gz'): + logging.info('Opening gz file {}.'.format(from_path)) default_block_size = 65536 filename = from_path[:-3] files = [filename] @@ -250,6 +257,7 @@ def extract_archive(from_path, to_path=None, overwrite=False): else: d_file.write(block) d_file.write(block) + logging.info('Finished extracting gz file {}.'.format(from_path)) return files else: From 81b24b5520b90e5c523fd747c7c8aefd8cf6bcda Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Mon, 8 Mar 2021 14:15:08 -0800 Subject: [PATCH 50/68] 20210308 Sync torchtext GH <-> fbcode Summary: Import latest GH changes Reviewed By: zhangguanheng66 Differential Revision: D26888371 fbshipit-source-id: cc27f51fd89ad86b8bcfb8f286ad874ab01b1fd6 --- README.rst | 136 ++--- .../benchmark_basic_english_normalize.py | 6 +- benchmark/benchmark_experimental_vectors.py | 2 +- benchmark/benchmark_experimental_vocab.py | 2 +- benchmark/benchmark_sentencepiece.py | 6 +- docs/source/conf.py | 5 - docs/source/datasets.rst | 21 +- docs/source/examples.rst | 91 --- docs/source/experimental_datasets_raw.rst | 52 ++ docs/source/index.rst | 2 +- .../legacy_tutorial/migration_tutorial.ipynb | 520 +++++++++++++++++ packaging/build_conda.sh | 2 +- packaging/build_wheel.sh | 2 +- setup.cfg | 2 + setup.py | 2 +- test/asset/raw_datasets.json | 9 +- test/common/cache_utils.py | 46 ++ test/data/test_builtin_datasets.py | 60 +- test/legacy/data/test_batch.py | 4 +- test/legacy/data/test_dataset.py | 4 +- torchtext/data/datasets_utils.py | 151 ++++- torchtext/datasets/__init__.py | 6 - torchtext/datasets/ag_news.py | 32 +- torchtext/datasets/amazonreviewfull.py | 40 +- torchtext/datasets/amazonreviewpolarity.py | 39 +- torchtext/datasets/conll2000chunking.py | 46 +- torchtext/datasets/dbpedia.py | 36 +- torchtext/datasets/enwik9.py | 27 +- torchtext/datasets/imdb.py | 16 +- torchtext/datasets/iwslt2016.py | 161 ++---- torchtext/datasets/iwslt2017.py | 176 ++---- torchtext/datasets/multi30k.py | 171 ------ torchtext/datasets/penntreebank.py | 24 +- torchtext/datasets/sogounews.py | 39 +- torchtext/datasets/squad1.py | 36 +- torchtext/datasets/squad2.py | 36 +- torchtext/datasets/udpos.py | 42 +- torchtext/datasets/wikitext103.py | 31 +- torchtext/datasets/wikitext2.py | 26 +- torchtext/datasets/wmt14.py | 179 ------ torchtext/datasets/yahooanswers.py | 31 +- torchtext/datasets/yelpreviewfull.py | 36 +- torchtext/datasets/yelpreviewpolarity.py | 33 +- .../datasets/language_modeling.py | 21 +- .../experimental/datasets/question_answer.py | 8 +- .../experimental/datasets/raw/__init__.py | 22 + .../experimental/datasets/raw/multi30k.py | 543 ++++++++++++++++++ torchtext/experimental/datasets/raw/wmt14.py | 159 +++++ .../datasets/raw}/wmtnewscrawl.py | 28 +- .../experimental/datasets/sequence_tagging.py | 8 +- .../datasets/text_classification.py | 8 +- .../experimental/datasets/translation.py | 249 ++++---- torchtext/legacy/README.rst | 53 ++ torchtext/legacy/data/__init__.py | 6 + torchtext/legacy/data/dataset.py | 7 +- torchtext/legacy/data/field.py | 6 +- .../legacy/datasets/language_modeling.py | 27 +- torchtext/nn/modules/multiheadattention.py | 46 +- 58 files changed, 2232 insertions(+), 1347 deletions(-) delete mode 100644 docs/source/examples.rst create mode 100644 docs/source/experimental_datasets_raw.rst create mode 100644 examples/legacy_tutorial/migration_tutorial.ipynb create mode 100644 setup.cfg create mode 100644 test/common/cache_utils.py delete mode 100644 torchtext/datasets/multi30k.py delete mode 100644 torchtext/datasets/wmt14.py create mode 100644 torchtext/experimental/datasets/raw/__init__.py create mode 100644 torchtext/experimental/datasets/raw/multi30k.py create mode 100644 torchtext/experimental/datasets/raw/wmt14.py rename torchtext/{datasets => experimental/datasets/raw}/wmtnewscrawl.py (65%) create mode 100644 torchtext/legacy/README.rst diff --git a/README.rst b/README.rst index 501388d543..9369ba40cf 100644 --- a/README.rst +++ b/README.rst @@ -12,14 +12,12 @@ torchtext This repository consists of: -* `torchtext.data <#data>`_: Generic data loaders, abstractions, and iterators for text (including vocabulary and word vectors) -* `torchtext.datasets <#datasets>`_: Pre-built loaders for common NLP datasets +* `torchtext.datasets `_: The raw text iterators for common NLP datasets +* `torchtext.data `_: Some basic NLP building blocks (tokenizers, metrics, functionals etc.) +* `torchtext.nn `_: NLP related modules +* `examples `_: Example NLP workflows with PyTorch and torchtext library. -Note: we are currently re-designing the torchtext library to make it more compatible with pytorch (e.g. ``torch.utils.data``). Several datasets have been written with the new abstractions in `torchtext.experimental `_ folder. We also created an issue to discuss the new abstraction, and users are welcome to leave feedback `link `_. These prototype building blocks and datasets in the experimental folder are available in the nightly release only. The nightly packages are accessible via Pip and Conda for Windows, Mac, and Linux. For example, Linux users can install the nightly wheels with the following command:: - - pip install --pre torch torchtext -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html - -For more detailed instructions, please refer to `Install PyTorch `_. It should be noted that the new building blocks are still under development, and the APIs have not been solidified. +Note: the legacy code discussed in `torchtext v0.7.0 release note `_ has been retired to `torchtext.legacy `_ folder. Those legacy code will not be maintained by the development team, and we plan to fully remove them in the future release. See `torchtext.legacy `_ folder for more details. Installation ============ @@ -31,6 +29,7 @@ We recommend Anaconda as Python package management system. Please refer to `pyto :widths: 10, 10, 10 nightly build, master, 3.6+ + 1.8, 0.9, 3.6+ 1.7, 0.8, 3.6+ 1.6, 0.7, 3.6+ 1.5, 0.6, 3.5+ @@ -51,7 +50,7 @@ Optional requirements If you want to use English tokenizer from `SpaCy `_, you need to install SpaCy and download its English model:: pip install spacy - python -m spacy download en + python -m spacy download en_core_web_sm Alternatively, you might want to use the `Moses `_ tokenizer port in `SacreMoses `_ (split from `NLTK `_). You have to install SacreMoses:: @@ -88,105 +87,62 @@ Documentation Find the documentation `here `_. -Data -==== - -The data module provides the following: - -* Ability to describe declaratively how to load a custom NLP dataset that's in a "normal" format: - - .. code-block:: python - - >>> pos = data.TabularDataset( - ... path='data/pos/pos_wsj_train.tsv', format='tsv', - ... fields=[('text', data.Field()), - ... ('labels', data.Field())]) - ... - >>> sentiment = data.TabularDataset( - ... path='data/sentiment/train.json', format='json', - ... fields={'sentence_tokenized': ('text', data.Field(sequential=True)), - ... 'sentiment_gold': ('labels', data.Field(sequential=False))}) - -* Ability to define a preprocessing pipeline: - - .. code-block:: python - - >>> src = data.Field(tokenize=my_custom_tokenizer) - >>> trg = data.Field(tokenize=my_custom_tokenizer) - >>> mt_train = datasets.TranslationDataset( - ... path='data/mt/wmt16-ende.train', exts=('.en', '.de'), - ... fields=(src, trg)) +Datasets +======== -* Batching, padding, and numericalizing (including building a vocabulary object): +The datasets module currently contains: - .. code-block:: python +* Language modeling: WikiText2, WikiText103, PennTreebank, EnWik9 +* Machine translation: IWSLT2016, IWSLT2017 +* Sequence tagging (e.g. POS/NER): UDPOS, CoNLL2000Chunking +* Question answering: SQuAD1, SQuAD2 +* Text classification: AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, YelpReviewFull, YahooAnswers, AmazonReviewPolarity, AmazonReviewFull, IMDB - >>> # continuing from above - >>> mt_dev = datasets.TranslationDataset( - ... path='data/mt/newstest2014', exts=('.en', '.de'), - ... fields=(src, trg)) - >>> src.build_vocab(mt_train, max_size=80000) - >>> trg.build_vocab(mt_train, max_size=40000) - >>> # mt_dev shares the fields, so it shares their vocab objects - >>> - >>> train_iter = data.BucketIterator( - ... dataset=mt_train, batch_size=32, - ... sort_key=lambda x: data.interleave_keys(len(x.src), len(x.trg))) - >>> # usage - >>> next(iter(train_iter)) - - -* Wrapper for dataset splits (train, validation, test): +For example, to access the raw text from the AG_NEWS dataset: .. code-block:: python - >>> TEXT = data.Field() - >>> LABELS = data.Field() - >>> - >>> train, val, test = data.TabularDataset.splits( - ... path='/data/pos_wsj/pos_wsj', train='_train.tsv', - ... validation='_dev.tsv', test='_test.tsv', format='tsv', - ... fields=[('text', TEXT), ('labels', LABELS)]) - >>> - >>> train_iter, val_iter, test_iter = data.BucketIterator.splits( - ... (train, val, test), batch_sizes=(16, 256, 256), - >>> sort_key=lambda x: len(x.text), device=0) - >>> - >>> TEXT.build_vocab(train) - >>> LABELS.build_vocab(train) + >>> from torchtext.datasets import AG_NEWS + >>> train_iter = AG_NEWS(split='train') + >>> next(train_iter) + >>> # Or iterate with for loop + >>> for (label, line) in train_iter: + >>> print(label, line) + >>> # Or send to DataLoader + >>> from torch.utils.data import DataLoader + >>> train_iter = AG_NEWS(split='train') + >>> dataloader = DataLoader(train_iter, batch_size=8, shuffle=False) -Datasets -======== +A tutorial for the end-to-end text classification workflow can be found in `PyTorch tutorial `_ -The datasets module currently contains: +[Prototype] Experimental Code +============================= -* Sentiment analysis: SST and IMDb -* Question classification: TREC -* Entailment: SNLI, MultiNLI -* Language modeling: abstract class + WikiText-2, WikiText103, PennTreebank -* Machine translation: abstract class + Multi30k, IWSLT, WMT14 -* Sequence tagging (e.g. POS/NER): abstract class + UDPOS, CoNLL2000Chunking -* Question answering: 20 QA bAbI tasks -* Text classification: AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, YelpReviewFull, YahooAnswers, AmazonReviewPolarity, AmazonReviewFull +We have re-written several building blocks under ``torchtext.experimental``: -Others are planned or a work in progress: +* `Transforms `_: some basic data processing building blocks +* `Vocabulary `_: a vocabulary to numericalize tokens +* `Vectors `_: the vectors to convert tokens into tensors. -* Question answering: SQuAD +These prototype building blocks in the experimental folder are available in the nightly release only. The nightly packages are accessible via Pip and Conda for Windows, Mac, and Linux. For example, Linux users can install the nightly wheels with the following command:: -See the ``test`` directory for examples of dataset usage. + pip install --pre --upgrade torch torchtext -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html -Experimental Code -================= +For more detailed instructions, please refer to `Install PyTorch `_. It should be noted that the new building blocks are still under development, and the APIs have not been solidified. -We have re-written several datasets under ``torchtext.experimental.datasets``: +[BC Breaking] Legacy +==================== -* Sentiment analysis: IMDb -* Language modeling: abstract class + WikiText-2, WikiText103, PennTreebank +In v0.9.0 release, we move the following legacy code to `torchtext.legacy `_. This is part of the work to revamp the torchtext library and the motivation has been discussed in `Issue #664 `_: -A new pattern is introduced in `Release v0.5.0 `_. Several other datasets are also in the new pattern: +* ``torchtext.legacy.data.field`` +* ``torchtext.legacy.data.batch`` +* ``torchtext.legacy.data.example`` +* ``torchtext.legacy.data.iterator`` +* ``torchtext.legacy.data.pipeline`` +* ``torchtext.legacy.datasets`` -* Unsupervised learning dataset: Enwik9 -* Text classification: AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, YelpReviewFull, YahooAnswers, AmazonReviewPolarity, AmazonReviewFull +We have a `migration tutorial `_ to help users switch to the torchtext datasets in ``v0.9.0`` release. For the users who still want the legacy components, they can add ``legacy`` to the import path. Disclaimer on Datasets ====================== diff --git a/benchmark/benchmark_basic_english_normalize.py b/benchmark/benchmark_basic_english_normalize.py index cb24235746..b4f9e99f93 100644 --- a/benchmark/benchmark_basic_english_normalize.py +++ b/benchmark/benchmark_basic_english_normalize.py @@ -18,17 +18,17 @@ def _run_benchmark_lookup(train, tokenizer): experimental_jit_basic_english_normalize = torch.jit.script(experimental_basic_english_normalize) # existing eager lookup - train, _ = AG_NEWS() + train = AG_NEWS(split='train') print("BasicEnglishNormalize - Eager Mode") _run_benchmark_lookup(train, existing_basic_english_tokenizer) # experimental eager lookup - train, _ = AG_NEWS() + train = AG_NEWS(split='train') print("BasicEnglishNormalize Experimental - Eager Mode") _run_benchmark_lookup(train, experimental_basic_english_normalize) # experimental jit lookup - train, _ = AG_NEWS() + train = AG_NEWS(split='train') print("BasicEnglishNormalize Experimental - Jit Mode") _run_benchmark_lookup(train, experimental_jit_basic_english_normalize) diff --git a/benchmark/benchmark_experimental_vectors.py b/benchmark/benchmark_experimental_vectors.py index f644c14e62..f3dee98ba5 100644 --- a/benchmark/benchmark_experimental_vectors.py +++ b/benchmark/benchmark_experimental_vectors.py @@ -13,7 +13,7 @@ def _run_benchmark_lookup(tokens, vector): vector[token] print("Lookup time:", time.monotonic() - t0) - train, = AG_NEWS(data_select='train') + train = AG_NEWS(split='train') vocab = train.get_vocab() tokens = [] for (label, text) in train: diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index f815bf3648..e63904934d 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -94,7 +94,7 @@ def _run_benchmark_lookup(tokens, vocab): tokens = [] tokens_lists = [] - train, = AG_NEWS(data_select='train') + train = AG_NEWS(split='train') vocab = train.get_vocab() for (_, text) in train: cur_tokens = [] diff --git a/benchmark/benchmark_sentencepiece.py b/benchmark/benchmark_sentencepiece.py index 1049a95523..8a047e7805 100644 --- a/benchmark/benchmark_sentencepiece.py +++ b/benchmark/benchmark_sentencepiece.py @@ -3,7 +3,7 @@ from torchtext.experimental.transforms import load_sp_model as load_pybind_sp_model from torchtext.data.functional import load_sp_model as load_torchbind_sp_model from torchtext.utils import download_from_url -from torchtext.datasets import text_classification as raw +from torchtext.datasets import DATASETS def benchmark_sentencepiece(args): @@ -17,13 +17,13 @@ def _run_benchmark(train, spm_processor): sp_model_path = download_from_url('https://pytorch.s3.amazonaws.com/models/text/pretrained_spm/text_unigram_15000.model') # existing sentencepiece model with torchbind - train, _ = raw.DATASETS[args.dataset]() + train = DATASETS[args.dataset](split='train') sp_model = load_torchbind_sp_model(sp_model_path) print("SentencePiece EncodeAsIds - torchbind") _run_benchmark(train, sp_model.EncodeAsIds) # experimental sentencepiece model with pybind - train, _ = raw.DATASETS[args.dataset]() + train = DATASETS[args.dataset](split='train') sp_model = load_pybind_sp_model(sp_model_path) print("SentencePiece EncodeAsIds - pybind") _run_benchmark(train, sp_model.EncodeAsIds) diff --git a/docs/source/conf.py b/docs/source/conf.py index 2756d79f22..2116258ead 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -121,11 +121,6 @@ html_static_path = ['_static'] -def setup(app): - app.add_stylesheet('css/pytorch_theme.css') - app.add_stylesheet('https://fonts.googleapis.com/css/family=Lato') - - intersphinx_mapping = { 'python': ('https://docs.python.org/', None), 'numpy': ('http://docs.scipy.org/doc/numpy/', None), diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index 22342d5997..adead6c4a4 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -15,8 +15,8 @@ General use cases are as follows: :: return line.split() tokens = [] - for line in train_iter: - tokens += tokenize(line) + for label, line in train_iter: + tokens += tokenize(label, line) The following datasets are available: @@ -98,20 +98,9 @@ PennTreebank .. autofunction:: PennTreebank -WMTNewsCrawl -~~~~~~~~~~~~ - -.. autofunction:: WMTNewsCrawl - - Machine Translation ^^^^^^^^^^^^^^^^^^^ -Multi30k -~~~~~~~~ - -.. autofunction:: Multi30k - IWSLT2016 ~~~~~~~~~ @@ -124,12 +113,6 @@ IWSLT2017 .. autofunction:: IWSLT2017 -WMT14 -~~~~~ - -.. autofunction:: WMT14 - - Sequence Tagging ^^^^^^^^^^^^^^^^ diff --git a/docs/source/examples.rst b/docs/source/examples.rst deleted file mode 100644 index 660936aaa1..0000000000 --- a/docs/source/examples.rst +++ /dev/null @@ -1,91 +0,0 @@ -.. role:: hidden - :class: hidden-section - -Examples -========= - -Note: We are working on new building blocks and datasets. Some of the components in the examples (e.g. Field) will eventually retire. See the release note 0.5.0 `here `_. - -1. Ability to describe declaratively how to load a custom NLP dataset that's in a "normal" format: - -.. code-block:: python - - pos = data.TabularDataset( - path='data/pos/pos_wsj_train.tsv', format='tsv', - fields=[('text', data.Field()), - ('labels', data.Field())]) - - sentiment = data.TabularDataset( - path='data/sentiment/train.json', format='json', - fields={'sentence_tokenized': ('text', data.Field(sequential=True)), - 'sentiment_gold': ('labels', data.Field(sequential=False))}) - -2. Ability to parse nested keys for loading a JSON dataset - -2.1 sample.json - -.. code-block:: json - - {"foods": { - "fruits": ["Apple", "Banana"], - "vegetables": [{"name": "lettuce"}, {"name": "marrow"}] - } - } - -2.2 pass in nested keys to parse nested data directly - -.. code-block:: python - - In [1]: from torchtext import data - In [2]: fields = {'foods.vegetables.name': ('vegs', data.Field())} - In [3]: dataset = data.TabularDataset(path='sample.json', format='json', fields=fields) - In [4]: dataset.examples[0].vegs - Out[4]: ['lettuce', 'marrow'] - -3. Ability to define a preprocessing pipeline: - -.. code-block:: python - - src = data.Field(tokenize=my_custom_tokenizer) - trg = data.Field(tokenize=my_custom_tokenizer) - mt_train = datasets.TranslationDataset( - path='data/mt/wmt16-ende.train', exts=('.en', '.de'), - fields=(src, trg)) - -4. Batching, padding, and numericalizing (including building vocabulary object): - -.. code-block:: python - - # continuing from above - mt_dev = data.TranslationDataset( - path='data/mt/newstest2014', exts=('.en', '.de'), - fields=(src, trg)) - src.build_vocab(mt_train, max_size=80000) - trg.build_vocab(mt_train, max_size=40000) - # mt_dev shares the fields, so it shares their vocab objects - - train_iter = data.BucketIterator( - dataset=mt_train, batch_size=32, - sort_key=lambda x: data.interleave_keys(len(x.src), len(x.trg))) - # usage - >>>next(iter(train_iter)) - - -5. Wrapper for dataset splits (train, validation, test): - -.. code-block:: python - - TEXT = data.Field() - LABELS = data.Field() - - train, val, test = data.TabularDataset.splits( - path='/data/pos_wsj/pos_wsj', train='_train.tsv', - validation='_dev.tsv', test='_test.tsv', format='tsv', - fields=[('text', TEXT), ('labels', LABELS)]) - - train_iter, val_iter, test_iter = data.BucketIterator.splits( - (train, val, test), batch_sizes=(16, 256, 256), - sort_key=lambda x: len(x.text), device=0) - - TEXT.build_vocab(train) - LABELS.build_vocab(train) diff --git a/docs/source/experimental_datasets_raw.rst b/docs/source/experimental_datasets_raw.rst new file mode 100644 index 0000000000..2f8665bce6 --- /dev/null +++ b/docs/source/experimental_datasets_raw.rst @@ -0,0 +1,52 @@ +torchtext.experimental.datasets.raw +=================================== + +.. currentmodule:: torchtext.experimental.datasets.raw + +General use cases are as follows: :: + + + # import datasets + from torchtext.experimental.datasets.raw import Multi30k + + train_iter = Multi30k(split='train') + + def tokenize(label, line): + return line.split() + + tokens_src = [] + tokens_tgt = [] + + for line in train_iter: + src, tgt = line + tokens_src += tokenize(src) + tokens_tgt += tokenize(tgt) + +The following datasets are available: + +.. contents:: Datasets + :local: + + +Machine Translation +^^^^^^^^^^^^^^^^^^^ + +Multi30k +~~~~~~~~ + +.. autofunction:: Multi30k + + +WMT14 +~~~~~ + +.. autofunction:: WMT14 + + +Language Modeling +^^^^^^^^^^^^^^^^^ + +WMTNewsCrawl +~~~~~~~~~~~~ + +.. autofunction:: WMTNewsCrawl diff --git a/docs/source/index.rst b/docs/source/index.rst index 704b40a8f7..525466264e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -40,11 +40,11 @@ popular datasets for natural language. torchtext.vocab torchtext.utils experimental_datasets + experimental_datasets_raw experimental_transforms experimental_vectors experimental_vocab models_utils - examples .. automodule:: torchtext :members: diff --git a/examples/legacy_tutorial/migration_tutorial.ipynb b/examples/legacy_tutorial/migration_tutorial.ipynb new file mode 100644 index 0000000000..7be3ade927 --- /dev/null +++ b/examples/legacy_tutorial/migration_tutorial.ipynb @@ -0,0 +1,520 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Migrate torchtext from the legacy API to the new API", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "HMGWxQCO7s0e" + }, + "source": [ + "!pip install -U torch==1.8.0 torchtext==0.9.0\n", + "\n", + "# Reload environment\n", + "exit()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jXUgsnxw70-M" + }, + "source": [ + "This is a tutorial to show how to migrate from the legacy API in torchtext to the new API in 0.9.0 release. Here, we take the IMDB dataset as an example for the sentiment analysis. Both legacy and new APIs in torchtext can preprocess the text input and prepare the data to train/validate a model with the following steps:\n", + "\n", + "* Train/validate/test split: generate train/validate/test data set if they are available\n", + "* Tokenization: break a raw text string sentence into a list of words\n", + "* Vocab: define a \"contract\" from tokens to indexes\n", + "* Numericalize: convert a list of tokens to the corresponding indexes\n", + "* Batch: generate batches of data samples and add padding if necessary\n", + "\n", + "It should be noted that all the legacy features are still available, but within torchtext.legacy instead of torchtext." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWRW4bsL8UL0" + }, + "source": [ + "## Step 1: Create a dataset object\n", + "----------------------------\n", + "\n", + "Fist of all, we create a dataset for the sentiment analysis. The individual data sample contains a label and a text string.\n", + "\n", + "### *Legacy*\n", + "In the legacy code, `Field` class is used for data processing, including tokenizer and numberzation. To check out the dataset, users need to first set up the TEXT/LABEL fields." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FttPxcbc70j1" + }, + "source": [ + "import torchtext\n", + "import torch\n", + "from torchtext.legacy import data\n", + "from torchtext.legacy import datasets\n", + "\n", + "TEXT = data.Field()\n", + "LABEL = data.LabelField(dtype = torch.long)\n", + "legacy_train, legacy_test = datasets.IMDB.splits(TEXT, LABEL) # datasets here refers to torchtext.legacy.datasets" + ], + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ssXfxJJSq7WT" + }, + "source": [ + "You can print out the raw data by checking out Dataset.examples. The entire text data are stored as a list of tokens." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "7DRXJFgzriaH" + }, + "source": [ + "legacy_examples = legacy_train.examples\n", + "print(legacy_examples[0].text, legacy_examples[0].label)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eQMfAN_Fz3aa" + }, + "source": [ + "### *New*\n", + "The new dataset API returns the train/test dataset split directly without the preprocessing information. Each split is an iterator which yields the raw texts and labels line-by-line." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YHUYZ7yt0Lb5" + }, + "source": [ + "from torchtext.datasets import IMDB\n", + "train_iter, test_iter = IMDB(split=('train', 'test'))" + ], + "execution_count": 9, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yB7MShEBsd3P" + }, + "source": [ + "To print out the raw data, you can call the next() function on the IterableDataset." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wUkWE1KWsPqy" + }, + "source": [ + "next(train_iter)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ycL7xqRP0eLU" + }, + "source": [ + "## Step 2 Build the data processing pipeline\n", + "----------------------------\n", + "\n", + "### *Legacy*\n", + "\n", + "The default tokenizer implemented in the `Field` class is the built-in python `split()` function. Users choose the tokenizer by calling `data.get_tokenizer()`, and add it to the `Field` constructor. For the sequence model, it's common to append `` (begin-of-sentence) and `` (end-of-sentence) tokens, and the special tokens need to be defined in the `Field` class." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8H_I_XW8gSR1" + }, + "source": [ + "TEXT = data.Field(tokenize=data.get_tokenizer('basic_english'),\n", + " init_token='', eos_token='', lower=True)\n", + "LABEL = data.LabelField(dtype = torch.long)\n", + "legacy_train, legacy_test = datasets.IMDB.splits(TEXT, LABEL) # datasets here refers to torchtext.legacy.datasets" + ], + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "opQ6LcnigTKx" + }, + "source": [ + "Now you can create a vocabulary of the words from the text file stored in the predefined `Field` object, `TEXT`. You fist have to build a vocabulary in your `Field` object by passing the dataset to the `build_vocab` func. The Field object builds the vocabulary (`TEXT.vocab`) on a specific data split." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Cffl6ueN8T5X" + }, + "source": [ + "TEXT.build_vocab(legacy_train)\n", + "LABEL.build_vocab(legacy_train)" + ], + "execution_count": 12, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OXQ9rmiHt58H" + }, + "source": [ + "Things you can do with a vocabuary object\n", + "\n", + "\n", + "* Total length of the vocabulary\n", + "* String2Index (stoi) and Index2String (itos)\n", + "* A purpose-specific vocabulary which contains word appearing more than N times\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YzweKLh5uSNC" + }, + "source": [ + "legacy_vocab = TEXT.vocab\n", + "print(\"The length of the legacy vocab is\", len(legacy_vocab))\n", + "legacy_stoi = legacy_vocab.stoi\n", + "print(\"The index of 'example' is\", legacy_stoi['example'])\n", + "legacy_itos = legacy_vocab.itos\n", + "print(\"The token at index 686 is\", legacy_itos[686])\n", + "\n", + "# Set up the mim_freq value in the Vocab class\n", + "TEXT.build_vocab(legacy_train, min_freq=10)\n", + "legacy_vocab2 = TEXT.vocab\n", + "print(\"The length of the legacy vocab is\", len(legacy_vocab2))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LXTibHc00olW" + }, + "source": [ + "### *New*\n", + "\n", + "Users have the access to different kinds of tokenizers directly via `data.get_tokenizer()` function." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "QavK23zjhNlx" + }, + "source": [ + "from torchtext.data.utils import get_tokenizer\n", + "tokenizer = get_tokenizer('basic_english')" + ], + "execution_count": 14, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TnNpf4mWF5pe" + }, + "source": [ + "To have more flexibility, users can build the vocabulary directly with the Vocab class. For example, the argument `min_freq` is to set up the cutoff frequency to in the vocabulary. The special tokens, like `` and `` can be assigned to the special symbols in the constructor of the Vocab class." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ro8HXPwmwtp7" + }, + "source": [ + "from collections import Counter\n", + "from torchtext.vocab import Vocab\n", + "\n", + "train_iter = IMDB(split='train')\n", + "counter = Counter()\n", + "for (label, line) in train_iter:\n", + " counter.update(tokenizer(line))\n", + "vocab = Vocab(counter, min_freq=10, specials=('', '', '', ''))" + ], + "execution_count": 15, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "xGuqqa7CxLq8" + }, + "source": [ + "print(\"The length of the new vocab is\", len(vocab))\n", + "new_stoi = vocab.stoi\n", + "print(\"The index of '' is\", new_stoi[''])\n", + "new_itos = vocab.itos\n", + "print(\"The token at index 2 is\", new_itos[2])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l31FBekVr9j8" + }, + "source": [ + "Both `text_transform` and `label_transform` are the callable object, such as a lambda func here, to process the raw text and label data from the dataset iterators. Users can add the special symbols `` and `` to the sentence in `text_transform`." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ez2lT2QO0sNj" + }, + "source": [ + "text_transform = lambda x: [vocab['']] + [vocab[token] for token in tokenizer(x)] + [vocab['']]\n", + "label_transform = lambda x: 1 if x == 'pos' else 0\n", + "\n", + "# Print out the output of text_transform\n", + "print(\"input to the text_transform:\", \"here is an example\")\n", + "print(\"output of the text_transform:\", text_transform(\"here is an example\"))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4dEG7pyi1ElM" + }, + "source": [ + "## Step 3: Generate batch iterator\n", + "--------------------------------\n", + "\n", + "To train a model efficiently, it's recommended to build an iterator to generate data batch.\n", + "\n", + "### *Legacy*\n", + "The legacy `Iterator` class is used to batch the dataset and send to the target device, like CPU or GPU." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NN67ofUB-sz1" + }, + "source": [ + "import torch\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "legacy_train, legacy_test = datasets.IMDB.splits(TEXT, LABEL) # datasets here refers to torchtext.legacy.datasets\n", + "legacy_train_iterator, legacy_test_iterator = data.Iterator.splits(\n", + " (legacy_train, legacy_test), batch_size=8, device = device)" + ], + "execution_count": 18, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vBMjFVvsMPqR" + }, + "source": [ + "For a NLP workflow, it's also common to define an iterator and batch texts with similar lengths together. The legacy `BucketIterator` class in torchtext library minimizes the amount of padding needed." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PgC6dhDqMOjp" + }, + "source": [ + "from torchtext.legacy.data import BucketIterator\n", + "legacy_train, legacy_test = datasets.IMDB.splits(TEXT, LABEL)\n", + "legacy_train_bucketiterator, legacy_test_bucketiterator = data.BucketIterator.splits(\n", + " (legacy_train, legacy_test),\n", + " sort_key=lambda x: len(x.text),\n", + " batch_size=8, device = device)" + ], + "execution_count": 19, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kBV-Wvlo07ye" + }, + "source": [ + "### *New*\n", + "\n", + "`torch.utils.data.DataLoader` is used to generate data batch. Users could customize the data batch by defining a function with the `collate_fn` argument in the DataLoader. Here, in the `collate_batch` func, we process the raw text data and add padding to dynamically match the longest sentence in a batch." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EC054Wlr0-xB" + }, + "source": [ + "from torch.utils.data import DataLoader\n", + "from torch.nn.utils.rnn import pad_sequence\n", + "\n", + "def collate_batch(batch):\n", + " label_list, text_list = [], []\n", + " for (_label, _text) in batch:\n", + " label_list.append(label_transform(_label))\n", + " processed_text = torch.tensor(text_transform(_text))\n", + " text_list.append(processed_text)\n", + " return torch.tensor(label_list), pad_sequence(text_list, padding_value=3.0)\n", + "\n", + "train_iter = IMDB(split='train')\n", + "train_dataloader = DataLoader(list(train_iter), batch_size=8, shuffle=True, \n", + " collate_fn=collate_batch)" + ], + "execution_count": 20, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Jky4X-iFU4HK" + }, + "source": [ + "To group the texts with similar length together, like introduced in the legacy `BucketIterator` class, first of all, we randomly create multiple \"pools\", and each of them has a size of `batch_size * 100`. Then, we sort the samples within the individual pool by length. This idea can be implemented succintly through `batch_sampler` argument of PyTorch `Dataloader`. `batch_sampler` accepts 'Sampler' or Iterable object that yields indices of next batch. In the code below, we implemented a generator that yields batch of indices for which the corresponding batch of data is of similar length. " + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zCvxeLbYW3I_" + }, + "source": [ + "import random\n", + "\n", + "train_iter = IMDB(split='train')\n", + "train_list = list(train_iter)\n", + "batch_size = 8 # A batch size of 8\n", + "\n", + "def batch_sampler():\n", + " indices = [(i, len(tokenizer(s[1]))) for i, s in enumerate(train_list)]\n", + " random.shuffle(indices)\n", + " pooled_indices = []\n", + " # create pool of indices with similar lengths \n", + " for i in range(0, len(indices), batch_size * 100):\n", + " pooled_indices.extend(sorted(indices[i:i + batch_size * 100], key=lambda x: x[1]))\n", + "\n", + " pooled_indices = [x[0] for x in pooled_indices]\n", + "\n", + " # yield indices for current batch\n", + " for i in range(0, len(pooled_indices), batch_size):\n", + " yield pooled_indices[i:i + batch_size]\n", + "\n", + "bucket_dataloader = DataLoader(train_list, batch_sampler=batch_sampler(),\n", + " collate_fn=collate_batch)\n", + "\n", + "print(next(iter(bucket_dataloader)))" + ], + "execution_count": 24, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0wrbC_v01Ib9" + }, + "source": [ + "## Step 4: Iterate batch to train a model\n", + "-------------------------------\n", + "\n", + "It's almost same for both legacy and new APIs to iterate the data for batches during training and validating a model.\n", + "\n", + "### *Legacy*\n", + "\n", + "The legacy batch iterator can be iterated or executed with `next()` method." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "X_tml54u-6AS" + }, + "source": [ + "# for item in legacy_train_iterator:\n", + "# model(item)\n", + "\n", + "# Or\n", + "next(iter(legacy_train_iterator))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sRTvfxMB1P2P" + }, + "source": [ + "### *New*\n", + "\n", + "The batch iterator can be iterated or executed with `next()` method." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iTotRtXe1CWn" + }, + "source": [ + "# for idx, (label, text) in enumerate(train_dataloader):\n", + "# model(item)\n", + "\n", + "# Or\n", + "next(iter(train_dataloader))" + ], + "execution_count": null, + "outputs": [] + } + ] +} diff --git a/packaging/build_conda.sh b/packaging/build_conda.sh index 3dfac7fd34..6ee237613d 100755 --- a/packaging/build_conda.sh +++ b/packaging/build_conda.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="conda" export NO_CUDA_PACKAGE=1 -setup_env 0.9.0 +setup_env 0.10.0 export SOURCE_ROOT_DIR="$PWD" setup_conda_pytorch_constraint setup_visual_studio_constraint diff --git a/packaging/build_wheel.sh b/packaging/build_wheel.sh index 4f1604e722..dbdc1f2702 100755 --- a/packaging/build_wheel.sh +++ b/packaging/build_wheel.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="wheel" export NO_CUDA_PACKAGE=1 -setup_env 0.9.0 +setup_env 0.10.0 setup_wheel_python pip_install numpy future setup_pip_pytorch_version diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000000..182c9f7e3f --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[pydocstyle] +select = D417 # Missing argument descriptions in the docstring diff --git a/setup.py b/setup.py index 7c71a0ddca..95fffe4035 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ def read(*names, **kwargs): def _get_version(): - version = '0.9.0a0' + version = '0.10.0a0' sha = None try: diff --git a/test/asset/raw_datasets.json b/test/asset/raw_datasets.json index 6ceefe73b7..e48add06d2 100644 --- a/test/asset/raw_datasets.json +++ b/test/asset/raw_datasets.json @@ -21,14 +21,14 @@ {"dataset_name": "UDPOS", "split": "test", "NUM_LINES": 2077, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": [["What", "if", "Google", "Morphed", "Into", "GoogleOS", "?"], ["PRON", "SCONJ", "PROPN", "VERB", "ADP", "PROPN", "PUNCT"], ["WP", "IN", "NNP", "VBD", "IN", "NNP", "."]]} {"dataset_name": "CoNLL2000Chunking", "split": "train", "NUM_LINES": 8936, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": [["Confidence", "in", "the", "pound", "is", "widely", "expected", "to", "take", "another", "sharp", "dive", "if", "trade", "figures", "for", "September", ",", "due", "for", "release", "tomorrow", ",", "fail", "to", "show", "a", "substantial", "improvement", "from", "July", "and", "August", "'s", "near-record", "deficits", "."], ["NN", "IN", "DT", "NN", "VBZ", "RB", "VBN", "TO", "VB", "DT", "JJ", "NN", "IN", "NN", "NNS", "IN", "NNP", ",", "JJ", "IN", "NN", "NN", ",", "VB", "TO", "VB", "DT", "JJ", "NN", "IN", "NNP", "CC", "NNP", "POS", "JJ", "NNS", "."], ["B-NP", "B-PP", "B-NP", "I-NP", "B-VP", "I-VP", "I-VP", "I-VP", "I-VP", "B-NP", "I-NP", "I-NP", "B-SBAR", "B-NP", "I-NP", "B-PP", "B-NP", "O", "B-ADJP", "B-PP", "B-NP", "B-NP", "O", "B-VP", "I-VP", "I-VP", "B-NP", "I-NP", "I-NP", "B-PP", "B-NP", "I-NP", "I-NP", "B-NP", "I-NP", "I-NP", "O"]]} {"dataset_name": "CoNLL2000Chunking", "split": "test", "NUM_LINES": 2012, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": [["Rockwell", "International", "Corp.", "'s", "Tulsa", "unit", "said", "it", "signed", "a", "tentative", "agreement", "extending", "its", "contract", "with", "Boeing", "Co.", "to", "provide", "structural", "parts", "for", "Boeing", "'s", "747", "jetliners", "."], ["NNP", "NNP", "NNP", "POS", "NNP", "NN", "VBD", "PRP", "VBD", "DT", "JJ", "NN", "VBG", "PRP$", "NN", "IN", "NNP", "NNP", "TO", "VB", "JJ", "NNS", "IN", "NNP", "POS", "CD", "NNS", "."], ["B-NP", "I-NP", "I-NP", "B-NP", "I-NP", "I-NP", "B-VP", "B-NP", "B-VP", "B-NP", "I-NP", "I-NP", "B-VP", "B-NP", "I-NP", "B-PP", "B-NP", "I-NP", "B-VP", "I-VP", "B-NP", "I-NP", "B-PP", "B-NP", "B-NP", "I-NP", "I-NP", "O"]]} -{"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Zwei junge wei\u00dfe M\u00e4nner sind im Freien in der N\u00e4he vieler B\u00fcsche.\n", "Two young, White males are outside near many bushes.\n"]} -{"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Eine Gruppe von M\u00e4nnern l\u00e4dt Baumwolle auf einen Lastwagen\n", "A group of men are loading cotton onto a truck\n"]} -{"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "ff2c0fcb4893a13bd73414306bc250ae", "08dc7cd4a662f31718412de95ca9bfe3", "6a8d5c87f6ae19e3d35681aa6fd16571", "005396bac545d880abe6f00bbb7dbbb4", "cb09af7d2b501f9112f2d6a59fa1360d", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "a7b684e0edbef1d4a23660c8e8e743fd", "4995d10954a804d3cdfd907b9fd093e8", "a152878809942757a55ce087073486b8", "d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "ac0c72653c140dd96707212a1baa4278", "eec05227daba4bb8f3f8f25b1cb335f4", "6dfb42cae4e4fd9a3c40e62ff5398a55", "9318fa08c0c0b96114eadb10eb2fc633", "ece8cec6b87bf00dd12607f3062dae4c", "088ec0765fa213a0eb937a62adfd4996", "9a7e7b2dcc33135a32cd621c3b37d2d8", "5f7c8d0be0ac739856b47d32a9434998", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "713ed720636622a54546d5f14f88b00f", "62f36422bfab90fb42a560546b704009", "cbf5bfc2147706f228d288e1b18bf4af", "540da4566bb6dd35fdbc720218b742b7", "bdfe4222f4692ccaa1e3389460f0890e", "613eb4a3f0c2b13f0871ced946851b0e", "0e1ee2b4145795bd180b193424db204b", "d848fe0ae8b9447209fb49c5c31cb3d2", "1cff688d1aadef7fdb22e9ad27d6fd2c", "abc13b4042f4fef1cdff6de3b6c53b71", "3e10289959d0059952511c31df3c7550", "b26486ede1d4436d5acf6e38c65bb44d", "df57faf5f00d434d2559c021ef55f1aa", "16165248083beacebfe18866d5f4f0ae", "9077a5127480cc799116384de501bd70", "7180780822d4b600eb81c1ccf171c230", "c1f697c3b6dfb7305349db34e26b45fc", "8edb43c90cae66ec762748a968089b99", "acb5ea26a577ceccfae6337181c31716", "873a377a348713d3ab84db1fb57cdede", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Ein Mann mit einem orangefarbenen Hut, der etwas anstarrt.\n", "A man in an orange hat starring at something.\n"]} +{"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": ["d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "62f36422bfab90fb42a560546b704009", "540da4566bb6dd35fdbc720218b742b7", "613eb4a3f0c2b13f0871ced946851b0e", "d848fe0ae8b9447209fb49c5c31cb3d2", "abc13b4042f4fef1cdff6de3b6c53b71", "cbf5bfc2147706f228d288e1b18bf4af", "bdfe4222f4692ccaa1e3389460f0890e", "0e1ee2b4145795bd180b193424db204b", "1cff688d1aadef7fdb22e9ad27d6fd2c", "3e10289959d0059952511c31df3c7550"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz"], "first_line": ["Zwei junge wei\u00dfe M\u00e4nner sind im Freien in der N\u00e4he vieler B\u00fcsche.\n", "Two young, White males are outside near many bushes.\n"]} +{"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": ["83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "b26486ede1d4436d5acf6e38c65bb44d", "16165248083beacebfe18866d5f4f0ae", "7180780822d4b600eb81c1ccf171c230", "8edb43c90cae66ec762748a968089b99", "873a377a348713d3ab84db1fb57cdede", "df57faf5f00d434d2559c021ef55f1aa", "9077a5127480cc799116384de501bd70", "c1f697c3b6dfb7305349db34e26b45fc", "acb5ea26a577ceccfae6337181c31716", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Eine Gruppe von M\u00e4nnern l\u00e4dt Baumwolle auf einen Lastwagen\n", "A group of men are loading cotton onto a truck\n"]} +{"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "6a8d5c87f6ae19e3d35681aa6fd16571", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "ff2c0fcb4893a13bd73414306bc250ae", "005396bac545d880abe6f00bbb7dbbb4", "a7b684e0edbef1d4a23660c8e8e743fd", "a152878809942757a55ce087073486b8", "08dc7cd4a662f31718412de95ca9bfe3", "cb09af7d2b501f9112f2d6a59fa1360d", "4995d10954a804d3cdfd907b9fd093e8", "ac0c72653c140dd96707212a1baa4278", "6dfb42cae4e4fd9a3c40e62ff5398a55", "ece8cec6b87bf00dd12607f3062dae4c", "9a7e7b2dcc33135a32cd621c3b37d2d8", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "eec05227daba4bb8f3f8f25b1cb335f4", "9318fa08c0c0b96114eadb10eb2fc633", "088ec0765fa213a0eb937a62adfd4996", "5f7c8d0be0ac739856b47d32a9434998", "713ed720636622a54546d5f14f88b00f"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz"], "first_line": ["Ein Mann mit einem orangefarbenen Hut, der etwas anstarrt.\n", "A man in an orange hat starring at something.\n"]} {"dataset_name": "IWSLT2016", "split": "train", "NUM_LINES": 196884, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["David Gallo: Das ist Bill Lange. Ich bin Dave Gallo.\n", "David Gallo: This is Bill Lange. I'm Dave Gallo.\n"]} {"dataset_name": "IWSLT2016", "split": "valid", "NUM_LINES": 993, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich 11 Jahre alt war, wurde ich eines Morgens von den Kl\u00e4ngen heller Freude geweckt.\n", "When I was 11, I remember waking up one morning to the sound of joy in my house.\n"]} {"dataset_name": "IWSLT2016", "split": "test", "NUM_LINES": 1305, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich in meinen 20ern war, hatte ich meine erste Psychotherapie-Patientin.\n", "When I was in my 20s, I saw my very first psychotherapy client.\n"]} {"dataset_name": "IWSLT2017", "split": "train", "NUM_LINES": 206112, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Vielen Dank, Chris.\n", "Thank you so much, Chris.\n"]} -{"dataset_name": "IWSLT2017", "split": "valid", "NUM_LINES": 888, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Letztes Jahr habe ich diese beiden Folien gezeigt, um zu veranschaulichen, dass die arktische Eiskappe, die für annähernd drei Millionen Jahre die Grösse der unteren 48 Staaten hatte, um 40 Prozent geschrumpft ist.\n","Last year I showed these two slides so that demonstrate that the arctic ice cap, which for most of the last three million years has been the size of the lower 48 states, has shrunk by 40 percent.\n"]} +{"dataset_name": "IWSLT2017", "split": "valid", "NUM_LINES": 888, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Letztes Jahr habe ich diese beiden Folien gezeigt, um zu veranschaulichen, dass die arktische Eiskappe, die f\u00fcr ann\u00e4hernd drei Millionen Jahre die Gr\u00f6sse der unteren 48 Staaten hatte, um 40 Prozent geschrumpft ist.\n","Last year I showed these two slides so that demonstrate that the arctic ice cap, which for most of the last three million years has been the size of the lower 48 states, has shrunk by 40 percent.\n"]} {"dataset_name": "IWSLT2017", "split": "test", "NUM_LINES": 1568, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Vor einigen Jahren, hier bei TED, stellte Peter Skillman einen Design-Wettbewerb namens \"Die Marshmallow-Herausforderung\" vor.\n","Several years ago here at TED, Peter Skillman introduced a design challenge called the marshmallow challenge.\n"]} {"dataset_name": "WMT14", "split": "train", "NUM_LINES": 4500966, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Wiederaufnahme der Sitzungsperiode\n", "Res@@ um@@ ption of the session\n"]} {"dataset_name": "WMT14", "split": "valid", "NUM_LINES": 3000, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Eine repub@@ li@@ kanische Strategie , um der Wieder@@ wahl von Obama entgegen@@ zu@@ treten\n", "A Republic@@ an strategy to counter the re-@@ election of Obama\n"]} @@ -42,7 +42,6 @@ {"dataset_name": "PennTreebank", "split": "train", "NUM_LINES": 42068, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " aer banknote berlitz calloway centrust cluett fromstein gitano guterman hydro-quebec ipo kia memotec mlx nahb punts rake regatta rubens sim snack-food ssangyong swapo wachter \n"} {"dataset_name": "PennTreebank", "split": "valid", "NUM_LINES": 3370, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " consumers may want to move their telephones a little closer to the tv set \n"} {"dataset_name": "PennTreebank", "split": "test", "NUM_LINES": 3761, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " no it was n't black monday \n"} -{"dataset_name": "WMTNewsCrawl", "split": "train", "NUM_LINES": 17676013, "MD5": "c70da2ba79db33fb0fc9119cbad16260", "URL": "http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz", "first_line": "I Need to Vent.\n"} {"dataset_name": "SQuAD1", "split": "train", "NUM_LINES": 87599, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": ["Architecturally, the school has a Catholic character. Atop the Main Building's gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend \"Venite Ad Me Omnes\". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.", "To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?", ["Saint Bernadette Soubirous"], [515]]} {"dataset_name": "SQuAD1", "split": "dev", "NUM_LINES": 10570, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": ["Super Bowl 50 was an American football game to determine the champion of the National Football League (NFL) for the 2015 season. The American Football Conference (AFC) champion Denver Broncos defeated the National Football Conference (NFC) champion Carolina Panthers 24\u201310 to earn their third Super Bowl title. The game was played on February 7, 2016, at Levi's Stadium in the San Francisco Bay Area at Santa Clara, California. As this was the 50th Super Bowl, the league emphasized the \"golden anniversary\" with various gold-themed initiatives, as well as temporarily suspending the tradition of naming each Super Bowl game with Roman numerals (under which the game would have been known as \"Super Bowl L\"), so that the logo could prominently feature the Arabic numerals 50.", "Which NFL team represented the AFC at Super Bowl 50?", ["Denver Broncos", "Denver Broncos", "Denver Broncos"], [177, 177, 177]]} {"dataset_name": "SQuAD2", "split": "train", "NUM_LINES": 130319, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": ["Beyonc\u00e9 Giselle Knowles-Carter (/bi\u02d0\u02c8j\u0252nse\u026a/ bee-YON-say) (born September 4, 1981) is an American singer, songwriter, record producer and actress. Born and raised in Houston, Texas, she performed in various singing and dancing competitions as a child, and rose to fame in the late 1990s as lead singer of R&B girl-group Destiny's Child. Managed by her father, Mathew Knowles, the group became one of the world's best-selling girl groups of all time. Their hiatus saw the release of Beyonc\u00e9's debut album, Dangerously in Love (2003), which established her as a solo artist worldwide, earned five Grammy Awards and featured the Billboard Hot 100 number-one singles \"Crazy in Love\" and \"Baby Boy\".", "When did Beyonce start becoming popular?", ["in the late 1990s"], [269]]} diff --git a/test/common/cache_utils.py b/test/common/cache_utils.py new file mode 100644 index 0000000000..982ebcfadd --- /dev/null +++ b/test/common/cache_utils.py @@ -0,0 +1,46 @@ +import os +import json +import torchtext +from .parameterized_utils import load_params + +CACHE_STATUS_FILE = '.data/cache_status_file.json' + + +def check_cache_status(): + assert os.path.exists(CACHE_STATUS_FILE), "Cache status file does not exists" + with open(CACHE_STATUS_FILE, 'r') as f: + cache_status = json.load(f) + for dataset_name in cache_status: + for split in cache_status[dataset_name]: + if cache_status[dataset_name][split]['status'] == "fail": + raise FileNotFoundError("Failing all raw dataset unit tests as cache is missing atleast one raw dataset") + + +def generate_data_cache(): + # cache already created, nothing to do + if os.path.exists(CACHE_STATUS_FILE): + return + + raw_data_info = load_params('raw_datasets.json') + cache_status = {} + for info in raw_data_info: + info = info.args[0] + dataset_name = info['dataset_name'] + split = info['split'] + if dataset_name not in cache_status: + cache_status[dataset_name] = {} + try: + if dataset_name == "Multi30k" or dataset_name == 'WMT14': + _ = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) + else: + _ = torchtext.datasets.DATASETS[dataset_name](split=split) + cache_status[dataset_name][split] = {'status': 'success', 'reason': 'No exception thrown'} + except Exception as e: + cache_status[dataset_name][split] = {'status': 'fail', 'reason': str(e)} + + with open(CACHE_STATUS_FILE, 'w') as f: + json.dump(cache_status, f) + + +if __name__ == "__main__": + generate_data_cache() diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 93d0df8145..29c4c9581f 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -3,26 +3,12 @@ import os import torch import torchtext -import unittest from torchtext.legacy import data from parameterized import parameterized from ..common.torchtext_test_case import TorchtextTestCase from ..common.parameterized_utils import load_params from ..common.assets import conditional_remove - -GOOGLE_DRIVE_BASED_DATASETS = [ - 'AmazonReviewFull', - 'AmazonReviewPolarity', - 'DBpedia', - 'IMDB', - 'IWSLT2016', - 'IWSLT2017', - 'SogouNews', - 'WMT14', - 'YahooAnswers', - 'YelpReviewFull', - 'YelpReviewPolarity' -] +from ..common.cache_utils import check_cache_status def _raw_text_custom_name_func(testcase_func, param_num, param): @@ -35,6 +21,10 @@ def _raw_text_custom_name_func(testcase_func, param_num, param): class TestDataset(TorchtextTestCase): + @classmethod + def setUpClass(cls): + check_cache_status() + def _helper_test_func(self, length, target_length, results, target_results): self.assertEqual(length, target_length) if isinstance(target_results, list): @@ -168,21 +158,39 @@ def test_raw_ag_news(self): @parameterized.expand( load_params('raw_datasets.json'), name_func=_raw_text_custom_name_func) - def test_raw_text_classification(self, info): + def test_raw_text_name_property(self, info): dataset_name = info['dataset_name'] - if dataset_name in GOOGLE_DRIVE_BASED_DATASETS: - return + split = info['split'] - # Currently disabled due to incredibly slow download - if dataset_name == "WMTNewsCrawl": - return + if dataset_name == "Multi30k" or dataset_name == 'WMT14': + data_iter = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) + else: + data_iter = torchtext.datasets.DATASETS[dataset_name](split=split) + + self.assertEqual(str(data_iter), dataset_name) + + @parameterized.expand( + load_params('raw_datasets.json'), + name_func=_raw_text_custom_name_func) + def test_raw_text_classification(self, info): + dataset_name = info['dataset_name'] split = info['split'] - data_iter = torchtext.datasets.DATASETS[dataset_name](split=split) + + if dataset_name == "Multi30k" or dataset_name == 'WMT14': + data_iter = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) + else: + data_iter = torchtext.datasets.DATASETS[dataset_name](split=split) self.assertEqual(len(data_iter), info['NUM_LINES']) self.assertEqual(next(data_iter), info['first_line']) if dataset_name == "AG_NEWS": self.assertEqual(torchtext.datasets.URLS[dataset_name][split], info['URL']) self.assertEqual(torchtext.datasets.MD5[dataset_name][split], info['MD5']) + elif dataset_name == "Multi30k": + self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name][split], info['URL']) + self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name][split], info['MD5']) + elif dataset_name == "WMT14": + self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name], info['URL']) + self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name], info['MD5']) else: self.assertEqual(torchtext.datasets.URLS[dataset_name], info['URL']) self.assertEqual(torchtext.datasets.MD5[dataset_name], info['MD5']) @@ -190,8 +198,6 @@ def test_raw_text_classification(self, info): @parameterized.expand(list(sorted(torchtext.datasets.DATASETS.keys()))) def test_raw_datasets_split_argument(self, dataset_name): - if dataset_name in GOOGLE_DRIVE_BASED_DATASETS: - return if 'statmt' in torchtext.datasets.URLS[dataset_name]: return dataset = torchtext.datasets.DATASETS[dataset_name] @@ -207,8 +213,6 @@ def test_raw_datasets_split_argument(self, dataset_name): @parameterized.expand(["AG_NEWS", "WikiText2", "IMDB"]) def test_datasets_split_argument(self, dataset_name): - if dataset_name in GOOGLE_DRIVE_BASED_DATASETS: - return dataset = torchtext.experimental.datasets.DATASETS[dataset_name] train1 = dataset(split='train') train2, = dataset(split=('train',)) @@ -257,7 +261,6 @@ def test_imdb(self): self._helper_test_func(len(test_iter), 25000, next(test_iter)[1][:25], 'I love sci-fi and am will') del train_iter, test_iter - @unittest.skip("Depend on Google drive download") def test_iwslt2017(self): from torchtext.experimental.datasets import IWSLT2017 @@ -284,7 +287,6 @@ def assert_nth_pair_is_equal(n, expected_sentence_pair): 'Frau', 'Tipper', '.', '"', '\n'], ['And', 'she', 'said', '"', 'Yes', ',', 'that', "'s", 'former', 'Vice', 'President', 'Al', 'Gore', 'and', 'his', 'wife', ',', 'Tipper', '.', '"', '\n'])) - @unittest.skip("Depend on Google drive download") def test_iwslt2016(self): from torchtext.experimental.datasets import IWSLT2016 @@ -355,7 +357,7 @@ def test_multi30k(self): [18, 24, 1168, 807, 16, 56, 83, 335, 1338]) # Add test for the subset of the standard datasets - train_iter, valid_iter = torchtext.datasets.Multi30k(split=('train', 'valid')) + train_iter, valid_iter = torchtext.experimental.datasets.raw.Multi30k(split=('train', 'valid')) self._helper_test_func(len(train_iter), 29000, ' '.join(next(train_iter)), ' '.join(['Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n', 'Two young, White males are outside near many bushes.\n'])) diff --git a/test/legacy/data/test_batch.py b/test/legacy/data/test_batch.py index ca90adf47b..cf4a1f76a4 100644 --- a/test/legacy/data/test_batch.py +++ b/test/legacy/data/test_batch.py @@ -37,7 +37,7 @@ def test_batch_iter(self): batch = next(iter(itr)) (x1, x2), y = batch x = (x1, x2)[fld_order.index("float")] - self.assertEquals(y.data[0], 1) - self.assertEquals(y.data[1], 12) + self.assertEqual(y.data[0], 1) + self.assertEqual(y.data[1], 12) self.assertAlmostEqual(x.data[0], 0.1, places=4) self.assertAlmostEqual(x.data[1], 0.5, places=4) diff --git a/test/legacy/data/test_dataset.py b/test/legacy/data/test_dataset.py index 603a9e3857..4f5a05c67e 100644 --- a/test/legacy/data/test_dataset.py +++ b/test/legacy/data/test_dataset.py @@ -120,8 +120,8 @@ def test_input_with_newlines_in_text(self): path=self.test_newline_dataset_path, format=format_, fields=fields) # if the newline is not parsed correctly, this should raise an error for example in dataset: - self.assert_(hasattr(example, "text")) - self.assert_(hasattr(example, "label")) + self.assertTrue(hasattr(example, "text")) + self.assertTrue(hasattr(example, "label")) def test_csv_file_with_header(self): example_with_header = [("text", "label"), diff --git a/torchtext/data/datasets_utils.py b/torchtext/data/datasets_utils.py index 637bb737bd..1baef44e70 100644 --- a/torchtext/data/datasets_utils.py +++ b/torchtext/data/datasets_utils.py @@ -1,18 +1,97 @@ import functools import inspect import os +import io +import json import torch -from torchtext.utils import validate_file -from torchtext.utils import download_from_url -from torchtext.utils import extract_archive - +from torchtext.utils import ( + validate_file, + download_from_url, + extract_archive, + unicode_csv_reader, +) +import codecs +import xml.etree.ElementTree as ET """ These functions and classes are meant solely for use in torchtext.datasets and not for public consumption yet. """ -def check_default_set(split, target_select, dataset_name): +def _clean_xml_file(f_xml): + f_txt = os.path.splitext(f_xml)[0] + with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: + root = ET.parse(f_xml).getroot()[0] + for doc in root.findall('doc'): + for e in doc.findall('seg'): + fd_txt.write(e.text.strip() + '\n') + + +def _clean_tags_file(f_orig): + xml_tags = [ + ' 0: + yield columns + + +def _read_text_iterator(path): + with io.open(path, encoding="utf8") as f: + for row in f: + yield row + + +def _create_data_from_csv(data_path): + with io.open(data_path, encoding="utf8") as f: + reader = unicode_csv_reader(f) + for row in reader: + yield int(row[0]), ' '.join(row[1:]) + + +def _check_default_set(split, target_select, dataset_name): # Check whether given object split is either a tuple of strings or string # and represents a valid selection of options given by the tuple of strings # target_select. @@ -28,7 +107,7 @@ def check_default_set(split, target_select, dataset_name): return split -def wrap_datasets(datasets, split): +def _wrap_datasets(datasets, split): # Wrap return value for _setup_datasets functions to support singular values instead # of tuples when split is a string. if isinstance(split, str): @@ -38,7 +117,7 @@ def wrap_datasets(datasets, split): return datasets -def find_match(match, lst): +def _find_match(match, lst): """ Searches list of strings and returns first entry that partially or fully contains the given string match. @@ -49,7 +128,7 @@ def find_match(match, lst): return None -def dataset_docstring_header(fn, num_lines=None): +def _dataset_docstring_header(fn, num_lines=None, num_classes=None): """ Returns docstring for a dataset based on function arguments. @@ -77,6 +156,10 @@ def dataset_docstring_header(fn, num_lines=None): for k, v in num_lines.items(): header_s += "\n {}: {}\n".format(k, v) + if num_classes is not None: + header_s += "\n\nNumber of classes" + header_s += "\n {}\n".format(num_classes) + args_s = "\nArgs:" args_s += "\n root: Directory where the datasets are saved." args_s += "\n Default: .data" @@ -92,10 +175,10 @@ def dataset_docstring_header(fn, num_lines=None): return "\n".join([header_s, args_s]) + "\n" -def add_docstring_header(docstring=None, num_lines=None): +def _add_docstring_header(docstring=None, num_lines=None, num_classes=None): def docstring_decorator(fn): old_doc = fn.__doc__ - fn.__doc__ = dataset_docstring_header(fn, num_lines) + fn.__doc__ = _dataset_docstring_header(fn, num_lines, num_classes) if docstring is not None: fn.__doc__ += docstring if old_doc is not None: @@ -104,7 +187,7 @@ def docstring_decorator(fn): return docstring_decorator -def _wrap_split_argument(fn, splits): +def _wrap_split_argument_with_fn(fn, splits): """ Wraps given function of specific signature to extend behavior of split to support individual strings. The given function is expected to have a split @@ -116,7 +199,6 @@ def _wrap_split_argument(fn, splits): train = AG_NEWS(split='train') train, valid = AG_NEWS(split=('train', 'valid')) """ - argspec = inspect.getfullargspec(fn) if not (argspec.args[0] == "root" and argspec.args[1] == "split" and @@ -130,9 +212,9 @@ def _wrap_split_argument(fn, splits): @functools.wraps(fn) def new_fn(root='.data', split=splits, **kwargs): result = [] - for item in check_default_set(split, splits, fn.__name__): + for item in _check_default_set(split, splits, fn.__name__): result.append(fn(root, item, **kwargs)) - return wrap_datasets(tuple(result), split) + return _wrap_datasets(tuple(result), split) new_sig = inspect.signature(new_fn) new_sig_params = new_sig.parameters @@ -146,14 +228,38 @@ def new_fn(root='.data', split=splits, **kwargs): return new_fn -def wrap_split_argument(splits): +def _wrap_split_argument(splits): def new_fn(fn): - return _wrap_split_argument(fn, splits) + return _wrap_split_argument_with_fn(fn, splits) return new_fn -def download_extract_validate(root, url, url_md5, downloaded_file, extracted_file, extracted_file_md5, - hash_type="sha256"): +def _create_dataset_directory(dataset_name): + def decorator(func): + argspec = inspect.getfullargspec(func) + if not (argspec.args[0] == "root" and + argspec.args[1] == "split" and + argspec.varargs is None and + argspec.varkw is None and + len(argspec.kwonlyargs) == 0 and + len(argspec.annotations) == 0 + ): + raise ValueError("Internal Error: Given function {} did not adhere to standard signature.".format(fn)) + + @functools.wraps(func) + def wrapper(root='.data', *args, **kwargs): + new_root = os.path.join(root, dataset_name) + if not os.path.exists(new_root): + os.makedirs(new_root) + return func(root=new_root, *args, **kwargs) + + return wrapper + + return decorator + + +def _download_extract_validate(root, url, url_md5, downloaded_file, extracted_file, extracted_file_md5, + hash_type="sha256"): root = os.path.abspath(root) downloaded_file = os.path.abspath(downloaded_file) extracted_file = os.path.abspath(extracted_file) @@ -165,18 +271,19 @@ def download_extract_validate(root, url, url_md5, downloaded_file, extracted_fil dataset_tar = download_from_url(url, path=os.path.join(root, downloaded_file), hash_value=url_md5, hash_type=hash_type) extracted_files = extract_archive(dataset_tar) - assert extracted_file == find_match(extracted_file, extracted_files) + assert os.path.exists(extracted_file), "extracted_file [{}] was not found in the archive [{}]".format(extracted_file, extracted_files) + return extracted_file -class RawTextIterableDataset(torch.utils.data.IterableDataset): +class _RawTextIterableDataset(torch.utils.data.IterableDataset): """Defines an abstraction for raw text iterable datasets. """ def __init__(self, description, full_num_lines, iterator): - """Initiate text-classification dataset. + """Initiate the dataset abstraction. """ - super(RawTextIterableDataset, self).__init__() + super(_RawTextIterableDataset, self).__init__() self.description = description self.full_num_lines = full_num_lines self._iterator = iterator diff --git a/torchtext/datasets/__init__.py b/torchtext/datasets/__init__.py index a53c273aee..77838b441d 100644 --- a/torchtext/datasets/__init__.py +++ b/torchtext/datasets/__init__.py @@ -8,7 +8,6 @@ from .imdb import IMDB from .iwslt2016 import IWSLT2016 from .iwslt2017 import IWSLT2017 -from .multi30k import Multi30k from .penntreebank import PennTreebank from .sogounews import SogouNews from .squad1 import SQuAD1 @@ -16,8 +15,6 @@ from .udpos import UDPOS from .wikitext103 import WikiText103 from .wikitext2 import WikiText2 -from .wmt14 import WMT14 -from .wmtnewscrawl import WMTNewsCrawl from .yahooanswers import YahooAnswers from .yelpreviewfull import YelpReviewFull from .yelpreviewpolarity import YelpReviewPolarity @@ -32,14 +29,11 @@ 'IMDB': IMDB, 'IWSLT2016': IWSLT2016, 'IWSLT2017': IWSLT2017, - 'Multi30k': Multi30k, 'PennTreebank': PennTreebank, 'SQuAD1': SQuAD1, 'SQuAD2': SQuAD2, 'SogouNews': SogouNews, 'UDPOS': UDPOS, - 'WMT14': WMT14, - 'WMTNewsCrawl': WMTNewsCrawl, 'WikiText103': WikiText103, 'WikiText2': WikiText2, 'YahooAnswers': YahooAnswers, diff --git a/torchtext/datasets/ag_news.py b/torchtext/datasets/ag_news.py index e108ebcc35..136a0069c6 100644 --- a/torchtext/datasets/ag_news.py +++ b/torchtext/datasets/ag_news.py @@ -1,9 +1,14 @@ -from torchtext.utils import download_from_url, unicode_csv_reader -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header +from torchtext.utils import ( + download_from_url, +) +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _create_dataset_directory, + _create_data_from_csv, +) import os -import io URL = { 'train': "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", @@ -20,19 +25,16 @@ 'test': 7600, } +DATASET_NAME = "AG_NEWS" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'test')) -def AG_NEWS(root, split): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) +@_add_docstring_header(num_lines=NUM_LINES, num_classes=4) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'test')) +def AG_NEWS(root, split): path = download_from_url(URL[split], root=root, path=os.path.join(root, split + ".csv"), hash_value=MD5[split], hash_type='md5') - return RawTextIterableDataset("AG_NEWS", NUM_LINES[split], - _create_data_from_csv(path)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/amazonreviewfull.py b/torchtext/datasets/amazonreviewfull.py index 70395fd267..c90237976b 100644 --- a/torchtext/datasets/amazonreviewfull.py +++ b/torchtext/datasets/amazonreviewfull.py @@ -1,9 +1,12 @@ -from torchtext.utils import unicode_csv_reader -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import download_extract_validate -import io +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _download_extract_validate, + _create_dataset_directory, + _create_data_from_csv, +) +import os import logging URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA' @@ -18,8 +21,8 @@ _PATH = 'amazon_review_full_csv.tar.gz' _EXTRACTED_FILES = { - 'train': 'amazon_review_full_csv/train.csv', - 'test': 'amazon_review_full_csv/test.csv' + 'train': f'{os.sep}'.join(['amazon_review_full_csv', 'train.csv']), + 'test': f'{os.sep}'.join(['amazon_review_full_csv', 'test.csv']), } _EXTRACTED_FILES_MD5 = { @@ -27,18 +30,15 @@ 'test': "0f1e78ab60f625f2a30eab6810ef987c" } +DATASET_NAME = "AmazonReviewFull" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES, num_classes=5) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'test')) def AmazonReviewFull(root, split): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - - path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[split], - _EXTRACTED_FILES_MD5[split], hash_type="md5") + path = _download_extract_validate(root, URL, MD5, os.path.join(root, _PATH), os.path.join(root, _EXTRACTED_FILES[split]), + _EXTRACTED_FILES_MD5[split], hash_type="md5") logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset("AmazonReviewFull", NUM_LINES[split], - _create_data_from_csv(path)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/amazonreviewpolarity.py b/torchtext/datasets/amazonreviewpolarity.py index 49555b5d9c..c143677fb7 100644 --- a/torchtext/datasets/amazonreviewpolarity.py +++ b/torchtext/datasets/amazonreviewpolarity.py @@ -1,9 +1,12 @@ -from torchtext.utils import unicode_csv_reader -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import download_extract_validate -import io +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _download_extract_validate, + _create_dataset_directory, + _create_data_from_csv, +) +import os import logging URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM' @@ -18,8 +21,8 @@ _PATH = 'amazon_review_polarity_csv.tar.gz' _EXTRACTED_FILES = { - 'train': 'amazon_review_polarity_csv/train.csv', - 'test': 'amazon_review_polarity_csv/test.csv' + 'train': f'{os.sep}'.join(['amazon_review_polarity_csv', 'train.csv']), + 'test': f'{os.sep}'.join(['amazon_review_polarity_csv', 'test.csv']), } _EXTRACTED_FILES_MD5 = { @@ -27,17 +30,15 @@ 'test': "f4c8bded2ecbde5f996b675db6228f16" } +DATASET_NAME = "AmazonReviewPolarity" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES, num_classes=2) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'test')) def AmazonReviewPolarity(root, split): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[split], - _EXTRACTED_FILES_MD5[split], hash_type="md5") + path = _download_extract_validate(root, URL, MD5, os.path.join(root, _PATH), os.path.join(root, _EXTRACTED_FILES[split]), + _EXTRACTED_FILES_MD5[split], hash_type="md5") logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset("AmazonReviewPolarity", NUM_LINES[split], - _create_data_from_csv(path)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/conll2000chunking.py b/torchtext/datasets/conll2000chunking.py index 71680a5a67..3816c1ddb3 100644 --- a/torchtext/datasets/conll2000chunking.py +++ b/torchtext/datasets/conll2000chunking.py @@ -1,7 +1,11 @@ -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import download_extract_validate +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _download_extract_validate, + _create_dataset_directory, + _create_data_from_iob, +) import os import logging @@ -31,32 +35,18 @@ } -def _create_data_from_iob(data_path, separator): - with open(data_path, encoding="utf-8") as input_file: - columns = [] - for line in input_file: - line = line.strip() - if line == "": - if columns: - yield columns - columns = [] - else: - for i, column in enumerate(line.split(separator)): - if len(columns) < i + 1: - columns.append([]) - columns[i].append(column) - if len(columns) > 0: - yield columns - - -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'test')) +DATASET_NAME = "CoNLL2000Chunking" + + +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'test')) def CoNLL2000Chunking(root, split): # Create a dataset specific subfolder to deal with generic download filenames root = os.path.join(root, 'conll2000chunking') path = os.path.join(root, split + ".txt.gz") - data_filename = download_extract_validate(root, URL[split], MD5[split], path, os.path.join(root, _EXTRACTED_FILES[split]), - _EXTRACTED_FILES_MD5[split], hash_type="md5") + data_filename = _download_extract_validate(root, URL[split], MD5[split], path, os.path.join(root, _EXTRACTED_FILES[split]), + _EXTRACTED_FILES_MD5[split], hash_type="md5") logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset("CoNLL2000Chunking", NUM_LINES[split], - _create_data_from_iob(data_filename, " ")) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_iob(data_filename, " ")) diff --git a/torchtext/datasets/dbpedia.py b/torchtext/datasets/dbpedia.py index 16be98897f..08f506451f 100644 --- a/torchtext/datasets/dbpedia.py +++ b/torchtext/datasets/dbpedia.py @@ -1,10 +1,16 @@ -from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import find_match +from torchtext.utils import ( + download_from_url, + extract_archive, +) +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _find_match, + _create_dataset_directory, + _create_data_from_csv, +) import os -import io URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k' @@ -17,20 +23,18 @@ _PATH = 'dbpedia_csv.tar.gz' +DATASET_NAME = "DBpedia" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES, num_classes=14) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'test')) def DBpedia(root, split): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) dataset_tar = download_from_url(URL, root=root, path=os.path.join(root, _PATH), hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - path = find_match(split + '.csv', extracted_files) - return RawTextIterableDataset("DBpedia", NUM_LINES[split], - _create_data_from_csv(path)) + path = _find_match(split + '.csv', extracted_files) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/enwik9.py b/torchtext/datasets/enwik9.py index cd3de45723..7ec4060573 100644 --- a/torchtext/datasets/enwik9.py +++ b/torchtext/datasets/enwik9.py @@ -1,9 +1,15 @@ import logging -from torchtext.utils import download_from_url, extract_archive -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -import io +from torchtext.utils import ( + download_from_url, + extract_archive, +) +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _create_dataset_directory, + _read_text_iterator, +) URL = 'http://mattmahoney.net/dc/enwik9.zip' @@ -13,13 +19,16 @@ 'train': 13147026 } +DATASET_NAME = "EnWik9" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train',)) + +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train',)) def EnWik9(root, split): dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) path = extracted_files[0] logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset('EnWik9', - NUM_LINES[split], iter(io.open(path, encoding="utf8"))) + return _RawTextIterableDataset(DATASET_NAME, + NUM_LINES[split], _read_text_iterator(path)) diff --git a/torchtext/datasets/imdb.py b/torchtext/datasets/imdb.py index 42e843094f..802fec28b5 100644 --- a/torchtext/datasets/imdb.py +++ b/torchtext/datasets/imdb.py @@ -1,7 +1,8 @@ from torchtext.utils import download_from_url, extract_archive -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header +from torchtext.data.datasets_utils import _RawTextIterableDataset +from torchtext.data.datasets_utils import _wrap_split_argument +from torchtext.data.datasets_utils import _add_docstring_header +from torchtext.data.datasets_utils import _create_dataset_directory import io URL = 'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz' @@ -15,9 +16,12 @@ _PATH = 'aclImdb_v1.tar.gz' +DATASET_NAME = "IMDB" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES, num_classes=2) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'test')) def IMDB(root, split): def generate_imdb_data(key, extracted_files): for fname in extracted_files: @@ -31,4 +35,4 @@ def generate_imdb_data(key, extracted_files): hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) iterator = generate_imdb_data(split, extracted_files) - return RawTextIterableDataset("IMDB", NUM_LINES[split], iterator) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], iterator) diff --git a/torchtext/datasets/iwslt2016.py b/torchtext/datasets/iwslt2016.py index 3d1c598b62..6083502079 100644 --- a/torchtext/datasets/iwslt2016.py +++ b/torchtext/datasets/iwslt2016.py @@ -1,10 +1,13 @@ import os -import io -import codecs -import xml.etree.ElementTree as ET from torchtext.utils import (download_from_url, extract_archive) -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _clean_xml_file, + _clean_tags_file, + _read_text_iterator, +) +from torchtext.data.datasets_utils import _create_dataset_directory SUPPORTED_DATASETS = { @@ -29,134 +32,84 @@ NUM_LINES = { 'train': { 'train': { - ('en', 'ar'): 224126, - ('en', 'de'): 196884, - ('en', 'fr'): 220400, - ('en', 'cs'): 114390, ('ar', 'en'): 224126, - ('fr', 'en'): 220400, ('de', 'en'): 196884, + ('en', 'fr'): 220400, ('cs', 'en'): 114390 } }, 'valid': { 'dev2010': { - ('en', 'ar'): 887, - ('en', 'de'): 887, - ('en', 'fr'): 887, - ('en', 'cs'): 480, ('ar', 'en'): 887, - ('fr', 'en'): 887, ('de', 'en'): 887, + ('en', 'fr'): 887, ('cs', 'en'): 480 }, 'tst2010': { - ('en', 'ar'): 1569, - ('en', 'de'): 1565, - ('en', 'fr'): 1664, - ('en', 'cs'): 1511, ('ar', 'en'): 1569, - ('fr', 'en'): 1664, ('de', 'en'): 1565, + ('en', 'fr'): 1664, ('cs', 'en'): 1511 }, 'tst2011': { - ('en', 'ar'): 1199, - ('en', 'de'): 1433, - ('en', 'fr'): 818, - ('en', 'cs'): 1013, ('ar', 'en'): 1199, - ('fr', 'en'): 818, ('de', 'en'): 1433, + ('en', 'fr'): 818, ('cs', 'en'): 1013 }, 'tst2012': { - ('en', 'ar'): 1702, - ('en', 'de'): 1700, - ('en', 'fr'): 1124, - ('en', 'cs'): 1385, ('ar', 'en'): 1702, - ('fr', 'en'): 1124, ('de', 'en'): 1700, + ('en', 'fr'): 1124, ('cs', 'en'): 1385 }, 'tst2013': { - ('en', 'ar'): 1169, - ('en', 'de'): 993, - ('en', 'fr'): 1026, - ('en', 'cs'): 1327, ('ar', 'en'): 1169, - ('fr', 'en'): 1026, ('de', 'en'): 993, + ('en', 'fr'): 1026, ('cs', 'en'): 1327 }, 'tst2014': { - ('en', 'ar'): 1107, - ('en', 'de'): 1305, - ('en', 'fr'): 1305, ('ar', 'en'): 1107, - ('fr', 'en'): 1305, - ('de', 'en'): 1305 + ('de', 'en'): 1305, + ('en', 'fr'): 1305 } }, 'test': { 'dev2010': { - ('en', 'ar'): 887, - ('en', 'de'): 887, - ('en', 'fr'): 887, - ('en', 'cs'): 480, ('ar', 'en'): 887, - ('fr', 'en'): 887, ('de', 'en'): 887, + ('en', 'fr'): 887, ('cs', 'en'): 480 }, 'tst2010': { - ('en', 'ar'): 1569, - ('en', 'de'): 1565, - ('en', 'fr'): 1664, - ('en', 'cs'): 1511, ('ar', 'en'): 1569, - ('fr', 'en'): 1664, ('de', 'en'): 1565, + ('en', 'fr'): 1664, ('cs', 'en'): 1511 }, 'tst2011': { - ('en', 'ar'): 1199, - ('en', 'de'): 1433, - ('en', 'fr'): 818, - ('en', 'cs'): 1013, ('ar', 'en'): 1199, - ('fr', 'en'): 818, ('de', 'en'): 1433, + ('en', 'fr'): 818, ('cs', 'en'): 1013 }, 'tst2012': { - ('en', 'ar'): 1702, - ('en', 'de'): 1700, - ('en', 'fr'): 1124, - ('en', 'cs'): 1385, ('ar', 'en'): 1702, - ('fr', 'en'): 1124, ('de', 'en'): 1700, + ('en', 'fr'): 1124, ('cs', 'en'): 1385 }, 'tst2013': { - ('en', 'ar'): 1169, - ('en', 'de'): 993, - ('en', 'fr'): 1026, - ('en', 'cs'): 1327, ('ar', 'en'): 1169, - ('fr', 'en'): 1026, ('de', 'en'): 993, + ('en', 'fr'): 1026, ('cs', 'en'): 1327 }, 'tst2014': { - ('en', 'ar'): 1107, - ('en', 'de'): 1305, - ('en', 'fr'): 1305, ('ar', 'en'): 1107, - ('fr', 'en'): 1305, - ('de', 'en'): 1305 + ('de', 'en'): 1305, + ('en', 'fr'): 1305 } } } @@ -173,38 +126,6 @@ } -def _read_text_iterator(path): - with io.open(path, encoding="utf8") as f: - for row in f: - yield row - - -def _clean_xml_file(f_xml): - f_txt = os.path.splitext(f_xml)[0] - with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: - root = ET.parse(f_xml).getroot()[0] - for doc in root.findall('doc'): - for e in doc.findall('seg'): - fd_txt.write(e.text.strip() + '\n') - - -def _clean_tags_file(f_orig): - xml_tags = [ - '>> from torchtext.datasets import IWSLT2016 + >>> train_iter, valid_iter, test_iter = IWSLT2016() + >>> src_sentence, tgt_sentence = next(train_iter) + """ num_lines_set_identifier = { 'train': 'train', @@ -255,9 +198,9 @@ def IWSLT2016(root='.data', split=('train', 'valid', 'test'), offset=0, language src_language, tgt_language = language_pair[0], language_pair[1] - if src_language not in SUPPORTED_DATASETS['language_pair'].keys(): + if src_language not in SUPPORTED_DATASETS['language_pair']: raise ValueError("src_language '{}' is not valid. Supported source languages are {}". - format(src_language, SUPPORTED_DATASETS['language_pair'].keys())) + format(src_language, list(SUPPORTED_DATASETS['language_pair']))) if tgt_language not in SUPPORTED_DATASETS['language_pair'][src_language]: raise ValueError("tgt_language '{}' is not valid for give src_language '{}'. Supported target language are {}". @@ -328,4 +271,4 @@ def _iter(src_data_iter, tgt_data_iter): for item in zip(src_data_iter, tgt_data_iter): yield item - return RawTextIterableDataset("IWSLT2016", NUM_LINES[split][num_lines_set_identifier[split]][language_pair], _iter(src_data_iter, tgt_data_iter)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split][num_lines_set_identifier[split]][tuple(sorted(language_pair))], _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/datasets/iwslt2017.py b/torchtext/datasets/iwslt2017.py index 0837d343b1..051f1377d5 100644 --- a/torchtext/datasets/iwslt2017.py +++ b/torchtext/datasets/iwslt2017.py @@ -1,10 +1,13 @@ import os -import io -import codecs -import xml.etree.ElementTree as ET from torchtext.utils import (download_from_url, extract_archive) -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _clean_xml_file, + _clean_tags_file, + _read_text_iterator, +) +from torchtext.data.datasets_utils import _create_dataset_directory SUPPORTED_DATASETS = { @@ -29,154 +32,72 @@ 'train': { 'train': { ('en', 'nl'): 237240, - ('en', 'de'): 206112, + ('de', 'en'): 206112, ('en', 'it'): 231619, ('en', 'ro'): 220538, - ('ro', 'de'): 201455, - ('ro', 'en'): 220538, - ('ro', 'nl'): 206920, - ('ro', 'it'): 217551, ('de', 'ro'): 201455, - ('de', 'en'): 206112, + ('nl', 'ro'): 206920, + ('it', 'ro'): 217551, ('de', 'nl'): 213628, ('de', 'it'): 205465, - ('it', 'en'): 231619, - ('it', 'nl'): 233415, - ('it', 'de'): 205465, - ('it', 'ro'): 217551, - ('nl', 'de'): 213628, - ('nl', 'en'): 237240, - ('nl', 'it'): 233415, - ('nl', 'ro'): 206920 + ('it', 'nl'): 233415 } }, 'valid': { 'dev2010': { ('en', 'nl'): 1003, - ('en', 'de'): 888, + ('de', 'en'): 888, ('en', 'it'): 929, ('en', 'ro'): 914, - ('ro', 'de'): 912, - ('ro', 'en'): 914, - ('ro', 'nl'): 913, - ('ro', 'it'): 914, ('de', 'ro'): 912, - ('de', 'en'): 888, + ('nl', 'ro'): 913, + ('it', 'ro'): 914, ('de', 'nl'): 1001, ('de', 'it'): 923, - ('it', 'en'): 929, - ('it', 'nl'): 1001, - ('it', 'de'): 923, - ('it', 'ro'): 914, - ('nl', 'de'): 1001, - ('nl', 'en'): 1003, - ('nl', 'it'): 1001, - ('nl', 'ro'): 913 + ('it', 'nl'): 1001 }, 'tst2010': { ('en', 'nl'): 1777, - ('en', 'de'): 1568, + ('de', 'en'): 1568, ('en', 'it'): 1566, ('en', 'ro'): 1678, - ('ro', 'de'): 1677, - ('ro', 'en'): 1678, - ('ro', 'nl'): 1680, - ('ro', 'it'): 1643, ('de', 'ro'): 1677, - ('de', 'en'): 1568, + ('nl', 'ro'): 1680, + ('it', 'ro'): 1643, ('de', 'nl'): 1779, ('de', 'it'): 1567, - ('it', 'en'): 1566, - ('it', 'nl'): 1669, - ('it', 'de'): 1567, - ('it', 'ro'): 1643, - ('nl', 'de'): 1779, - ('nl', 'en'): 1777, - ('nl', 'it'): 1669, - ('nl', 'ro'): 1680 + ('it', 'nl'): 1669 } }, 'test': { 'dev2010': { ('en', 'nl'): 1003, - ('en', 'de'): 888, + ('de', 'en'): 888, ('en', 'it'): 929, ('en', 'ro'): 914, - ('ro', 'de'): 912, - ('ro', 'en'): 914, - ('ro', 'nl'): 913, - ('ro', 'it'): 914, ('de', 'ro'): 912, - ('de', 'en'): 888, + ('nl', 'ro'): 913, + ('it', 'ro'): 914, ('de', 'nl'): 1001, ('de', 'it'): 923, - ('it', 'en'): 929, - ('it', 'nl'): 1001, - ('it', 'de'): 923, - ('it', 'ro'): 914, - ('nl', 'de'): 1001, - ('nl', 'en'): 1003, - ('nl', 'it'): 1001, - ('nl', 'ro'): 913 + ('it', 'nl'): 1001 }, 'tst2010': { ('en', 'nl'): 1777, - ('en', 'de'): 1568, + ('de', 'en'): 1568, ('en', 'it'): 1566, ('en', 'ro'): 1678, - ('ro', 'de'): 1677, - ('ro', 'en'): 1678, - ('ro', 'nl'): 1680, - ('ro', 'it'): 1643, ('de', 'ro'): 1677, - ('de', 'en'): 1568, + ('nl', 'ro'): 1680, + ('it', 'ro'): 1643, ('de', 'nl'): 1779, ('de', 'it'): 1567, - ('it', 'en'): 1566, - ('it', 'nl'): 1669, - ('it', 'de'): 1567, - ('it', 'ro'): 1643, - ('nl', 'de'): 1779, - ('nl', 'en'): 1777, - ('nl', 'it'): 1669, - ('nl', 'ro'): 1680 + ('it', 'nl'): 1669 } } } -def _read_text_iterator(path): - with io.open(path, encoding="utf8") as f: - for row in f: - yield row - - -def _clean_xml_file(f_xml): - f_txt = os.path.splitext(f_xml)[0] - with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: - root = ET.parse(f_xml).getroot()[0] - for doc in root.findall('doc'): - for e in doc.findall('seg'): - fd_txt.write(e.text.strip() + '\n') - - -def _clean_tags_file(f_orig): - xml_tags = [ - '>> from torchtext.datasets import IWSLT2017 + >>> train_iter, valid_iter, test_iter = IWSLT2017() + >>> src_sentence, tgt_sentence = next(train_iter) + """ valid_set = 'dev2010' @@ -229,9 +171,9 @@ def IWSLT2017(root='.data', split=('train', 'valid', 'test'), language_pair=('de src_language, tgt_language = language_pair[0], language_pair[1] - if src_language not in SUPPORTED_DATASETS['language_pair'].keys(): - raise ValueError("src_language '{}' is not valid for ISWLT_year {}. Supported source languages are {}". - format(src_language, year, SUPPORTED_DATASETS['language_pair'].keys())) + if src_language not in SUPPORTED_DATASETS['language_pair']: + raise ValueError("src_language '{}' is not valid. Supported source languages are {}". + format(src_language, list(SUPPORTED_DATASETS['language_pair']))) if tgt_language not in SUPPORTED_DATASETS['language_pair'][src_language]: raise ValueError("tgt_language '{}' is not valid for give src_language '{}'. Supported target language are {}". @@ -277,7 +219,7 @@ def IWSLT2017(root='.data', split=('train', 'valid', 'test'), language_pair=('de "valid": _construct_filepaths(file_archives, src_eval, tgt_eval), "test": _construct_filepaths(file_archives, src_test, tgt_test) } - for key in data_filenames.keys(): + for key in data_filenames: if len(data_filenames[key]) == 0 or data_filenames[key] is None: raise FileNotFoundError( "Files are not found for data type {}".format(key)) @@ -289,4 +231,4 @@ def _iter(src_data_iter, tgt_data_iter): for item in zip(src_data_iter, tgt_data_iter): yield item - return RawTextIterableDataset("IWSLT2017", NUM_LINES[split][num_lines_set_identifier[split]][language_pair], _iter(src_data_iter, tgt_data_iter)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split][num_lines_set_identifier[split]][tuple(sorted(language_pair))], _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/datasets/multi30k.py b/torchtext/datasets/multi30k.py deleted file mode 100644 index 868a4b7d1f..0000000000 --- a/torchtext/datasets/multi30k.py +++ /dev/null @@ -1,171 +0,0 @@ -import io -import os -from torchtext.utils import (download_from_url, extract_archive) -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header - -_URL_BASE_ = 'https://raw.githubusercontent.com/multi30k/dataset/master/data/task' - -_URL1 = [ - '1/raw/test_2016_flickr.cs.gz', - '1/raw/test_2016_flickr.de.gz', - '1/raw/test_2016_flickr.en.gz', - '1/raw/test_2016_flickr.fr.gz', - '1/raw/test_2017_flickr.de.gz', - '1/raw/test_2017_flickr.en.gz', - '1/raw/test_2017_flickr.fr.gz', - '1/raw/test_2017_mscoco.de.gz', - '1/raw/test_2017_mscoco.en.gz', - '1/raw/test_2017_mscoco.fr.gz', - '1/raw/test_2018_flickr.en.gz', - '1/raw/train.cs.gz', - '1/raw/train.de.gz', - '1/raw/train.en.gz', - '1/raw/train.fr.gz', - '1/raw/val.cs.gz', - '1/raw/val.de.gz', - '1/raw/val.en.gz', - '1/raw/val.fr.gz' -] -URL = [_URL_BASE_ + u for u in _URL1] - -_URL2 = [ - '2/raw/test_2016', - '2/raw/train', - '2/raw/val', -] -for u in _URL2: - for i in range(1, 6): - for lang in ['de', 'en']: - URL.append(_URL_BASE_ + u + "." + str(i) + "." + lang + '.gz') - -MD5 = [ - '3104872229daa1bef3b401d44dd2220b', - 'efd67d314d98489b716b145475101932', - 'ff2c0fcb4893a13bd73414306bc250ae', - '08dc7cd4a662f31718412de95ca9bfe3', - '6a8d5c87f6ae19e3d35681aa6fd16571', - '005396bac545d880abe6f00bbb7dbbb4', - 'cb09af7d2b501f9112f2d6a59fa1360d', - 'e8cd6ec2bc8a11fc846fa48a46e3d0bb', - 'a7b684e0edbef1d4a23660c8e8e743fd', - '4995d10954a804d3cdfd907b9fd093e8', - 'a152878809942757a55ce087073486b8', - 'd9a5fc268917725a2b0efce3a0cc8607', - '81ff90b99829c0cd4b1b587d394afd39', - '0065d13af80720a55ca8153d126e6627', - '6cb767741dcad3931f966fefbc05203f', - '83cdc082f646b769095615384cf5c0ca', - '6e0e229eb049e3fc99a1ef02fb2d5f91', - '2b69aa9253948ac9f67e94917272dd40', - '93fc564584b7e5ba410c761ea5a1c682', - 'ac0c72653c140dd96707212a1baa4278', - 'eec05227daba4bb8f3f8f25b1cb335f4', - '6dfb42cae4e4fd9a3c40e62ff5398a55', - '9318fa08c0c0b96114eadb10eb2fc633', - 'ece8cec6b87bf00dd12607f3062dae4c', - '088ec0765fa213a0eb937a62adfd4996', - '9a7e7b2dcc33135a32cd621c3b37d2d8', - '5f7c8d0be0ac739856b47d32a9434998', - '7d5ef0f069ee2d74dc2fdc6b46cd47fa', - '713ed720636622a54546d5f14f88b00f', - '62f36422bfab90fb42a560546b704009', - 'cbf5bfc2147706f228d288e1b18bf4af', - '540da4566bb6dd35fdbc720218b742b7', - 'bdfe4222f4692ccaa1e3389460f0890e', - '613eb4a3f0c2b13f0871ced946851b0e', - '0e1ee2b4145795bd180b193424db204b', - 'd848fe0ae8b9447209fb49c5c31cb3d2', - '1cff688d1aadef7fdb22e9ad27d6fd2c', - 'abc13b4042f4fef1cdff6de3b6c53b71', - '3e10289959d0059952511c31df3c7550', - 'b26486ede1d4436d5acf6e38c65bb44d', - 'df57faf5f00d434d2559c021ef55f1aa', - '16165248083beacebfe18866d5f4f0ae', - '9077a5127480cc799116384de501bd70', - '7180780822d4b600eb81c1ccf171c230', - 'c1f697c3b6dfb7305349db34e26b45fc', - '8edb43c90cae66ec762748a968089b99', - 'acb5ea26a577ceccfae6337181c31716', - '873a377a348713d3ab84db1fb57cdede', - '680816e0938fea5cf5331444bc09a4cf' -] - -NUM_LINES = { - 'train': 29000, - 'valid': 1014, - 'test': 1000, -} - - -def _read_text_iterator(path): - with io.open(path, encoding="utf8") as f: - for row in f: - yield row - - -def _construct_filepaths(paths, src_filename, tgt_filename): - src_path = None - tgt_path = None - for p in paths: - src_path = p if src_filename in p else src_path - tgt_path = p if tgt_filename in p else tgt_path - return (src_path, tgt_path) - - -_DOCSTRING = \ - """ train_filenames: the source and target filenames for training. - Default: ('train.de', 'train.en') - valid_filenames: the source and target filenames for valid. - Default: ('val.de', 'val.en') - test_filenames: the source and target filenames for test. - Default: ('test2016.de', 'test2016.en') - - The available dataset include:""" - -for u in URL: - _DOCSTRING += ("\n " + os.path.basename(u)[:-3]) - - -@add_docstring_header(_DOCSTRING, NUM_LINES) -@wrap_split_argument(('train', 'valid', 'test')) -def Multi30k(root, split, - train_filenames=("train.de", "train.en"), - valid_filenames=("val.de", "val.en"), - test_filenames=("test_2016_flickr.de", "test_2016_flickr.en")): - if not isinstance(train_filenames, tuple) and not isinstance(valid_filenames, tuple) \ - and not isinstance(test_filenames, tuple): - raise ValueError("All filenames must be tuples") - src_train, tgt_train = train_filenames - src_eval, tgt_eval = valid_filenames - src_test, tgt_test = test_filenames - - extracted_files = [] # list of paths to the extracted files - - for idx, f in enumerate(URL): - dataset_tar = download_from_url( - f, root=root, hash_value=MD5[idx], hash_type='md5') - extracted_files.extend(extract_archive(dataset_tar)) - - file_archives = extracted_files - - data_filenames = { - "train": _construct_filepaths(file_archives, src_train, tgt_train), - "valid": _construct_filepaths(file_archives, src_eval, tgt_eval), - "test": _construct_filepaths(file_archives, src_test, tgt_test) - } - - for key in data_filenames.keys(): - if len(data_filenames[key]) == 0 or data_filenames[key] is None: - raise FileNotFoundError( - "Files are not found for data type {}".format(key)) - - src_data_iter = _read_text_iterator(data_filenames[split][0]) - tgt_data_iter = _read_text_iterator(data_filenames[split][1]) - - def _iter(src_data_iter, tgt_data_iter): - for item in zip(src_data_iter, tgt_data_iter): - yield item - - return RawTextIterableDataset("Multi30k", NUM_LINES[split], _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/datasets/penntreebank.py b/torchtext/datasets/penntreebank.py index 3c23f0202d..29d9666af1 100644 --- a/torchtext/datasets/penntreebank.py +++ b/torchtext/datasets/penntreebank.py @@ -1,9 +1,12 @@ import logging from torchtext.utils import download_from_url -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -import io +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _create_dataset_directory, + _read_text_iterator, +) URL = { 'train': "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", @@ -23,14 +26,17 @@ 'test': 3761, } +DATASET_NAME = "PennTreebank" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'valid', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'valid', 'test')) def PennTreebank(root, split): path = download_from_url(URL[split], root=root, hash_value=MD5[split], hash_type='md5') logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset('PennTreebank', - NUM_LINES[split], - iter(io.open(path, encoding="utf8"))) + return _RawTextIterableDataset(DATASET_NAME, + NUM_LINES[split], + _read_text_iterator(path)) diff --git a/torchtext/datasets/sogounews.py b/torchtext/datasets/sogounews.py index 5db30f8fd1..6370ddd522 100644 --- a/torchtext/datasets/sogounews.py +++ b/torchtext/datasets/sogounews.py @@ -1,9 +1,12 @@ -from torchtext.utils import unicode_csv_reader -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import download_extract_validate -import io +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _download_extract_validate, + _create_dataset_directory, + _create_data_from_csv, +) +import os import logging URL = 'https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE' @@ -18,8 +21,8 @@ _PATH = 'sogou_news_csv.tar.gz' _EXTRACTED_FILES = { - 'train': 'sogou_news_csv/train.csv', - 'test': 'sogou_news_csv/test.csv' + 'train': f'{os.sep}'.join(['sogou_news_csv', 'train.csv']), + 'test': f'{os.sep}'.join(['sogou_news_csv', 'test.csv']), } _EXTRACTED_FILES_MD5 = { @@ -27,17 +30,15 @@ 'test': "59e493c41cee050329446d8c45615b38" } +DATASET_NAME = "SogouNews" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES, num_classes=5) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'test')) def SogouNews(root, split): - def _create_data_from_csv(data_path): - with io.open(data_path, encoding="utf8") as f: - reader = unicode_csv_reader(f) - for row in reader: - yield int(row[0]), ' '.join(row[1:]) - path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[split], - _EXTRACTED_FILES_MD5[split], hash_type="md5") + path = _download_extract_validate(root, URL, MD5, os.path.join(root, _PATH), os.path.join(root, _EXTRACTED_FILES[split]), + _EXTRACTED_FILES_MD5[split], hash_type="md5") logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset("SogouNews", NUM_LINES[split], - _create_data_from_csv(path)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_csv(path)) diff --git a/torchtext/datasets/squad1.py b/torchtext/datasets/squad1.py index 24e4a6b1a4..2c9fdc3ff4 100644 --- a/torchtext/datasets/squad1.py +++ b/torchtext/datasets/squad1.py @@ -1,9 +1,11 @@ from torchtext.utils import download_from_url -import json -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header - +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _create_dataset_directory, + _create_data_from_json, +) URL = { 'train': "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", 'dev': "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json", @@ -20,25 +22,13 @@ } -def _create_data_from_json(data_path): - with open(data_path) as json_file: - raw_json_data = json.load(json_file)['data'] - for layer1 in raw_json_data: - for layer2 in layer1['paragraphs']: - for layer3 in layer2['qas']: - _context, _question = layer2['context'], layer3['question'] - _answers = [item['text'] for item in layer3['answers']] - _answer_start = [item['answer_start'] for item in layer3['answers']] - if len(_answers) == 0: - _answers = [""] - _answer_start = [-1] - # yield the raw data in the order of context, question, answers, answer_start - yield (_context, _question, _answers, _answer_start) +DATASET_NAME = "SQuAD1" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'dev')) +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'dev')) def SQuAD1(root, split): extracted_files = download_from_url(URL[split], root=root, hash_value=MD5[split], hash_type='md5') - return RawTextIterableDataset('SQuAD1', NUM_LINES[split], - _create_data_from_json(extracted_files)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_json(extracted_files)) diff --git a/torchtext/datasets/squad2.py b/torchtext/datasets/squad2.py index 9e24beded3..a889f9900f 100644 --- a/torchtext/datasets/squad2.py +++ b/torchtext/datasets/squad2.py @@ -1,9 +1,11 @@ from torchtext.utils import download_from_url -import json -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header - +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _create_dataset_directory, + _create_data_from_json, +) URL = { 'train': "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", 'dev': "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json", @@ -20,25 +22,13 @@ } -def _create_data_from_json(data_path): - with open(data_path) as json_file: - raw_json_data = json.load(json_file)['data'] - for layer1 in raw_json_data: - for layer2 in layer1['paragraphs']: - for layer3 in layer2['qas']: - _context, _question = layer2['context'], layer3['question'] - _answers = [item['text'] for item in layer3['answers']] - _answer_start = [item['answer_start'] for item in layer3['answers']] - if len(_answers) == 0: - _answers = [""] - _answer_start = [-1] - # yield the raw data in the order of context, question, answers, answer_start - yield (_context, _question, _answers, _answer_start) +DATASET_NAME = "SQuAD2" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'dev')) +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'dev')) def SQuAD2(root, split): extracted_files = download_from_url(URL[split], root=root, hash_value=MD5[split], hash_type='md5') - return RawTextIterableDataset('SQuAD2', NUM_LINES[split], - _create_data_from_json(extracted_files)) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_json(extracted_files)) diff --git a/torchtext/datasets/udpos.py b/torchtext/datasets/udpos.py index 1942e5ecbd..2377448939 100644 --- a/torchtext/datasets/udpos.py +++ b/torchtext/datasets/udpos.py @@ -1,8 +1,12 @@ from torchtext.utils import download_from_url, extract_archive -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import find_match +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _find_match, + _create_dataset_directory, + _create_data_from_iob, +) URL = 'https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip' @@ -15,32 +19,18 @@ } -def _create_data_from_iob(data_path, separator="\t"): - with open(data_path, encoding="utf-8") as input_file: - columns = [] - for line in input_file: - line = line.strip() - if line == "": - if columns: - yield columns - columns = [] - else: - for i, column in enumerate(line.split(separator)): - if len(columns) < i + 1: - columns.append([]) - columns[i].append(column) - if len(columns) > 0: - yield columns +DATASET_NAME = "UDPOS" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'valid', 'test')) +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'valid', 'test')) def UDPOS(root, split): dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) if split == 'valid': - path = find_match("dev.txt", extracted_files) + path = _find_match("dev.txt", extracted_files) else: - path = find_match(split + ".txt", extracted_files) - return RawTextIterableDataset("UDPOS", NUM_LINES[split], - _create_data_from_iob(path)) + path = _find_match(split + ".txt", extracted_files) + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], + _create_data_from_iob(path)) diff --git a/torchtext/datasets/wikitext103.py b/torchtext/datasets/wikitext103.py index 0222357036..49164b2789 100644 --- a/torchtext/datasets/wikitext103.py +++ b/torchtext/datasets/wikitext103.py @@ -1,10 +1,16 @@ import logging -from torchtext.utils import download_from_url, extract_archive -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import find_match -import io +from torchtext.utils import ( + download_from_url, + extract_archive, +) +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _find_match, + _create_dataset_directory, + _read_text_iterator, +) URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip' @@ -16,14 +22,17 @@ 'test': 4358, } +DATASET_NAME = "WikiText103" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'valid', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'valid', 'test')) def WikiText103(root, split): dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - path = find_match(split, extracted_files) + path = _find_match(split, extracted_files) logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset('WikiText103', - NUM_LINES[split], iter(io.open(path, encoding="utf8"))) + return _RawTextIterableDataset(DATASET_NAME, + NUM_LINES[split], _read_text_iterator(path)) diff --git a/torchtext/datasets/wikitext2.py b/torchtext/datasets/wikitext2.py index 76e1047ab0..b4c20fc880 100644 --- a/torchtext/datasets/wikitext2.py +++ b/torchtext/datasets/wikitext2.py @@ -1,10 +1,13 @@ import logging from torchtext.utils import download_from_url, extract_archive -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import find_match -import io +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _find_match, + _create_dataset_directory, + _read_text_iterator, +) URL = 'https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip' @@ -16,13 +19,16 @@ 'test': 4358, } +DATASET_NAME = "WikiText2" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train', 'valid', 'test')) + +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'valid', 'test')) def WikiText2(root, split): dataset_tar = download_from_url(URL, root=root, hash_value=MD5, hash_type='md5') extracted_files = extract_archive(dataset_tar) - path = find_match(split, extracted_files) + path = _find_match(split, extracted_files) logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset('WikiText2', - NUM_LINES[split], iter(io.open(path, encoding="utf8"))) + return _RawTextIterableDataset(DATASET_NAME, + NUM_LINES[split], _read_text_iterator(path)) diff --git a/torchtext/datasets/wmt14.py b/torchtext/datasets/wmt14.py deleted file mode 100644 index 1215558123..0000000000 --- a/torchtext/datasets/wmt14.py +++ /dev/null @@ -1,179 +0,0 @@ -import os -import io -import codecs -import xml.etree.ElementTree as ET -from torchtext.utils import (download_from_url, extract_archive) -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header - -URL = 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8' - -_PATH = 'wmt16_en_de.tar.gz' - -MD5 = '874ab6bbfe9c21ec987ed1b9347f95ec' - -NUM_LINES = { - 'train': 4500966, - 'valid': 3000, - 'test': 3003, -} - - -def _read_text_iterator(path): - with io.open(path, encoding="utf8") as f: - for row in f: - yield row - - -def _clean_xml_file(f_xml): - f_txt = os.path.splitext(f_xml)[0] - with codecs.open(f_txt, mode='w', encoding='utf-8') as fd_txt: - root = ET.parse(f_xml).getroot()[0] - for doc in root.findall('doc'): - for e in doc.findall('seg'): - fd_txt.write(e.text.strip() + '\n') - - -def _clean_tags_file(f_orig): - xml_tags = [ - '>> from torchtext.experimental.datasets.raw import Multi30k + >>> train_iter, valid_iter, test_iter = Multi30k() + >>> src_sentence, tgt_sentence = next(train_iter) + """ + + if task not in SUPPORTED_DATASETS.keys(): + raise ValueError('task {} is not supported. Valid options are {}'. + format(task, SUPPORTED_DATASETS.keys())) + + assert (len(language_pair) == 2), 'language_pair must contain only 2 elements: src and tgt language respectively' + + if language_pair[0] not in SUPPORTED_DATASETS[task].keys(): + raise ValueError("Source language '{}' is not supported. Valid options for task '{}' are {}". + format(language_pair[0], task, list(SUPPORTED_DATASETS[task].keys()))) + + if language_pair[1] not in SUPPORTED_DATASETS[task].keys(): + raise ValueError("Target language '{}' is not supported. Valid options for task '{}' are {}". + format(language_pair[1], task, list(SUPPORTED_DATASETS[task].keys()))) + + if train_set not in SUPPORTED_DATASETS[task][language_pair[0]].keys() or 'train' not in train_set: + raise ValueError("'{}' is not a valid train set identifier. valid options for task '{}' and language pair {} are {}". + format(train_set, task, language_pair, [k for k in SUPPORTED_DATASETS[task][language_pair[0]].keys() if 'train' in k])) + + if valid_set not in SUPPORTED_DATASETS[task][language_pair[0]].keys() or 'val' not in valid_set: + raise ValueError("'{}' is not a valid valid set identifier. valid options for task '{}' and language pair {} are {}". + format(valid_set, task, language_pair, [k for k in SUPPORTED_DATASETS[task][language_pair[0]].keys() if 'val' in k])) + + if test_set not in SUPPORTED_DATASETS[task][language_pair[0]].keys() or 'test' not in test_set: + raise ValueError("'{}' is not a valid test set identifier. valid options for task '{}' and language pair {} are {}". + format(test_set, task, language_pair, [k for k in SUPPORTED_DATASETS[task][language_pair[0]].keys() if 'test' in k])) + + train_filenames = ["{}.{}".format( + train_set, language_pair[0]), "{}.{}".format(train_set, + language_pair[1])] + valid_filenames = ["{}.{}".format( + valid_set, language_pair[0]), "{}.{}".format(valid_set, + language_pair[1])] + test_filenames = ["{}.{}".format( + test_set, language_pair[0]), "{}.{}".format(test_set, + language_pair[1])] + + if split == 'train': + src_file, tgt_file = train_filenames + elif split == 'valid': + src_file, tgt_file = valid_filenames + else: + src_file, tgt_file = test_filenames + + extracted_files = [] # list of paths to the extracted files + + current_url = [] + current_md5 = [] + + current_filenames = [src_file, tgt_file] + for url, md5 in zip(URL[split], MD5[split]): + if any(f in url for f in current_filenames): + current_url.append(url) + current_md5.append(md5) + + for url, md5 in zip(current_url, current_md5): + dataset_tar = download_from_url( + url, path=os.path.join(root, os.path.basename(url)), root=root, hash_value=md5, hash_type='md5') + extracted_files.extend(extract_archive(dataset_tar)) + + file_archives = extracted_files + + data_filenames = { + split: _construct_filepaths(file_archives, src_file, tgt_file), + } + + for key in data_filenames: + if len(data_filenames[key]) == 0 or data_filenames[key] is None: + raise FileNotFoundError( + "Files are not found for data type {}".format(key)) + + assert data_filenames[split][0] is not None, "Internal Error: File not found for reading" + assert data_filenames[split][1] is not None, "Internal Error: File not found for reading" + src_data_iter = _read_text_iterator(data_filenames[split][0]) + tgt_data_iter = _read_text_iterator(data_filenames[split][1]) + + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item + + set_identifier = { + 'train': train_set, + 'valid': valid_set, + 'test': test_set, + } + + return _RawTextIterableDataset(DATASET_NAME, + SUPPORTED_DATASETS[task][language_pair[0]][set_identifier[split]]['NUM_LINES'], + _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/experimental/datasets/raw/wmt14.py b/torchtext/experimental/datasets/raw/wmt14.py new file mode 100644 index 0000000000..a9e5bd7f53 --- /dev/null +++ b/torchtext/experimental/datasets/raw/wmt14.py @@ -0,0 +1,159 @@ +import os +from torchtext.utils import (download_from_url, extract_archive) +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _read_text_iterator, +) +from torchtext.data.datasets_utils import _create_dataset_directory + +URL = 'https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8' + +_PATH = 'wmt16_en_de.tar.gz' + +MD5 = '874ab6bbfe9c21ec987ed1b9347f95ec' + +NUM_LINES = { + 'newstest2010.tok.bpe.32000': 2489, + 'newstest2012': 3003, + 'newstest2010.tok': 2489, + 'newstest2016': 2999, + 'newstest2014.tok': 3003, + 'newstest2009': 2525, + 'newstest2015.tok.bpe.32000': 2169, + 'newstest2016.tok': 2999, + 'newstest2011.tok.bpe.32000': 3003, + 'newstest2012.tok': 3003, + 'newstest2013': 3000, + 'newstest2014.tok.bpe.32000': 3003, + 'newstest2011.tok': 3003, + 'newstest2011': 3003, + 'newstest2015.tok': 2169, + 'newstest2012.tok.bpe.32000': 3003, + 'newstest2015': 2169, + 'newstest2016.tok.bpe.32000': 2999, + 'newstest2009.tok.bpe.32000': 2525, + 'newstest2014': 3003, + 'newstest2009.tok': 2525, + 'newstest2013.tok.bpe.32000': 3000, + 'newstest2013.tok': 3000, + 'newstest2010': 2489, + 'train.tok.clean.bpe.32000': 4500966 +} + + +def _construct_filenames(filename, languages): + filenames = [] + for lang in languages: + filenames.append(filename + "." + lang) + return filenames + + +def _construct_filepaths(paths, src_filename, tgt_filename): + src_path = None + tgt_path = None + for p in paths: + src_path = p if src_filename in p else src_path + tgt_path = p if tgt_filename in p else tgt_path + return (src_path, tgt_path) + + +DATASET_NAME = "WMT14" + + +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'valid', 'test')) +def WMT14(root, split, + language_pair=('de', 'en'), + train_set='train.tok.clean.bpe.32000', + valid_set='newstest2013.tok.bpe.32000', + test_set='newstest2014.tok.bpe.32000'): + """WMT14 Dataset + + The available datasets include following: + + **Language pairs**: + + +-----+-----+-----+ + | |'en' |'de' | + +-----+-----+-----+ + |'en' | | x | + +-----+-----+-----+ + |'de' | x | | + +-----+-----+-----+ + + + Args: + root: Directory where the datasets are saved. Default: ".data" + split: split or splits to be returned. Can be a string or tuple of strings. Default: (‘train’, ‘valid’, ‘test’) + language_pair: tuple or list containing src and tgt language + train_set: A string to identify train set. + valid_set: A string to identify validation set. + test_set: A string to identify test set. + + Examples: + >>> from torchtext.datasets import WMT14 + >>> train_iter, valid_iter, test_iter = WMT14() + >>> src_sentence, tgt_sentence = next(train_iter) + """ + + supported_language = ['en', 'de'] + supported_train_set = [s for s in NUM_LINES if 'train' in s] + supported_valid_set = [s for s in NUM_LINES if 'test' in s] + supported_test_set = [s for s in NUM_LINES if 'test' in s] + + assert (len(language_pair) == 2), 'language_pair must contain only 2 elements: src and tgt language respectively' + + if language_pair[0] not in supported_language: + raise ValueError("Source language '{}' is not supported. Valid options are {}". + format(language_pair[0], supported_language)) + + if language_pair[1] not in supported_language: + raise ValueError("Target language '{}' is not supported. Valid options are {}". + format(language_pair[1], supported_language)) + + if train_set not in supported_train_set: + raise ValueError("'{}' is not a valid train set identifier. valid options are {}". + format(train_set, supported_train_set)) + + if valid_set not in supported_valid_set: + raise ValueError("'{}' is not a valid valid set identifier. valid options are {}". + format(valid_set, supported_valid_set)) + + if test_set not in supported_test_set: + raise ValueError("'{}' is not a valid valid set identifier. valid options are {}". + format(test_set, supported_test_set)) + + train_filenames = '{}.{}'.format(train_set, language_pair[0]), '{}.{}'.format(train_set, language_pair[1]) + valid_filenames = '{}.{}'.format(valid_set, language_pair[0]), '{}.{}'.format(valid_set, language_pair[1]) + test_filenames = '{}.{}'.format(test_set, language_pair[0]), '{}.{}'.format(test_set, language_pair[1]) + + if split == 'train': + src_file, tgt_file = train_filenames + elif split == 'valid': + src_file, tgt_file = valid_filenames + else: + src_file, tgt_file = test_filenames + + dataset_tar = download_from_url(URL, root=root, hash_value=MD5, path=os.path.join(root, _PATH), hash_type='md5') + extracted_files = extract_archive(dataset_tar) + + data_filenames = { + split: _construct_filepaths(extracted_files, src_file, tgt_file), + } + + for key in data_filenames: + if len(data_filenames[key]) == 0 or data_filenames[key] is None: + raise FileNotFoundError( + "Files are not found for data type {}".format(key)) + + assert data_filenames[split][0] is not None, "Internal Error: File not found for reading" + assert data_filenames[split][1] is not None, "Internal Error: File not found for reading" + src_data_iter = _read_text_iterator(data_filenames[split][0]) + tgt_data_iter = _read_text_iterator(data_filenames[split][1]) + + def _iter(src_data_iter, tgt_data_iter): + for item in zip(src_data_iter, tgt_data_iter): + yield item + + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[os.path.splitext(src_file)[0]], _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/datasets/wmtnewscrawl.py b/torchtext/experimental/datasets/raw/wmtnewscrawl.py similarity index 65% rename from torchtext/datasets/wmtnewscrawl.py rename to torchtext/experimental/datasets/raw/wmtnewscrawl.py index 709ca393c3..5322c4466a 100644 --- a/torchtext/datasets/wmtnewscrawl.py +++ b/torchtext/experimental/datasets/raw/wmtnewscrawl.py @@ -1,8 +1,11 @@ -from torchtext.data.datasets_utils import RawTextIterableDataset -from torchtext.data.datasets_utils import wrap_split_argument -from torchtext.data.datasets_utils import add_docstring_header -from torchtext.data.datasets_utils import download_extract_validate -import io +from torchtext.data.datasets_utils import ( + _RawTextIterableDataset, + _wrap_split_argument, + _add_docstring_header, + _download_extract_validate, + _create_dataset_directory, + _read_text_iterator, +) import logging URL = 'http://www.statmt.org/wmt11/training-monolingual-news-2010.tgz' @@ -40,16 +43,19 @@ "fr": "066d671533f78bfe139cf7052574fd5a" } +DATASET_NAME = "WMTNewsCrawl" -@add_docstring_header(num_lines=NUM_LINES) -@wrap_split_argument(('train',)) + +@_add_docstring_header(num_lines=NUM_LINES) +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument('train') def WMTNewsCrawl(root, split, year=2010, language='en'): if year not in _AVAILABLE_YEARS: raise ValueError("{} not available. Please choose from years {}".format(year, _AVAILABLE_YEARS)) if language not in _AVAILABLE_LANGUAGES: raise ValueError("{} not available. Please choose from languages {}".format(language, _AVAILABLE_LANGUAGES)) - path = download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[language], - _EXTRACTED_FILES_MD5[language], hash_type="md5") + path = _download_extract_validate(root, URL, MD5, _PATH, _EXTRACTED_FILES[language], + _EXTRACTED_FILES_MD5[language], hash_type="md5") logging.info('Creating {} data'.format(split)) - return RawTextIterableDataset("WMTNewsCrawl", - NUM_LINES[split], iter(io.open(path, encoding="utf8"))) + return _RawTextIterableDataset(DATASET_NAME, + NUM_LINES[split], _read_text_iterator(path)) diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index 06148dabd3..edcf11048e 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -1,7 +1,7 @@ import torch import logging -from torchtext.data.datasets_utils import check_default_set -from torchtext.data.datasets_utils import wrap_datasets +from torchtext.data.datasets_utils import _check_default_set +from torchtext.data.datasets_utils import _wrap_datasets from torchtext import datasets as raw from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.functional import ( @@ -28,7 +28,7 @@ def build_vocab(data): def _setup_datasets(dataset_name, root, vocabs, split_): - split = check_default_set(split_, ('train', 'valid', 'test'), dataset_name) + split = _check_default_set(split_, ('train', 'valid', 'test'), dataset_name) raw_iter_tuple = raw.DATASETS[dataset_name](root=root, split=split) raw_data = {} for name, raw_iter in zip(split, raw_iter_tuple): @@ -60,7 +60,7 @@ def _setup_datasets(dataset_name, root, vocabs, split_): for idx in range(len(vocabs)) ] logger_.info('Building datasets for {}'.format(split)) - return wrap_datasets(tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in split), split_) + return _wrap_datasets(tuple(SequenceTaggingDataset(raw_data[item], vocabs, transformers) for item in split), split_) class SequenceTaggingDataset(torch.utils.data.Dataset): diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index d04833fd9b..d3834868db 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -3,8 +3,8 @@ from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext import datasets as raw -from torchtext.data.datasets_utils import check_default_set -from torchtext.data.datasets_utils import wrap_datasets +from torchtext.data.datasets_utils import _check_default_set +from torchtext.data.datasets_utils import _wrap_datasets from torchtext.experimental.functional import ( vocab_func, totensor, @@ -75,7 +75,7 @@ def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, split_): if tokenizer is None: tokenizer = get_tokenizer("basic_english") text_transform = sequential_transforms(tokenizer, ngrams_func(ngrams)) - split = check_default_set(split_, ('train', 'test'), dataset_name) + split = _check_default_set(split_, ('train', 'test'), dataset_name) raw_datasets = raw.DATASETS[dataset_name](root=root, split=split) # Materialize raw text iterable dataset raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} @@ -94,7 +94,7 @@ def _setup_datasets(dataset_name, root, ngrams, vocab, tokenizer, split_): else: label_transform = sequential_transforms(totensor(dtype=torch.long)) logger_.info('Building datasets for {}'.format(split)) - return wrap_datasets(tuple( + return _wrap_datasets(tuple( TextClassificationDataset( raw_data[item], vocab, (label_transform, text_transform) ) diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index 859a6f352a..c25fc0728e 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -1,8 +1,9 @@ import torch import logging -from torchtext.data.datasets_utils import check_default_set -from torchtext.data.datasets_utils import wrap_datasets +from torchtext.data.datasets_utils import _check_default_set +from torchtext.data.datasets_utils import _wrap_datasets from torchtext import datasets as raw +from torchtext.experimental.datasets import raw as experimental_raw from torchtext.vocab import Vocab, build_vocab_from_iterator from torchtext.data.utils import get_tokenizer from ..functional import vocab_func, totensor, sequential_transforms @@ -19,7 +20,7 @@ def apply_transforms(data): def _setup_datasets(dataset_name, split_, root, vocab, tokenizer, **kwargs): - split = check_default_set(split_, ('train', 'valid', 'test'), dataset_name) + split = _check_default_set(split_, ('train', 'valid', 'test'), dataset_name) src_vocab, tgt_vocab = vocab if tokenizer is None: src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') @@ -35,7 +36,10 @@ def _setup_datasets(dataset_name, "tokenizer must be an instance of tuple with length two" "or None") - raw_datasets = raw.DATASETS[dataset_name](split=split, root=root, **kwargs) + if dataset_name == 'Multi30k' or dataset_name == 'WMT14': + raw_datasets = experimental_raw.DATASETS[dataset_name](split=split, root=root, **kwargs) + else: + raw_datasets = raw.DATASETS[dataset_name](split=split, root=root, **kwargs) raw_data = {name: list(raw_dataset) for name, raw_dataset in zip(split, raw_datasets)} src_text_vocab_transform = sequential_transforms(src_tokenizer) tgt_text_vocab_transform = sequential_transforms(tgt_tokenizer) @@ -77,7 +81,7 @@ def _setup_datasets(dataset_name, TranslationDataset(raw_data[key], (src_vocab, tgt_vocab), (src_text_transform, tgt_text_transform))) - return wrap_datasets(tuple(datasets), split_) + return _wrap_datasets(tuple(datasets), split_) class TranslationDataset(torch.utils.data.Dataset): @@ -131,9 +135,11 @@ def get_vocab(self): return self.vocab -def Multi30k(train_filenames=("train.de", "train.en"), - valid_filenames=("val.de", "val.en"), - test_filenames=("test_2016_flickr.de", "test_2016_flickr.en"), +def Multi30k(task='task1', + language_pair=('de', 'en'), + train_set="train", + valid_set="val", + test_set="test_2016_flickr", split=('train', 'valid', 'test'), root='.data', vocab=(None, None), @@ -141,13 +147,41 @@ def Multi30k(train_filenames=("train.de", "train.en"), """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple + The available datasets include following: + + **Language pairs (task1)**: + + +-----+-----+-----+-----+-----+ + | |'en' |'cs' |'de' |'fr' | + +-----+-----+-----+-----+-----+ + |'en' | | x | x | x | + +-----+-----+-----+-----+-----+ + |'cs' | x | | x | x | + +-----+-----+-----+-----+-----+ + |'de' | x | x | | x | + +-----+-----+-----+-----+-----+ + |'fr' | x | x | x | | + +-----+-----+-----+-----+-----+ + + **Language pairs (task2)**: + + +-----+-----+-----+ + | |'en' |'de' | + +-----+-----+-----+ + |'en' | | x | + +-----+-----+-----+ + |'de' | x | | + +-----+-----+-----+ + + For additional details refer to source: https://github.com/multi30k/dataset + + Args: - train_filenames: the source and target filenames for training. - Default: ('train.de', 'train.en') - valid_filenames: the source and target filenames for valid. - Default: ('val.de', 'val.en') - test_filenames: the source and target filenames for test. - Default: ('test2016.de', 'test2016.en') + task: Indicate the task + language_pair: tuple or list containing src and tgt language + train_set: A string to identify train set. + valid_set: A string to identify validation set. + test_set: A string to identify test set. split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -163,57 +197,6 @@ def Multi30k(train_filenames=("train.de", "train.en"), Default: (get_tokenizer("spacy", language='de_core_news_sm'), get_tokenizer("spacy", language='en_core_web_sm')) - The available dataset include: - - test_2016_flickr.cs - test_2016_flickr.de - test_2016_flickr.en - test_2016_flickr.fr - test_2017_flickr.de - test_2017_flickr.en - test_2017_flickr.fr - test_2017_mscoco.de - test_2017_mscoco.en - test_2017_mscoco.fr - test_2018_flickr.en - train.cs - train.de - train.en - train.fr - val.cs - val.de - val.en - val.fr - test_2016.1.de - test_2016.1.en - test_2016.2.de - test_2016.2.en - test_2016.3.de - test_2016.3.en - test_2016.4.de - test_2016.4.en - test_2016.5.de - test_2016.5.en - train.1.de - train.1.en - train.2.de - train.2.en - train.3.de - train.3.en - train.4.de - train.4.en - train.5.de - train.5.en - val.1.de - val.1.en - val.2.de - val.2.en - val.3.de - val.3.en - val.4.de - val.4.en - val.5.de - val.5.en Examples: >>> from torchtext.experimental.datasets import Multi30k @@ -225,9 +208,11 @@ def Multi30k(train_filenames=("train.de", "train.en"), >>> src_data, tgt_data = train_dataset[10] """ return _setup_datasets("Multi30k", split, root, vocab, tokenizer, - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames) + task=task, + language_pair=language_pair, + train_set=train_set, + valid_set=valid_set, + test_set=test_set) def IWSLT2017(language_pair=('de', 'en'), @@ -240,10 +225,21 @@ def IWSLT2017(language_pair=('de', 'en'), The available datasets include following: - **Language pairs**: [('en', 'nl'), ('en', 'de'), ('en', 'it'), ('en', 'ro'), ('ro', 'de'), - ('ro', 'en'), ('ro', 'nl'), ('ro', 'it'), ('de', 'ro'), ('de', 'en'), - ('de', 'nl'), ('de', 'it'), ('it', 'en'), ('it', 'nl'), ('it', 'de'), - ('it', 'ro'), ('nl', 'de'), ('nl', 'en'), ('nl', 'it'), ('nl', 'ro')] + **Language pairs**: + + +-----+-----+-----+-----+-----+-----+ + | |'en' |'nl' |'de' |'it' |'ro' | + +-----+-----+-----+-----+-----+-----+ + |'en' | | x | x | x | x | + +-----+-----+-----+-----+-----+-----+ + |'nl' | x | | x | x | x | + +-----+-----+-----+-----+-----+-----+ + |'de' | x | x | | x | x | + +-----+-----+-----+-----+-----+-----+ + |'it' | x | x | x | | x | + +-----+-----+-----+-----+-----+-----+ + |'ro' | x | x | x | x | | + +-----+-----+-----+-----+-----+-----+ For additional details refer to source website: https://wit3.fbk.eu/2017-01 @@ -295,8 +291,21 @@ def IWSLT2016(language_pair=('de', 'en'), The available datasets include following: - **Language pairs**: [('en', 'ar'), ('en', 'de'), ('en', 'fr'), ('en', 'cs'), ('ar', 'en'), - ('fr', 'en'), ('de', 'en'), ('cs', 'en')] + **Language pairs**: + + +-----+-----+-----+-----+-----+-----+ + | |'en' |'fr' |'de' |'cs' |'ar' | + +-----+-----+-----+-----+-----+-----+ + |'en' | | x | x | x | x | + +-----+-----+-----+-----+-----+-----+ + |'fr' | x | | | | | + +-----+-----+-----+-----+-----+-----+ + |'de' | x | | | | | + +-----+-----+-----+-----+-----+-----+ + |'cs' | x | | | | | + +-----+-----+-----+-----+-----+-----+ + |'ar' | x | | | | | + +-----+-----+-----+-----+-----+-----+ **valid/test sets**: ['dev2010', 'tst2010', 'tst2011', 'tst2012', 'tst2013', 'tst2014'] @@ -341,78 +350,35 @@ def IWSLT2016(language_pair=('de', 'en'), return _setup_datasets("IWSLT2016", split, root, vocab, tokenizer, language_pair=language_pair, valid_set=valid_set, test_set=test_set) -def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', - 'train.tok.clean.bpe.32000.en'), - valid_filenames=('newstest2013.tok.bpe.32000.de', - 'newstest2013.tok.bpe.32000.en'), - test_filenames=('newstest2014.tok.bpe.32000.de', - 'newstest2014.tok.bpe.32000.en'), +def WMT14(language_pair=('de', 'en'), + train_set='train.tok.clean.bpe.32000', + valid_set='newstest2013.tok.bpe.32000', + test_set='newstest2014.tok.bpe.32000', split=('train', 'valid', 'test'), root='.data', vocab=(None, None), tokenizer=None): """ Define translation datasets: WMT14 Separately returns train/valid/test datasets - The available datasets include: - - newstest2016.en - newstest2016.de - newstest2015.en - newstest2015.de - newstest2014.en - newstest2014.de - newstest2013.en - newstest2013.de - newstest2012.en - newstest2012.de - newstest2011.tok.de - newstest2011.en - newstest2011.de - newstest2010.tok.de - newstest2010.en - newstest2010.de - newstest2009.tok.de - newstest2009.en - newstest2009.de - newstest2016.tok.de - newstest2015.tok.de - newstest2014.tok.de - newstest2013.tok.de - newstest2012.tok.de - newstest2010.tok.en - newstest2009.tok.en - newstest2015.tok.en - newstest2014.tok.en - newstest2013.tok.en - newstest2012.tok.en - newstest2011.tok.en - newstest2016.tok.en - newstest2009.tok.bpe.32000.en - newstest2011.tok.bpe.32000.en - newstest2010.tok.bpe.32000.en - newstest2013.tok.bpe.32000.en - newstest2012.tok.bpe.32000.en - newstest2015.tok.bpe.32000.en - newstest2014.tok.bpe.32000.en - newstest2016.tok.bpe.32000.en - train.tok.clean.bpe.32000.en - newstest2009.tok.bpe.32000.de - newstest2010.tok.bpe.32000.de - newstest2011.tok.bpe.32000.de - newstest2013.tok.bpe.32000.de - newstest2012.tok.bpe.32000.de - newstest2014.tok.bpe.32000.de - newstest2016.tok.bpe.32000.de - newstest2015.tok.bpe.32000.de - train.tok.clean.bpe.32000.de + + The available datasets include following: + + **Language pairs**: + + +-----+-----+-----+ + | |'en' |'de' | + +-----+-----+-----+ + |'en' | | x | + +-----+-----+-----+ + |'de' | x | | + +-----+-----+-----+ + Args: - train_filenames: the source and target filenames for training. - Default: ('train.tok.clean.bpe.32000.de', 'train.tok.clean.bpe.32000.en') - valid_filenames: the source and target filenames for valid. - Default: ('newstest2013.tok.bpe.32000.de', 'newstest2013.tok.bpe.32000.en') - test_filenames: the source and target filenames for test. - Default: ('newstest2014.tok.bpe.32000.de', 'newstest2014.tok.bpe.32000.en') + language_pair: tuple or list containing src and tgt language + train_set: A string to identify train set. + valid_set: A string to identify validation set. + test_set: A string to identify test set. split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -440,9 +406,10 @@ def WMT14(train_filenames=('train.tok.clean.bpe.32000.de', """ return _setup_datasets("WMT14", split, root, vocab, tokenizer, - train_filenames=train_filenames, - valid_filenames=valid_filenames, - test_filenames=test_filenames) + language_pair=language_pair, + train_set=train_set, + valid_set=valid_set, + test_set=test_set) DATASETS = {'Multi30k': Multi30k, 'IWSLT2016': IWSLT2016, 'IWSLT2017': IWSLT2017, 'WMT14': WMT14} diff --git a/torchtext/legacy/README.rst b/torchtext/legacy/README.rst new file mode 100644 index 0000000000..41fac9ecf6 --- /dev/null +++ b/torchtext/legacy/README.rst @@ -0,0 +1,53 @@ +Legacy +====== + +In v0.9.0 release, we move the following legacy code to `torchtext.legacy <#legacy>`_. This is part of the work to revamp the torchtext library and the motivation has been discussed in `Issue #664 `_: + +* ``torchtext.legacy.data.field`` +* ``torchtext.legacy.data.batch`` +* ``torchtext.legacy.data.example`` +* ``torchtext.legacy.data.iterator`` +* ``torchtext.legacy.data.pipeline`` +* ``torchtext.legacy.datasets`` + +We have a `migration tutorial `_ to help users switch to the torchtext datasets in ``v0.9.0`` release. For the users who still want the legacy components, they can add ``legacy`` to the import path. + +Another option is to import ``torchtext.legacy`` as ``torchtext``. For example: + +With `torchtext v0.8.1` + + .. code-block:: python + + >>> import torchtext + >>> import torch + + >>> TEXT = torchtext.data.Field(tokenize=torchtext.data.get_tokenizer('basic_english'), + init_token='', eos_token='', lower=True) + >>> LABEL = torchtext.data.LabelField(dtype = torch.long) + >>> train_split, test_split = torchtext.datasets.IMDB.splits(TEXT, LABEL) + >>> TEXT.build_vocab(train_split) + >>> LABEL.build_vocab(train_split) + + >>> device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + >>> train_iterator, test_iterator = torchtext.data.Iterator.splits( + (train_split, test_split), batch_size=8, device = device) + >>> next(iter(train_iterator)) + +With `torchtext v0.9.0` + + .. code-block:: python + + >>> import torchtext.legacy as torchtext # need to change only one line + >>> import torch + + >>> TEXT = torchtext.data.Field(tokenize=torchtext.data.get_tokenizer('basic_english'), + init_token='', eos_token='', lower=True) + >>> LABEL = torchtext.data.LabelField(dtype = torch.long) + >>> train_split, test_split = torchtext.datasets.IMDB.splits(TEXT, LABEL) + >>> TEXT.build_vocab(train_split) + >>> LABEL.build_vocab(train_split) + + >>> device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + >>> train_iterator, test_iterator = torchtext.data.Iterator.splits( + (train_split, test_split), batch_size=8, device = device) + >>> next(iter(train_iterator)) diff --git a/torchtext/legacy/data/__init__.py b/torchtext/legacy/data/__init__.py index 45c57f06c5..3c84a2ef11 100644 --- a/torchtext/legacy/data/__init__.py +++ b/torchtext/legacy/data/__init__.py @@ -5,8 +5,11 @@ from .pipeline import Pipeline from .dataset import Dataset, TabularDataset # Those are not in the legacy folder. +from ...data import metrics from ...data.metrics import bleu_score +from ...data import utils from ...data.utils import get_tokenizer, interleave_keys +from ...data import functional from ...data.functional import generate_sp_model, \ load_sp_model, \ sentencepiece_numericalizer, \ @@ -20,8 +23,11 @@ "batch", "BucketIterator", "Iterator", "BPTTIterator", "pool", "Pipeline", "Dataset", "TabularDataset", + "metrics", "bleu_score", + "utils", "get_tokenizer", "interleave_keys", + "functional", "generate_sp_model", "load_sp_model", "sentencepiece_numericalizer", "sentencepiece_tokenizer", "custom_replace", "simple_space_split", diff --git a/torchtext/legacy/data/dataset.py b/torchtext/legacy/data/dataset.py index d4da009c81..3af51df910 100644 --- a/torchtext/legacy/data/dataset.py +++ b/torchtext/legacy/data/dataset.py @@ -221,12 +221,12 @@ def __init__(self, path, format, fields, skip_header=False, csv_reader_params=None, **kwargs): """Create a TabularDataset given a path, file format, and field list. - Arguments: + Args: path (str): Path to the data file. format (str): The format of the data file. One of "CSV", "TSV", or "JSON" (case-insensitive). - fields (list(tuple(str, Field)) or dict[str: tuple(str, Field)]: - If using a list, the format must be CSV or TSV, and the values of the list + fields ((list(tuple(str, Field)) or dict[str: tuple(str, Field)): If using a list, + the format must be CSV or TSV, and the values of the list should be tuples of (name, field). The fields should be in the same order as the columns in the CSV or TSV file, while tuples of (name, None) represent columns that will be ignored. @@ -242,6 +242,7 @@ def __init__(self, path, format, fields, skip_header=False, See https://docs.python.org/3/library/csv.html#csv.reader for more details. + kwargs (dict): passed to the Dataset parent class. """ if csv_reader_params is None: csv_reader_params = {} diff --git a/torchtext/legacy/data/field.py b/torchtext/legacy/data/field.py index c6f3ce3490..39da51da72 100644 --- a/torchtext/legacy/data/field.py +++ b/torchtext/legacy/data/field.py @@ -309,8 +309,8 @@ def numericalize(self, arr, device=None): included in the return value. Arguments: - arr (List[List[str]], or tuple of (List[List[str]], List[int])): - List of tokenized and padded examples, or tuple of List of + arr (List[List[str]], or tuple of (List[List[str]], List[int])): List of tokenized + and padded examples, or tuple of List of tokenized and padded examples and List of lengths of each example if self.include_lengths is True. device (str or torch.device): A string or instance of `torch.device` @@ -692,7 +692,7 @@ def numericalize(self, arrs, device=None): tensors will be stacked at the first dimension. Arguments: - arr (List[List[str]]): List of tokenized and padded examples. + arrs (List[List[str]]): List of tokenized and padded examples. device (str or torch.device): A string or instance of `torch.device` specifying which device the Variables are going to be created on. If left as default, the tensors will be created on cpu. Default: None. diff --git a/torchtext/legacy/datasets/language_modeling.py b/torchtext/legacy/datasets/language_modeling.py index ab297ca815..5349c6b7b1 100644 --- a/torchtext/legacy/datasets/language_modeling.py +++ b/torchtext/legacy/datasets/language_modeling.py @@ -14,7 +14,8 @@ def __init__(self, path, text_field, newline_eos=True, text_field: The field that will be used for text data. newline_eos: Whether to add an token for every newline in the data file. Default: True. - Remaining keyword arguments: Passed to the constructor of + encoding: The encoding of the file. + kwargs: Passed to the constructor of data.Dataset. """ fields = [('text', text_field)] @@ -75,10 +76,10 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-2 subdirectory the data files will be stored. - wv_dir, wv_type, wv_dim: Passed to the Vocab constructor for the - text field. The word vectors are accessible as - train.dataset.fields['text'].vocab.vectors. - Remaining keyword arguments: Passed to the splits method. + vectors: One of either the available pretrained vectors + or custom pretrained vectors (see Vocab.load_vectors); + or a list of aforementioned vectors + kwargs: Passed to the splits method. """ TEXT = data.Field() @@ -136,10 +137,10 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', root: The root directory that the dataset's zip archive will be expanded into; therefore the directory in whose wikitext-2 subdirectory the data files will be stored. - wv_dir, wv_type, wv_dim: Passed to the Vocab constructor for the - text field. The word vectors are accessible as - train.dataset.fields['text'].vocab.vectors. - Remaining keyword arguments: Passed to the splits method. + vectors: One of either the available pretrained vectors + or custom pretrained vectors (see Vocab.load_vectors); + or a list of aforementioned vectors + kwargs: Passed to the splits method. """ TEXT = data.Field() @@ -200,10 +201,10 @@ def iters(cls, batch_size=32, bptt_len=35, device=0, root='.data', device: Device to create batches on. Use -1 for CPU and None for the currently active GPU device. root: The root directory where the data files will be stored. - wv_dir, wv_type, wv_dim: Passed to the Vocab constructor for the - text field. The word vectors are accessible as - train.dataset.fields['text'].vocab.vectors. - Remaining keyword arguments: Passed to the splits method. + vectors: One of either the available pretrained vectors + or custom pretrained vectors (see Vocab.load_vectors); + or a list of aforementioned vectors + kwargs: Passed to the splits method. """ TEXT = data.Field() diff --git a/torchtext/nn/modules/multiheadattention.py b/torchtext/nn/modules/multiheadattention.py index aac7419d0b..b581d245c4 100644 --- a/torchtext/nn/modules/multiheadattention.py +++ b/torchtext/nn/modules/multiheadattention.py @@ -48,27 +48,39 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, r""" Args: - query, key, value (Tensor): map a query and a set of key-value pairs to an output. + query (Tensor): The query of the attention function. See "Attention Is All You Need" for more details. - attn_mask, bias_k and bias_v (Tensor, optional): keyword arguments passed to the attention layer. - See the definitions in the attention. + key (Tensor): The keys of the attention function. + See "Attention Is All You Need" for more details. + value (Tensor): The values of the attention function. + See "Attention Is All You Need" for more details. + attn_mask (BoolTensor, optional): 3D mask that prevents attention to certain positions. + bias_k (Tensor, optional): one more key and value sequence to be added to keys at + sequence dim (dim=-3). Those are used for incremental decoding. Users should provide + ``bias_v``. + bias_v (Tensor, optional): one more key and value sequence to be added to values at + sequence dim (dim=-3). Those are used for incremental decoding. Users should also provide + ``bias_k``. Shape: + - Inputs: - - query: :math:`(..., L, N, E)` - - key: :math:`(..., S, N, E)` - - value: :math:`(..., S, N, E)` - - attn_mask, bias_k and bias_v: same with the shape of the corresponding args in attention layer. + + - query: :math:`(..., L, N, E)` + - key: :math:`(..., S, N, E)` + - value: :math:`(..., S, N, E)` + - attn_mask, bias_k and bias_v: same with the shape of the corresponding args in attention layer. - Outputs: - - attn_output: :math:`(..., L, N, E)` - - attn_output_weights: :math:`(N * H, L, S)` + + - attn_output: :math:`(..., L, N, E)` + - attn_output_weights: :math:`(N * H, L, S)` Note: It's optional to have the query/key/value inputs with more than three dimensions (for broadcast purpose). - The MultiheadAttentionContainer module will operate on the last three dimensions. + The MultiheadAttentionContainer module will operate on the last three dimensions. where where L is the target length, S is the sequence length, H is the number of attention heads, - N is the batch size, and E is the embedding dimension. + N is the batch size, and E is the embedding dimension. """ if self.batch_first: query, key, value = query.transpose(-3, -2), key.transpose(-3, -2), value.transpose(-3, -2) @@ -133,9 +145,13 @@ def forward(self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, key (Tensor): Projected key value (Tensor): Projected value attn_mask (BoolTensor, optional): 3D mask that prevents attention to certain positions. - bias_k and bias_v: (Tensor, optional): one more key and value sequence to be added at + attn_mask (BoolTensor, optional): 3D mask that prevents attention to certain positions. + bias_k (Tensor, optional): one more key and value sequence to be added to keys at sequence dim (dim=-3). Those are used for incremental decoding. Users should provide - non-None to both arguments in order to activate them. + ``bias_v``. + bias_v (Tensor, optional): one more key and value sequence to be added to values at + sequence dim (dim=-3). Those are used for incremental decoding. Users should also provide + ``bias_k``. Shape: - query: :math:`(..., L, N * H, E / H)` @@ -224,7 +240,9 @@ def forward(self, the forward func of query/key/value_proj, respectively. Args: - query, key, value (Tensors): sequence to be projected + query (Tensor): The query to be projected. + key (Tensor): The keys to be projected. + value (Tensor): The values to be projected. Examples:: >>> from torchtext.nn import InProjContainer From 03c91d4516cc0da72f1144be7bb7a98a8393e0c5 Mon Sep 17 00:00:00 2001 From: George Guanheng Zhang Date: Tue, 9 Mar 2021 14:30:50 -0800 Subject: [PATCH 51/68] Re-name raw_datasets.json file with jsonl extension Reviewed By: cpuhrsch Differential Revision: D26923978 fbshipit-source-id: c87c7776445e05d452f6b38244bf4cdaba45bdec --- test/asset/{raw_datasets.json => raw_datasets.jsonl} | 0 test/common/cache_utils.py | 2 +- test/data/test_builtin_datasets.py | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename test/asset/{raw_datasets.json => raw_datasets.jsonl} (100%) diff --git a/test/asset/raw_datasets.json b/test/asset/raw_datasets.jsonl similarity index 100% rename from test/asset/raw_datasets.json rename to test/asset/raw_datasets.jsonl diff --git a/test/common/cache_utils.py b/test/common/cache_utils.py index 982ebcfadd..404dbd0d24 100644 --- a/test/common/cache_utils.py +++ b/test/common/cache_utils.py @@ -21,7 +21,7 @@ def generate_data_cache(): if os.path.exists(CACHE_STATUS_FILE): return - raw_data_info = load_params('raw_datasets.json') + raw_data_info = load_params('raw_datasets.jsonl') cache_status = {} for info in raw_data_info: info = info.args[0] diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 29c4c9581f..278ef49c96 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -156,7 +156,7 @@ def test_raw_ag_news(self): del train_iter, test_iter @parameterized.expand( - load_params('raw_datasets.json'), + load_params('raw_datasets.jsonl'), name_func=_raw_text_custom_name_func) def test_raw_text_name_property(self, info): dataset_name = info['dataset_name'] @@ -170,7 +170,7 @@ def test_raw_text_name_property(self, info): self.assertEqual(str(data_iter), dataset_name) @parameterized.expand( - load_params('raw_datasets.json'), + load_params('raw_datasets.jsonl'), name_func=_raw_text_custom_name_func) def test_raw_text_classification(self, info): dataset_name = info['dataset_name'] From 066200caf2d2dd59e7882b6f1f80f2105649e08a Mon Sep 17 00:00:00 2001 From: Jeff Hwang Date: Mon, 29 Mar 2021 12:58:01 -0700 Subject: [PATCH 52/68] 20210329 Sync torchtext up to GH commit eb5e39d3d40525c0064c8e7b7c976755e7341a8b Summary: Sync torchtext up to GH commit eb5e39d3d40525c0064c8e7b7c976755e7341a8b Reviewed By: parmeet Differential Revision: D27400885 fbshipit-source-id: 1f8f92ca42ba36d070db6740b3bb4c148f69586b --- .circleci/config.yml | 384 +++++++++++++++--- .circleci/config.yml.in | 185 ++++++--- .circleci/regenerate.py | 23 +- .../unittest/linux/scripts/environment.yml | 3 +- .circleci/unittest/linux/scripts/install.sh | 5 +- .../unittest/windows/scripts/environment.yml | 3 +- .circleci/unittest/windows/scripts/install.sh | 5 +- benchmark/benchmark_experimental_vocab.py | 12 +- examples/data_pipeline/README.md | 12 +- examples/data_pipeline/dataset.py | 4 +- examples/data_pipeline/pipelines.py | 74 ++-- examples/text_classification/train.py | 2 +- test/asset/raw_datasets.jsonl | 98 ++--- test/data/test_builtin_datasets.py | 4 +- torchtext/csrc/register_bindings.cpp | 243 ++++++----- torchtext/csrc/vocab.cpp | 119 +++--- torchtext/csrc/vocab.h | 43 +- torchtext/data/__init__.py | 4 +- .../experimental/datasets/translation.py | 14 +- 19 files changed, 836 insertions(+), 401 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f18b086090..bb04316f56 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,6 +29,31 @@ commands: our_upload_channel=test fi echo "export UPLOAD_CHANNEL=${our_upload_channel}" >> ${BASH_ENV} + load_conda_channel_flags: + description: "Determines whether we need extra conda channels" + steps: + - run: + name: Adding CONDA_CHANNEL_FLAGS to BASH_ENV + command: | + CONDA_CHANNEL_FLAGS="" + if [[ "${PYTHON_VERSION}" = *3.9* ]]; then + echo "export CONDA_CHANNEL_FLAGS=-c=conda-forge" >> ${BASH_ENV} + fi + generate_cachekey: + description: "Generate .cachekey file that changes on daily basis" + steps: + - run: + name: Generate CCI cache key + command: echo "$(date "+%D")" > .cachekey + - persist_to_workspace: + root: . + paths: + - .cachekey + fetch_cachekey: + description: "Fetch the .cachekey file that is generated by generate_cachekey job" + steps: + - attach_workspace: + at: . binary_common: &binary_common parameters: @@ -71,7 +96,7 @@ jobs: binary_linux_wheel: <<: *binary_common docker: - - image: "pytorch/manylinux-cuda100" + - image: "pytorch/manylinux-cuda102" resource_class: 2xlarge+ steps: - checkout @@ -92,6 +117,7 @@ jobs: steps: - checkout - designate_upload_channel + - load_conda_channel_flags - run: packaging/build_conda.sh - store_artifacts: path: /opt/conda/conda-bld/linux-64 @@ -127,12 +153,13 @@ jobs: steps: - checkout - designate_upload_channel + - load_conda_channel_flags - run: name: build command: | eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" conda activate base - conda install -yq conda-build "conda-package-handling!=1.5.0" + conda install ${CONDA_CHANNEL_FLAGS} -yq conda-build "conda-package-handling!=1.5.0" bash packaging/build_conda.sh rm /C/tools/miniconda3/conda-bld/win-64/vs2019*.tar.bz2 - store_artifacts: @@ -175,6 +202,7 @@ jobs: steps: - checkout - designate_upload_channel + - load_conda_channel_flags - run: command: | curl -o conda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh @@ -232,13 +260,14 @@ jobs: - attach_workspace: at: ~/workspace - designate_upload_channel + - load_conda_channel_flags - run: name: install binaries command: | set -x source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} - conda install -v -y -c pytorch-${UPLOAD_CHANNEL} pytorch cpuonly - conda install -v -y -c file://$HOME/workspace/conda-bld torchtext + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c pytorch-${UPLOAD_CHANNEL} pytorch + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c file://$HOME/workspace/conda-bld torchtext - run: name: smoke test command: | @@ -291,6 +320,7 @@ jobs: - attach_workspace: at: ~/workspace - designate_upload_channel + - load_conda_channel_flags - run: name: install binaries command: | @@ -299,8 +329,8 @@ jobs: conda env remove -n python${PYTHON_VERSION} || true conda create -yn python${PYTHON_VERSION} python=${PYTHON_VERSION} conda activate python${PYTHON_VERSION} - conda install -v -y -c pytorch-"${UPLOAD_CHANNEL}" pytorch cpuonly - conda install -v -y -c ~/workspace/conda-bld torchtext + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c pytorch-"${UPLOAD_CHANNEL}" pytorch + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c ~/workspace/conda-bld torchtext - run: name: smoke test command: | @@ -332,40 +362,65 @@ jobs: conda activate python${PYTHON_VERSION} python -c "import torchtext" - unittest_linux: + cachesetup_linux: <<: *binary_common docker: - - image: "pytorch/manylinux-cuda100" + - image: "pytorch/manylinux-cuda102" resource_class: 2xlarge+ steps: - checkout - designate_upload_channel - - run: - name: Generate cache key - # This will refresh cache on Sundays, nightly build should generate new cache. - command: echo "$(date +"%Y-%U")" > .circleci-weekly + - load_conda_channel_flags + - generate_cachekey - restore_cache: - keys: - - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + - v1-linux-cache-index-{{ checksum ".cachekey" }} - run: - name: Setup - command: .circleci/unittest/linux/scripts/setup_env.sh + name: Generate cache + no_output_timeout: 30m + command: | + if [ ! -f .data/cache_status_file.json ] ; then + .circleci/unittest/linux/scripts/setup_env.sh + .circleci/unittest/linux/scripts/install.sh + .circleci/unittest/linux/scripts/generate_cache.sh + fi + cat .data/cache_status_file.json - save_cache: - key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + key: v1-linux-dataset-{{ checksum ".cachekey" }} paths: - - conda - - env + - .data + - save_cache: + + key: v1-linux-cache-index-{{ checksum ".cachekey" }} + + paths: + - .data/cache_status_file.json + + unittest_linux: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda102" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - load_conda_channel_flags + - fetch_cachekey + - run: + name: Setup + command: .circleci/unittest/linux/scripts/setup_env.sh - run: name: Install torchtext command: .circleci/unittest/linux/scripts/install.sh - restore_cache: keys: - - data-linux-v1-{{ checksum ".circleci-weekly" }} + - v1-linux-dataset-vector-{{ checksum ".cachekey" }} + - v1-linux-dataset-{{ checksum ".cachekey" }} - run: name: Run tests @@ -374,7 +429,7 @@ jobs: command: .circleci/unittest/linux/scripts/run_test.sh - save_cache: - key: data-linux-v1-{{ checksum ".circleci-weekly" }} + key: v1-linux-dataset-vector-{{ checksum ".cachekey" }} paths: - .vector_cache @@ -385,40 +440,65 @@ jobs: - store_test_results: path: test-results - unittest_windows: + cachesetup_windows: <<: *binary_common executor: name: windows-cpu steps: - checkout - designate_upload_channel - - run: - name: Generate cache key - # This will refresh cache on Sundays, nightly build should generate new cache. - command: echo "$(date +"%Y-%U")" > .circleci-weekly + - load_conda_channel_flags + - generate_cachekey - restore_cache: - keys: - - env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + + - v1-windows-cache-index-{{ checksum ".cachekey" }} - run: - name: Setup - command: .circleci/unittest/windows/scripts/setup_env.sh + name: Generate daily data Cache + no_output_timeout: 30m + command: | + if [ ! -f .data/cache_status_file.json ] ; then + .circleci/unittest/windows/scripts/setup_env.sh + .circleci/unittest/windows/scripts/install.sh + .circleci/unittest/windows/scripts/generate_cache.sh + fi + cat .data/cache_status_file.json + - save_cache: + + key: v1-windows-dataset-{{ checksum ".cachekey" }} + + paths: + - .data - save_cache: - key: env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + key: v1-windows-cache-index-{{ checksum ".cachekey" }} paths: - - conda - - env + - .data/cache_status_file.json + + unittest_windows: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - load_conda_channel_flags + - fetch_cachekey + - run: + name: Setup + command: .circleci/unittest/windows/scripts/setup_env.sh - run: name: Install torchtext command: .circleci/unittest/windows/scripts/install.sh - restore_cache: keys: - - data-windows-v1-{{ checksum ".circleci-weekly" }} + - v1-windows-dataset-vector-{{ checksum ".cachekey" }} + - v1-windows-dataset-{{ checksum ".cachekey" }} + - run: name: Run tests # Downloading embedding vector takes long time. @@ -426,7 +506,7 @@ jobs: command: .circleci/unittest/windows/scripts/run_test.sh - save_cache: - key: data-windows-v1-{{ checksum ".circleci-weekly" }} + key: v1-windows-dataset-vector-{{ checksum ".cachekey" }} paths: - .vector_cache @@ -440,30 +520,14 @@ jobs: stylecheck: <<: *binary_common docker: - - image: "pytorch/manylinux-cuda100" + - image: "pytorch/manylinux-cuda102" resource_class: medium steps: - checkout - designate_upload_channel - - run: - name: Generate cache key - # This will refresh cache on Sundays, nightly build should generate new cache. - command: echo "$(date +"%Y-%U")" > .circleci-weekly - - restore_cache: - - keys: - - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} - - run: name: Setup command: .circleci/unittest/linux/scripts/setup_env.sh - - save_cache: - - key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} - - paths: - - conda - - env - run: name: Run style check command: .circleci/unittest/linux/scripts/run_style_checks.sh @@ -524,6 +588,23 @@ jobs: target=${tag:-master} ~/workspace/.circleci/build_docs/commit_docs.sh ~/workspace $target + docstring_parameters_sync: + <<: *binary_common + docker: + - image: continuumio/miniconda3 + resource_class: medium + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - checkout + - run: + name: Check parameters docstring sync + command: | + pip install --user pydocstyle + export PATH="$HOME/.local/bin:$PATH" + pydocstyle torchtext + workflows: build: @@ -538,6 +619,9 @@ workflows: - binary_linux_wheel: name: binary_linux_wheel_py3.8 python_version: '3.8' + - binary_linux_wheel: + name: binary_linux_wheel_py3.9 + python_version: '3.9' - binary_macos_wheel: name: binary_macos_wheel_py3.6 python_version: '3.6' @@ -547,6 +631,9 @@ workflows: - binary_macos_wheel: name: binary_macos_wheel_py3.8 python_version: '3.8' + - binary_macos_wheel: + name: binary_macos_wheel_py3.9 + python_version: '3.9' - binary_windows_wheel: name: binary_windows_wheel_py3.6 python_version: '3.6' @@ -556,6 +643,9 @@ workflows: - binary_windows_wheel: name: binary_windows_wheel_py3.8 python_version: '3.8' + - binary_windows_wheel: + name: binary_windows_wheel_py3.9 + python_version: '3.9' - binary_linux_conda: name: binary_linux_conda_py3.6 python_version: '3.6' @@ -565,6 +655,9 @@ workflows: - binary_linux_conda: name: binary_linux_conda_py3.8 python_version: '3.8' + - binary_linux_conda: + name: binary_linux_conda_py3.9 + python_version: '3.9' - binary_macos_conda: name: binary_macos_conda_py3.6 python_version: '3.6' @@ -574,6 +667,9 @@ workflows: - binary_macos_conda: name: binary_macos_conda_py3.8 python_version: '3.8' + - binary_macos_conda: + name: binary_macos_conda_py3.9 + python_version: '3.9' - binary_windows_conda: name: binary_windows_conda_py3.6 python_version: '3.6' @@ -583,6 +679,9 @@ workflows: - binary_windows_conda: name: binary_windows_conda_py3.8 python_version: '3.8' + - binary_windows_conda: + name: binary_windows_conda_py3.9 + python_version: '3.9' - build_docs: name: build_docs python_version: '3.8' @@ -599,29 +698,62 @@ workflows: python_version: '3.8' requires: - build_docs + - docstring_parameters_sync: + name: docstring_parameters_sync + python_version: '3.8' + requires: + - binary_linux_wheel_py3.8 unittest: jobs: + - cachesetup_linux: + name: cachesetup_linux_py_any + python_version: '3.6' - unittest_linux: name: unittest_linux_py3.6 python_version: '3.6' + requires: + - cachesetup_linux_py_any - stylecheck: name: stylecheck_py3.6 python_version: '3.6' - unittest_linux: name: unittest_linux_py3.7 python_version: '3.7' + requires: + - cachesetup_linux_py_any - unittest_linux: name: unittest_linux_py3.8 python_version: '3.8' + requires: + - cachesetup_linux_py_any + - unittest_linux: + name: unittest_linux_py3.9 + python_version: '3.9' + requires: + - cachesetup_linux_py_any + - cachesetup_windows: + name: cachesetup_windows_py_any + python_version: '3.6' - unittest_windows: name: unittest_windows_py3.6 python_version: '3.6' + requires: + - cachesetup_windows_py_any - unittest_windows: name: unittest_windows_py3.7 python_version: '3.7' + requires: + - cachesetup_windows_py_any - unittest_windows: name: unittest_windows_py3.8 python_version: '3.8' + requires: + - cachesetup_windows_py_any + - unittest_windows: + name: unittest_windows_py3.9 + python_version: '3.9' + requires: + - cachesetup_windows_py_any nightly: jobs: - circleci_consistency: @@ -712,6 +844,34 @@ workflows: python_version: '3.8' requires: - nightly_binary_linux_wheel_py3.8_upload + - binary_linux_wheel: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_linux_wheel_py3.9 + python_version: '3.9' + - binary_wheel_upload: + context: org-member + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_linux_wheel_py3.9_upload + requires: + - nightly_binary_linux_wheel_py3.9 + - smoke_test_linux_pip: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_linux_wheel_py3.9_smoke_test_pip + python_version: '3.9' + requires: + - nightly_binary_linux_wheel_py3.9_upload - binary_macos_wheel: filters: branches: @@ -766,6 +926,24 @@ workflows: name: nightly_binary_macos_wheel_py3.8_upload requires: - nightly_binary_macos_wheel_py3.8 + - binary_macos_wheel: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_macos_wheel_py3.9 + python_version: '3.9' + - binary_wheel_upload: + context: org-member + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_macos_wheel_py3.9_upload + requires: + - nightly_binary_macos_wheel_py3.9 - binary_windows_wheel: filters: branches: @@ -850,6 +1028,34 @@ workflows: python_version: '3.8' requires: - nightly_binary_windows_wheel_py3.8_upload + - binary_windows_wheel: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_windows_wheel_py3.9 + python_version: '3.9' + - binary_wheel_upload: + context: org-member + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_windows_wheel_py3.9_upload + requires: + - nightly_binary_windows_wheel_py3.9 + - smoke_test_windows_pip: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_windows_wheel_py3.9_smoke_test_pip + python_version: '3.9' + requires: + - nightly_binary_windows_wheel_py3.9_upload - binary_linux_conda: filters: branches: @@ -934,6 +1140,34 @@ workflows: python_version: '3.8' requires: - nightly_binary_linux_conda_py3.8_upload + - binary_linux_conda: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_linux_conda_py3.9 + python_version: '3.9' + - binary_conda_upload: + context: org-member + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_linux_conda_py3.9_upload + requires: + - nightly_binary_linux_conda_py3.9 + - smoke_test_linux_conda: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_linux_conda_py3.9_smoke_test_conda + python_version: '3.9' + requires: + - nightly_binary_linux_conda_py3.9_upload - binary_macos_conda: filters: branches: @@ -988,6 +1222,24 @@ workflows: name: nightly_binary_macos_conda_py3.8_upload requires: - nightly_binary_macos_conda_py3.8 + - binary_macos_conda: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_macos_conda_py3.9 + python_version: '3.9' + - binary_conda_upload: + context: org-member + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_macos_conda_py3.9_upload + requires: + - nightly_binary_macos_conda_py3.9 - binary_windows_conda: filters: branches: @@ -1072,6 +1324,34 @@ workflows: python_version: '3.8' requires: - nightly_binary_windows_conda_py3.8_upload + - binary_windows_conda: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_windows_conda_py3.9 + python_version: '3.9' + - binary_conda_upload: + context: org-member + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_windows_conda_py3.9_upload + requires: + - nightly_binary_windows_conda_py3.9 + - smoke_test_windows_conda: + filters: + branches: + only: nightly + tags: + only: /v[0-9]+(\.[0-9]+)*-rc[0-9]+/ + name: nightly_binary_windows_conda_py3.9_smoke_test_conda + python_version: '3.9' + requires: + - nightly_binary_windows_conda_py3.9_upload docker_build: triggers: - schedule: diff --git a/.circleci/config.yml.in b/.circleci/config.yml.in index 12c4c242bd..e83a4e8c33 100644 --- a/.circleci/config.yml.in +++ b/.circleci/config.yml.in @@ -29,6 +29,31 @@ commands: our_upload_channel=test fi echo "export UPLOAD_CHANNEL=${our_upload_channel}" >> ${BASH_ENV} + load_conda_channel_flags: + description: "Determines whether we need extra conda channels" + steps: + - run: + name: Adding CONDA_CHANNEL_FLAGS to BASH_ENV + command: | + CONDA_CHANNEL_FLAGS="" + if [[ "${PYTHON_VERSION}" = *3.9* ]]; then + echo "export CONDA_CHANNEL_FLAGS=-c=conda-forge" >> ${BASH_ENV} + fi + generate_cachekey: + description: "Generate .cachekey file that changes on daily basis" + steps: + - run: + name: Generate CCI cache key + command: echo "$(date "+%D")" > .cachekey + - persist_to_workspace: + root: . + paths: + - .cachekey + fetch_cachekey: + description: "Fetch the .cachekey file that is generated by generate_cachekey job" + steps: + - attach_workspace: + at: . binary_common: &binary_common parameters: @@ -71,7 +96,7 @@ jobs: binary_linux_wheel: <<: *binary_common docker: - - image: "pytorch/manylinux-cuda100" + - image: "pytorch/manylinux-cuda102" resource_class: 2xlarge+ steps: - checkout @@ -92,6 +117,7 @@ jobs: steps: - checkout - designate_upload_channel + - load_conda_channel_flags - run: packaging/build_conda.sh - store_artifacts: path: /opt/conda/conda-bld/linux-64 @@ -127,12 +153,13 @@ jobs: steps: - checkout - designate_upload_channel + - load_conda_channel_flags - run: name: build command: | eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')" conda activate base - conda install -yq conda-build "conda-package-handling!=1.5.0" + conda install ${CONDA_CHANNEL_FLAGS} -yq conda-build "conda-package-handling!=1.5.0" bash packaging/build_conda.sh rm /C/tools/miniconda3/conda-bld/win-64/vs2019*.tar.bz2 - store_artifacts: @@ -175,6 +202,7 @@ jobs: steps: - checkout - designate_upload_channel + - load_conda_channel_flags - run: command: | curl -o conda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh @@ -232,13 +260,14 @@ jobs: - attach_workspace: at: ~/workspace - designate_upload_channel + - load_conda_channel_flags - run: name: install binaries command: | set -x source /usr/local/etc/profile.d/conda.sh && conda activate python${PYTHON_VERSION} - conda install -v -y -c pytorch-${UPLOAD_CHANNEL} pytorch cpuonly - conda install -v -y -c file://$HOME/workspace/conda-bld torchtext + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c pytorch-${UPLOAD_CHANNEL} pytorch + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c file://$HOME/workspace/conda-bld torchtext - run: name: smoke test command: | @@ -291,6 +320,7 @@ jobs: - attach_workspace: at: ~/workspace - designate_upload_channel + - load_conda_channel_flags - run: name: install binaries command: | @@ -299,8 +329,8 @@ jobs: conda env remove -n python${PYTHON_VERSION} || true conda create -yn python${PYTHON_VERSION} python=${PYTHON_VERSION} conda activate python${PYTHON_VERSION} - conda install -v -y -c pytorch-"${UPLOAD_CHANNEL}" pytorch cpuonly - conda install -v -y -c ~/workspace/conda-bld torchtext + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c pytorch-"${UPLOAD_CHANNEL}" pytorch + conda install -v -y ${CONDA_CHANNEL_FLAGS} -c ~/workspace/conda-bld torchtext - run: name: smoke test command: | @@ -332,40 +362,65 @@ jobs: conda activate python${PYTHON_VERSION} python -c "import torchtext" - unittest_linux: + cachesetup_linux: <<: *binary_common docker: - - image: "pytorch/manylinux-cuda100" + - image: "pytorch/manylinux-cuda102" resource_class: 2xlarge+ steps: - checkout - designate_upload_channel - - run: - name: Generate cache key - # This will refresh cache on Sundays, nightly build should generate new cache. - command: echo "$(date +"%Y-%U")" > .circleci-weekly + - load_conda_channel_flags + - generate_cachekey - restore_cache: - {% raw %} keys: - - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% raw %} + - v1-linux-cache-index-{{ checksum ".cachekey" }} {% endraw %} - run: - name: Setup - command: .circleci/unittest/linux/scripts/setup_env.sh + name: Generate cache + no_output_timeout: 30m + command: | + if [ ! -f .data/cache_status_file.json ] ; then + .circleci/unittest/linux/scripts/setup_env.sh + .circleci/unittest/linux/scripts/install.sh + .circleci/unittest/linux/scripts/generate_cache.sh + fi + cat .data/cache_status_file.json - save_cache: {% raw %} - key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + key: v1-linux-dataset-{{ checksum ".cachekey" }} {% endraw %} paths: - - conda - - env + - .data + - save_cache: + {% raw %} + key: v1-linux-cache-index-{{ checksum ".cachekey" }} + {% endraw %} + paths: + - .data/cache_status_file.json + + unittest_linux: + <<: *binary_common + docker: + - image: "pytorch/manylinux-cuda102" + resource_class: 2xlarge+ + steps: + - checkout + - designate_upload_channel + - load_conda_channel_flags + - fetch_cachekey + - run: + name: Setup + command: .circleci/unittest/linux/scripts/setup_env.sh - run: name: Install torchtext command: .circleci/unittest/linux/scripts/install.sh - restore_cache: keys: {% raw %} - - data-linux-v1-{{ checksum ".circleci-weekly" }} + - v1-linux-dataset-vector-{{ checksum ".cachekey" }} + - v1-linux-dataset-{{ checksum ".cachekey" }} {% endraw %} - run: name: Run tests @@ -374,7 +429,7 @@ jobs: command: .circleci/unittest/linux/scripts/run_test.sh - save_cache: {% raw %} - key: data-linux-v1-{{ checksum ".circleci-weekly" }} + key: v1-linux-dataset-vector-{{ checksum ".cachekey" }} {% endraw %} paths: - .vector_cache @@ -385,40 +440,65 @@ jobs: - store_test_results: path: test-results - unittest_windows: + cachesetup_windows: <<: *binary_common executor: name: windows-cpu steps: - checkout - designate_upload_channel - - run: - name: Generate cache key - # This will refresh cache on Sundays, nightly build should generate new cache. - command: echo "$(date +"%Y-%U")" > .circleci-weekly + - load_conda_channel_flags + - generate_cachekey - restore_cache: - {% raw %} keys: - - env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + {% raw %} + - v1-windows-cache-index-{{ checksum ".cachekey" }} {% endraw %} - run: - name: Setup - command: .circleci/unittest/windows/scripts/setup_env.sh + name: Generate daily data Cache + no_output_timeout: 30m + command: | + if [ ! -f .data/cache_status_file.json ] ; then + .circleci/unittest/windows/scripts/setup_env.sh + .circleci/unittest/windows/scripts/install.sh + .circleci/unittest/windows/scripts/generate_cache.sh + fi + cat .data/cache_status_file.json + - save_cache: + {% raw %} + key: v1-windows-dataset-{{ checksum ".cachekey" }} + {% endraw %} + paths: + - .data - save_cache: {% raw %} - key: env-v1-windows-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/windows/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} + key: v1-windows-cache-index-{{ checksum ".cachekey" }} {% endraw %} paths: - - conda - - env + - .data/cache_status_file.json + + unittest_windows: + <<: *binary_common + executor: + name: windows-cpu + steps: + - checkout + - designate_upload_channel + - load_conda_channel_flags + - fetch_cachekey + - run: + name: Setup + command: .circleci/unittest/windows/scripts/setup_env.sh - run: name: Install torchtext command: .circleci/unittest/windows/scripts/install.sh - restore_cache: keys: {% raw %} - - data-windows-v1-{{ checksum ".circleci-weekly" }} + - v1-windows-dataset-vector-{{ checksum ".cachekey" }} + - v1-windows-dataset-{{ checksum ".cachekey" }} {% endraw %} + - run: name: Run tests # Downloading embedding vector takes long time. @@ -426,7 +506,7 @@ jobs: command: .circleci/unittest/windows/scripts/run_test.sh - save_cache: {% raw %} - key: data-windows-v1-{{ checksum ".circleci-weekly" }} + key: v1-windows-dataset-vector-{{ checksum ".cachekey" }} {% endraw %} paths: - .vector_cache @@ -440,30 +520,14 @@ jobs: stylecheck: <<: *binary_common docker: - - image: "pytorch/manylinux-cuda100" + - image: "pytorch/manylinux-cuda102" resource_class: medium steps: - checkout - designate_upload_channel - - run: - name: Generate cache key - # This will refresh cache on Sundays, nightly build should generate new cache. - command: echo "$(date +"%Y-%U")" > .circleci-weekly - - restore_cache: - {% raw %} - keys: - - env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} - {% endraw %} - run: name: Setup command: .circleci/unittest/linux/scripts/setup_env.sh - - save_cache: - {% raw %} - key: env-v1-linux-{{ arch }}-py<< parameters.python_version >>-{{ checksum ".circleci/unittest/linux/scripts/environment.yml" }}-{{ checksum ".circleci-weekly" }} - {% endraw %} - paths: - - conda - - env - run: name: Run style check command: .circleci/unittest/linux/scripts/run_style_checks.sh @@ -524,6 +588,23 @@ jobs: target=${tag:-master} ~/workspace/.circleci/build_docs/commit_docs.sh ~/workspace $target + docstring_parameters_sync: + <<: *binary_common + docker: + - image: continuumio/miniconda3 + resource_class: medium + steps: + - attach_workspace: + at: ~/workspace + - designate_upload_channel + - checkout + - run: + name: Check parameters docstring sync + command: | + pip install --user pydocstyle + export PATH="$HOME/.local/bin:$PATH" + pydocstyle torchtext + workflows: build: diff --git a/.circleci/regenerate.py b/.circleci/regenerate.py index 6ab710bdf6..f963469c58 100755 --- a/.circleci/regenerate.py +++ b/.circleci/regenerate.py @@ -19,7 +19,7 @@ import os.path -PYTHON_VERSIONS = ["3.6", "3.7", "3.8"] +PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] DOC_VERSION = ('linux', '3.8') @@ -35,6 +35,7 @@ def build_workflows(prefix='', upload=False, filter_branch=None, indentation=6): # Build on every pull request, but upload only on nightly and tags w += build_doc_job(None) w += upload_doc_job('nightly') + w += docstring_parameters_sync_job(None) return indent(indentation, w) @@ -77,6 +78,18 @@ def upload_doc_job(filter_branch): return [{"upload_docs": job}] +def docstring_parameters_sync_job(filter_branch): + job = { + "name": "docstring_parameters_sync", + "python_version": "3.8", + "requires": ["binary_linux_wheel_py3.8", ], + } + + if filter_branch: + job["filters"] = gen_filter_branch_tree(filter_branch) + return [{"docstring_parameters_sync": job}] + + def generate_base_workflow(base_workflow_name, python_version, filter_branch, os_type, btype): d = { "name": base_workflow_name, @@ -140,11 +153,19 @@ def indent(indentation, data_list): def unittest_workflows(indentation=6): w = [] for os_type in ["linux", "windows"]: + w.append({ + f"cachesetup_{os_type}": { + "name": f"cachesetup_{os_type}_py_any", + "python_version": PYTHON_VERSIONS[0], + } + }) + for i, python_version in enumerate(PYTHON_VERSIONS): w.append({ f"unittest_{os_type}": { "name": f"unittest_{os_type}_py{python_version}", "python_version": python_version, + "requires": [f"cachesetup_{os_type}_py_any"], } }) diff --git a/.circleci/unittest/linux/scripts/environment.yml b/.circleci/unittest/linux/scripts/environment.yml index 282877c207..e1e9f2cda8 100644 --- a/.circleci/unittest/linux/scripts/environment.yml +++ b/.circleci/unittest/linux/scripts/environment.yml @@ -1,7 +1,8 @@ channels: - defaults + - conda-forge dependencies: - - flake8==3.7.9 + - flake8>=3.7.9 - codecov - pip - pip: diff --git a/.circleci/unittest/linux/scripts/install.sh b/.circleci/unittest/linux/scripts/install.sh index 41bca48068..e9201b266b 100755 --- a/.circleci/unittest/linux/scripts/install.sh +++ b/.circleci/unittest/linux/scripts/install.sh @@ -11,8 +11,11 @@ eval "$(./conda/bin/conda shell.bash hook)" conda activate ./env printf "* Installing PyTorch\n" -conda install -y -c "pytorch-${UPLOAD_CHANNEL}" pytorch cpuonly +conda install -y -c "pytorch-${UPLOAD_CHANNEL}" ${CONDA_CHANNEL_FLAGS} pytorch cpuonly printf "* Installing torchtext\n" git submodule update --init --recursive python setup.py develop + +printf "* Installing parameterized\n" +pip install parameterized diff --git a/.circleci/unittest/windows/scripts/environment.yml b/.circleci/unittest/windows/scripts/environment.yml index 2d7c790b91..9716f09114 100644 --- a/.circleci/unittest/windows/scripts/environment.yml +++ b/.circleci/unittest/windows/scripts/environment.yml @@ -1,7 +1,8 @@ channels: - defaults + - conda-forge dependencies: - - flake8==3.7.9 + - flake8>=3.7.9 - codecov - pip - pip: diff --git a/.circleci/unittest/windows/scripts/install.sh b/.circleci/unittest/windows/scripts/install.sh index 72a042c080..622ebc1cd1 100644 --- a/.circleci/unittest/windows/scripts/install.sh +++ b/.circleci/unittest/windows/scripts/install.sh @@ -16,8 +16,11 @@ eval "$(./conda/Scripts/conda.exe 'shell.bash' 'hook')" conda activate ./env printf "* Installing PyTorch\n" -conda install -y -c "pytorch-${UPLOAD_CHANNEL}" pytorch cpuonly +conda install -y -c "pytorch-${UPLOAD_CHANNEL}" ${CONDA_CHANNEL_FLAGS} pytorch cpuonly printf "* Installing torchtext\n" git submodule update --init --recursive "$root_dir/packaging/vc_env_helper.bat" python setup.py develop + +printf "* Installing parameterized\n" +pip install parameterized diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index e63904934d..3cd4e49a1d 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -3,7 +3,7 @@ import time import torch -from torchtext.experimental.datasets import AG_NEWS +from torchtext.experimental.datasets import DATASETS from torchtext.experimental.vocab import ( vocab as VocabExperimental, load_vocab_from_file, @@ -76,7 +76,7 @@ def benchmark_experimental_vocab_construction(vocab_file_path, is_raw_text=True, print("Construction time:", time.monotonic() - t0) -def benchmark_experimental_vocab_lookup(vocab_file_path=None): +def benchmark_experimental_vocab_lookup(vocab_file_path=None, dataset = 'AG_NEWS'): def _run_benchmark_lookup(tokens, vocab): t0 = time.monotonic() # list lookup @@ -94,7 +94,7 @@ def _run_benchmark_lookup(tokens, vocab): tokens = [] tokens_lists = [] - train = AG_NEWS(split='train') + train = DATASETS[dataset](split='train') vocab = train.get_vocab() for (_, text) in train: cur_tokens = [] @@ -124,7 +124,7 @@ def token_iterator(file_path): v_experimental = load_vocab_from_file(f) print("Construction time:", time.monotonic() - t0) else: - print("Loading Vocab from AG News") + print("Loading Vocab from {}".format(dataset)) counter = Counter(tokens) sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) ordered_dict = OrderedDict(sorted_by_freq_tuples) @@ -174,6 +174,8 @@ def token_iterator(file_path): help='The name of vocab file used for construction') parser.add_argument('--vocab-filename-lookup', type=str, default=None, help='The name of vocab file used for lookup') + parser.add_argument('--dataset', type=str, default='AG_NEWS', + help='The name of vocab file used for lookup') args = parser.parse_args() if args.run_construction_benchmark: @@ -181,4 +183,4 @@ def token_iterator(file_path): benchmark_experimental_vocab_construction(args.vocab_filename_construction, is_raw_text=args.is_raw_text, is_legacy=args.is_legacy) else: - benchmark_experimental_vocab_lookup(args.vocab_filename_lookup) + benchmark_experimental_vocab_lookup(args.vocab_filename_lookup, args.dataset) diff --git a/examples/data_pipeline/README.md b/examples/data_pipeline/README.md index 8ebbccc752..b579384e84 100644 --- a/examples/data_pipeline/README.md +++ b/examples/data_pipeline/README.md @@ -1,6 +1,6 @@ # Data processing pipelines with torchtext -This example shows a few data processing pipelines with the building blocks (like tokenizer, vocab). The raw text data from `torchtext.experimental.datasets.raw.text_classification` are used as the inputs for performance benchmark. We also enable the JIT support if possible. +This example shows a few data processing pipelines with the building blocks (like tokenizer, vocab). The raw text data from `torchtext.datasets` are used as the inputs for performance benchmark. We also enable the JIT support if possible. ## SentencePiece @@ -24,7 +24,7 @@ This pipeline example shows the application with the existing `Vocab` in torchte The command to run the pipeline: - python pipelines.py --pipeline torchtext + python pipelines.py --pipeline legacy_torchtext ## Experimental Torchtext @@ -36,7 +36,7 @@ This pipeline example shows the application with the vocab text file from Huggin The command to run the pipeline: - python pipelines.py --pipeline text_vocab + python pipelines.py --pipeline experimental_torchtext ## Legacy PyText @@ -80,7 +80,7 @@ And the text and label pipeline are passed to TextClassificationPipeline. Since The command to run the pipeline: - python pipelines.py --pipeline batch_torchtext + python pipelines.py --pipeline legacy_batch_torchtext ## Legacy FastText pretrained word vectors @@ -92,7 +92,7 @@ This pipeline example shows the application with the pretained word vector from The command to run the pipeline: - python pipelines.py --pipeline fasttext + python pipelines.py --pipeline legacy_fasttext ## Experimental FastText pretrained word vectors @@ -104,7 +104,7 @@ This pipeline example shows the application with the pretained word vector using The command to run the pipeline: - python pipelines.py --pipeline fasttext + python pipelines.py --pipeline experimental_fasttext Here are the time in seconds for the pipelines above: diff --git a/examples/data_pipeline/dataset.py b/examples/data_pipeline/dataset.py index 26740163a4..4877aa2f51 100644 --- a/examples/data_pipeline/dataset.py +++ b/examples/data_pipeline/dataset.py @@ -1,12 +1,12 @@ import torch -from torchtext.datasets import text_classification as raw +from torchtext.datasets import DATASETS class BatchTextClassificationData(torch.utils.data.IterableDataset): def __init__(self, dataset_name, batch_size=16): super(BatchTextClassificationData, self).__init__() - self._iterator = raw.DATASETS[dataset_name]()[0] # Load train dataset only + self._iterator = DATASETS[dataset_name](split='train') self.batch_size = batch_size def __iter__(self): diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index 455e5a5128..a0680f6f98 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -12,6 +12,7 @@ TextSequentialTransforms, sentencepiece_tokenizer, load_sp_model, + PRETRAINED_SP_MODEL, ) from torchtext.data.utils import get_tokenizer from torchtext.experimental.functional import ( @@ -20,14 +21,17 @@ from torchtext.experimental.vectors import FastText as FastTextExperimental from torchtext.experimental.vocab import load_vocab_from_file from torchtext.vocab import FastText - +from torchtext.utils import download_from_url import argparse -from torchtext.datasets import text_classification as raw +from torchtext.datasets import DATASETS import time from torch.utils.data import DataLoader -def build_sp_pipeline(spm_file): +def build_sp_pipeline(args): + spm_file = args.spm_filename + if spm_file in PRETRAINED_SP_MODEL: + spm_file = download_from_url(PRETRAINED_SP_MODEL[spm_file]) tokenizer = sentencepiece_tokenizer(spm_file) vocab = PretrainedSPVocab(load_sp_model(spm_file)) @@ -38,7 +42,8 @@ def build_sp_pipeline(spm_file): return pipeline, pipeline, jit_pipeline -def build_legacy_torchtext_vocab_pipeline(vocab_file): +def build_legacy_torchtext_vocab_pipeline(args): + vocab_file = args.vocab_filename tokenizer = get_tokenizer("basic_english") from torchtext.vocab import build_vocab_from_iterator @@ -53,9 +58,10 @@ def token_iterator(vocab_file): return pipeline, None, None -def build_experimental_torchtext_pipeline(hf_vocab_file): +def build_experimental_torchtext_pipeline(args): + vocab_file = args.vocab_filename tokenizer = basic_english_normalize() - with open(hf_vocab_file, 'r') as f: + with open(vocab_file, 'r') as f: vocab = load_vocab_from_file(f) pipeline = TextSequentialTransforms(tokenizer, vocab) jit_pipeline = torch.jit.script(pipeline) @@ -63,7 +69,8 @@ def build_experimental_torchtext_pipeline(hf_vocab_file): return pipeline, pipeline, jit_pipeline -def build_legacy_batch_torchtext_vocab_pipeline(vocab_file): +def build_legacy_batch_torchtext_vocab_pipeline(args): + vocab_file = args.vocab_filename tokenizer = get_tokenizer("basic_english") from torchtext.vocab import build_vocab_from_iterator @@ -78,7 +85,8 @@ def token_iterator(vocab_file): return text_pipeline, None, None -def build_legacy_pytext_vocab_pipeline(vocab_file): +def build_legacy_pytext_vocab_pipeline(args): + vocab_file = args.vocab_filename from pytext.data.utils import Vocabulary tokenizer = get_tokenizer("basic_english") @@ -92,7 +100,8 @@ def build_legacy_pytext_vocab_pipeline(vocab_file): return pipeline, None, None -def build_legacy_pytext_script_vocab_pipeline(vocab_file): +def build_legacy_pytext_script_vocab_pipeline(args): + vocab_file = args.vocab_filename from pytext.torchscript.vocab import ScriptVocabulary tokenizer = basic_english_normalize() @@ -108,7 +117,8 @@ def build_legacy_pytext_script_vocab_pipeline(vocab_file): return pipeline, pipeline, jit_pipeline -def build_experimental_pytext_script_pipeline(vocab_file): +def build_experimental_pytext_script_pipeline(args): + vocab_file = args.vocab_filename import os import sys # this is needed because we want to add 'torchtext/examples/vocab' directory to the @@ -129,7 +139,7 @@ def build_experimental_pytext_script_pipeline(vocab_file): return pipeline, pipeline, jit_pipeline -def build_legacy_fasttext_vector_pipeline(): +def build_legacy_fasttext_vector_pipeline(args): tokenizer = get_tokenizer("basic_english") vector = FastText() @@ -137,7 +147,7 @@ def build_legacy_fasttext_vector_pipeline(): return pipeline, None, None -def build_experimental_fasttext_vector_pipeline(): +def build_experimental_fasttext_vector_pipeline(args): tokenizer = basic_english_normalize() vector = FastTextExperimental() @@ -166,44 +176,38 @@ def collate_fn(data_batch): def generate_dataset(args): - train, test = raw.DATASETS[args.dataset]() + train, test = DATASETS[args.dataset]() return [_data for _data in train], [_data for _data in test] +PIPELINES = { + 'sentencepiece': build_sp_pipeline, + 'experimental_torchtext': build_experimental_torchtext_pipeline, + 'legacy_torchtext': build_legacy_torchtext_vocab_pipeline, + 'experimental_fasttext': build_experimental_fasttext_vector_pipeline, + 'legacy_fasttext': build_legacy_fasttext_vector_pipeline, + 'experimental_pytext_script_vocab': build_experimental_pytext_script_pipeline, + 'legacy_pytext_vocab': build_legacy_pytext_vocab_pipeline, + 'legacy_pytext_script_vocab': build_legacy_pytext_script_vocab_pipeline, + 'legacy_batch_torchtext': build_legacy_batch_torchtext_vocab_pipeline, +} + if __name__ == "__main__": parser = argparse.ArgumentParser(description='Data procesing pipelines') parser.add_argument('--pipeline', type=str, default='sentencepiece', help='The name of pipeline') parser.add_argument('--dataset', type=str, default='AG_NEWS', help='Dataset for performance benchmark') - parser.add_argument('--spm-filename', type=str, default='m_user.model', + parser.add_argument('--spm-filename', type=str, default='text_unigram_25000', help='The filename of sentencepiece model') parser.add_argument('--vocab-filename', type=str, default='vocab.txt', help='The name of vocab filename') args = parser.parse_args() - if args.pipeline == 'sentencepiece': - pipeline, torchbind_pipeline, jit_pipeline = build_sp_pipeline(args.spm_filename) - elif args.pipeline == 'experimental_torchtext': - pipeline, torchbind_pipeline, jit_pipeline = build_experimental_torchtext_pipeline(args.vocab_filename) - elif args.pipeline == 'experimental_pytext_script_vocab': - pipeline, torchbind_pipeline, jit_pipeline = build_experimental_pytext_script_pipeline(args.vocab_filename) - elif args.pipeline == 'experimental_fasttext': - pipeline, torchbind_pipeline, jit_pipeline = build_experimental_fasttext_vector_pipeline() - elif args.pipeline == 'legacy_torchtext': - pipeline, torchbind_pipeline, jit_pipeline = build_legacy_torchtext_vocab_pipeline(args.vocab_filename) - elif args.pipeline == 'legacy_pytext_vocab': - pipeline, torchbind_pipeline, jit_pipeline = build_legacy_pytext_vocab_pipeline(args.vocab_filename) - elif args.pipeline == 'legacy_pytext_script_vocab': - pipeline, torchbind_pipeline, jit_pipeline = build_legacy_pytext_script_vocab_pipeline(args.vocab_filename) - elif args.pipeline == 'legacy_fasttext': - pipeline, torchbind_pipeline, jit_pipeline = build_legacy_fasttext_vector_pipeline() - elif args.pipeline == 'legacy_batch_torchtext': - pipeline, torchbind_pipeline, jit_pipeline = build_legacy_batch_torchtext_vocab_pipeline(args.vocab_filename) - else: - print("pipeline is not supported. Current pipelines include sentencepiece, experimental_torchtext, " + - "experimental_fasttext, legacy_pytext, experimental_fasttext, legacy_torchtext, legacy_batch_torchtext") + if args.pipeline not in PIPELINES: + raise KeyError('Pipeline {} is not supported. Valid pipelines are {}'.format(args.pipeline, list(PIPELINES.keys()))) + pipeline, torchbind_pipeline, jit_pipeline = PIPELINES[args.pipeline](args) if pipeline is not None: print("Test eager mode for pipeline with pybind", args.pipeline) train, test = generate_dataset(args) diff --git a/examples/text_classification/train.py b/examples/text_classification/train.py index 84f20fb0d4..ed2a2ea5e9 100644 --- a/examples/text_classification/train.py +++ b/examples/text_classification/train.py @@ -5,7 +5,7 @@ import torch import sys -from torchtext.datasets import text_classification +from torchtext.experimental.datasets import text_classification from torch.utils.data import DataLoader from model import TextSentiment diff --git a/test/asset/raw_datasets.jsonl b/test/asset/raw_datasets.jsonl index e48add06d2..e014d1aad7 100644 --- a/test/asset/raw_datasets.jsonl +++ b/test/asset/raw_datasets.jsonl @@ -1,49 +1,49 @@ -{"dataset_name": "IMDB", "split": "train", "NUM_LINES": 25000, "MD5": "7c2ac02c03563afcf9b574c7e56c153a", "URL": "http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz", "first_line": ["neg", "I rented I AM CURIOUS-YELLOW from my video store because of all the controversy that surrounded it when it was first released in 1967. I also heard that at first it was seized by U.S. customs if it ever tried to enter this country, therefore being a fan of films considered \"controversial\" I really had to see this for myself.

      The plot is centered around a young Swedish drama student named Lena who wants to learn everything she can about life. In particular she wants to focus her attentions to making some sort of documentary on what the average Swede thought about certain political issues such as the Vietnam War and race issues in the United States. In between asking politicians and ordinary denizens of Stockholm about their opinions on politics, she has sex with her drama teacher, classmates, and married men.

      What kills me about I AM CURIOUS-YELLOW is that 40 years ago, this was considered pornographic. Really, the sex and nudity scenes are few and far between, even then it's not shot like some cheaply made porno. While my countrymen mind find it shocking, in reality sex and nudity are a major staple in Swedish cinema. Even Ingmar Bergman, arguably their answer to good old boy John Ford, had sex scenes in his films.

      I do commend the filmmakers for the fact that any sex shown in the film is shown for artistic purposes rather than just to shock people and make money to be shown in pornographic theaters in America. I AM CURIOUS-YELLOW is a good film for anyone wanting to study the meat and potatoes (no pun intended) of Swedish cinema. But really, this film doesn't have much of a plot."]} -{"dataset_name": "IMDB", "split": "test", "NUM_LINES": 25000, "MD5": "7c2ac02c03563afcf9b574c7e56c153a", "URL": "http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz", "first_line": ["neg", "I love sci-fi and am willing to put up with a lot. Sci-fi movies/TV are usually underfunded, under-appreciated and misunderstood. I tried to like this, I really did, but it is to good TV sci-fi as Babylon 5 is to Star Trek (the original). Silly prosthetics, cheap cardboard sets, stilted dialogues, CG that doesn't match the background, and painfully one-dimensional characters cannot be overcome with a 'sci-fi' setting. (I'm sure there are those of you out there who think Babylon 5 is good sci-fi TV. It's not. It's clich\u00e9d and uninspiring.) While US viewers might like emotion and character development, sci-fi is a genre that does not take itself seriously (cf. Star Trek). It may treat important issues, yet not as a serious philosophy. It's really difficult to care about the characters here as they are not simply foolish, just missing a spark of life. Their actions and reactions are wooden and predictable, often painful to watch. The makers of Earth KNOW it's rubbish as they have to always say \"Gene Roddenberry's Earth...\" otherwise people would not continue watching. Roddenberry's ashes must be turning in their orbit as this dull, cheap, poorly edited (watching it without advert breaks really brings this home) trudging Trabant of a show lumbers into space. Spoiler. So, kill off a main character. And then bring him back as another actor. Jeeez! Dallas all over again."]} -{"dataset_name": "AG_NEWS", "split": "train", "NUM_LINES": 120000, "MD5": "b1a00f826fdfbd249f79597b59e1dc12", "URL": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", "first_line": [3, "Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\band of ultra-cynics, are seeing green again."]} -{"dataset_name": "AG_NEWS", "split": "test", "NUM_LINES": 7600, "MD5": "d52ea96a97a2d943681189a97654912d", "URL": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv", "first_line": [3, "Fears for T N pension after talks Unions representing workers at Turner Newall say they are 'disappointed' after talks with stricken parent firm Federal Mogul."]} -{"dataset_name": "SogouNews", "split": "train", "NUM_LINES": 450000, "MD5": "0c1700ba70b73f964dd8de569d3fd03e", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE", "first_line": [4, "2008 di4 qi1 jie4 qi1ng da3o guo2 ji4 che1 zha3n me3i nv3 mo2 te4 2008di4 qi1 jie4 qi1ng da3o guo2 ji4 che1 zha3n yu2 15 ri4 za4i qi1ng da3o guo2 ji4 hui4 zha3n zho1ng xi1n she4ng da4 ka1i mu4 . be3n ci4 che1 zha3n jia1ng chi2 xu4 da4o be3n yue4 19 ri4 . ji1n nia2n qi1ng da3o guo2 ji4 che1 zha3n shi4 li4 nia2n da3o che2ng che1 zha3n gui1 mo2 zui4 da4 di2 yi1 ci4 , shi3 yo4ng lia3o qi1ng da3o guo2 ji4 hui4 zha3n zho1ng xi1n di2 qua2n bu4 shi4 ne4i wa4i zha3n gua3n . yi3 xia4 we2i xia4n cha3ng mo2 te4 tu2 pia4n ."]} -{"dataset_name": "SogouNews", "split": "test", "NUM_LINES": 60000, "MD5": "0c1700ba70b73f964dd8de569d3fd03e", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE", "first_line": [1, " ti3 ca1o shi4 jie4 be1i : che2ng fe1i na2 pi2ng he2ng mu4 zi4 yo2u ca1o ji1n pa2i su4 du4 : ( shuo1 mi2ng : dia3n ji1 zi4 do4ng bo1 fa4ng )\\n shuo1 mi2ng : dia3n ji1 ga1i a4n niu3 , xua3n ze2 yi1 lu4n ta2n ji2 ke3 "]} -{"dataset_name": "DBpedia", "split": "train", "NUM_LINES": 560000, "MD5": "dca7b1ae12b1091090db52aa7ec5ca64", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k", "first_line": [1, "E. D. Abbott Ltd Abbott of Farnham E D Abbott Limited was a British coachbuilding business based in Farnham Surrey trading under that name from 1929. A major part of their output was under sub-contract to motor vehicle manufacturers. Their business closed in 1972."]} -{"dataset_name": "DBpedia", "split": "test", "NUM_LINES": 70000, "MD5": "dca7b1ae12b1091090db52aa7ec5ca64", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k", "first_line": [1, "TY KU TY KU /ta\u026aku\u02d0/ is an American alcoholic beverage company that specializes in sake and other spirits. The privately-held company was founded in 2004 and is headquartered in New York City New York. While based in New York TY KU's beverages are made in Japan through a joint venture with two sake breweries. Since 2011 TY KU's growth has extended its products into all 50 states."]} -{"dataset_name": "YelpReviewPolarity", "split": "train", "NUM_LINES": 560000, "MD5": "620c8ae4bd5a150b730f1ba9a7c6a4d3", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg", "first_line": [1, "Unfortunately, the frustration of being Dr. Goldberg's patient is a repeat of the experience I've had with so many other doctors in NYC -- good doctor, terrible staff. It seems that his staff simply never answers the phone. It usually takes 2 hours of repeated calling to get an answer. Who has time for that or wants to deal with it? I have run into this problem with many other doctors and I just don't get it. You have office workers, you have patients with medical needs, why isn't anyone answering the phone? It's incomprehensible and not work the aggravation. It's with regret that I feel that I have to give Dr. Goldberg 2 stars."]} -{"dataset_name": "YelpReviewPolarity", "split": "test", "NUM_LINES": 38000, "MD5": "620c8ae4bd5a150b730f1ba9a7c6a4d3", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg", "first_line": [2, "Contrary to other reviews, I have zero complaints about the service or the prices. I have been getting tire service here for the past 5 years now, and compared to my experience with places like Pep Boys, these guys are experienced and know what they're doing. \\nAlso, this is one place that I do not feel like I am being taken advantage of, just because of my gender. Other auto mechanics have been notorious for capitalizing on my ignorance of cars, and have sucked my bank account dry. But here, my service and road coverage has all been well explained - and let up to me to decide. \\nAnd they just renovated the waiting room. It looks a lot better than it did in previous years."]} -{"dataset_name": "YelpReviewFull", "split": "train", "NUM_LINES": 650000, "MD5": "f7ddfafed1033f68ec72b9267863af6c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0", "first_line": [5, "dr. goldberg offers everything i look for in a general practitioner. he's nice and easy to talk to without being patronizing; he's always on time in seeing his patients; he's affiliated with a top-notch hospital (nyu) which my parents have explained to me is very important in case something happens and you need surgery; and you can get referrals to see specialists without having to see him first. really, what more do you need? i'm sitting here trying to think of any complaints i have about him, but i'm really drawing a blank."]} -{"dataset_name": "YelpReviewFull", "split": "test", "NUM_LINES": 50000, "MD5": "f7ddfafed1033f68ec72b9267863af6c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0", "first_line": [1, "I got 'new' tires from them and within two weeks got a flat. I took my car to a local mechanic to see if i could get the hole patched, but they said the reason I had a flat was because the previous patch had blown - WAIT, WHAT? I just got the tire and never needed to have it patched? This was supposed to be a new tire. \\nI took the tire over to Flynn's and they told me that someone punctured my tire, then tried to patch it. So there are resentful tire slashers? I find that very unlikely. After arguing with the guy and telling him that his logic was far fetched he said he'd give me a new tire \\\"this time\\\". \\nI will never go back to Flynn's b/c of the way this guy treated me and the simple fact that they gave me a used tire!"]} -{"dataset_name": "YahooAnswers", "split": "train", "NUM_LINES": 1400000, "MD5": "f3f9899b997a42beb24157e62e3eea8d", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU", "first_line": [5, "why doesn't an optical mouse work on a glass table? or even on some surfaces? Optical mice use an LED and a camera to rapidly capture images of the surface beneath the mouse. The infomation from the camera is analyzed by a DSP (Digital Signal Processor) and used to detect imperfections in the underlying surface and determine motion. Some materials, such as glass, mirrors or other very shiny, uniform surfaces interfere with the ability of the DSP to accurately analyze the surface beneath the mouse. \\nSince glass is transparent and very uniform, the mouse is unable to pick up enough imperfections in the underlying surface to determine motion. Mirrored surfaces are also a problem, since they constantly reflect back the same image, causing the DSP not to recognize motion properly. When the system is unable to see surface changes associated with movement, the mouse will not work properly."]} -{"dataset_name": "YahooAnswers", "split": "test", "NUM_LINES": 60000, "MD5": "f3f9899b997a42beb24157e62e3eea8d", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU", "first_line": [9, "What makes friendship click? How does the spark keep going? good communication is what does it. Can you move beyond small talk and say what's really on your mind. If you start doing this, my expereince is that potentially good friends will respond or shun you. Then you know who the really good friends are."]} -{"dataset_name": "AmazonReviewPolarity", "split": "train", "NUM_LINES": 3600000, "MD5": "fe39f8b653cada45afd5792e0f0e8f9b", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM", "first_line": [2, "Stuning even for the non-gamer This sound track was beautiful! It paints the senery in your mind so well I would recomend it even to people who hate vid. game music! I have played the game Chrono Cross but out of all of the games I have ever played it has the best music! It backs away from crude keyboarding and takes a fresher step with grate guitars and soulful orchestras. It would impress anyone who cares to listen! ^_^"]} -{"dataset_name": "AmazonReviewPolarity", "split": "test", "NUM_LINES": 400000, "MD5": "fe39f8b653cada45afd5792e0f0e8f9b", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM", "first_line": [2, "Great CD My lovely Pat has one of the GREAT voices of her generation. I have listened to this CD for YEARS and I still LOVE IT. When I'm in a good mood it makes me feel better. A bad mood just evaporates like sugar in the rain. This CD just oozes LIFE. Vocals are jusat STUUNNING and lyrics just kill. One of life's hidden gems. This is a desert isle CD in my book. Why she never made it big is just beyond me. Everytime I play this, no matter black, white, young, old, male, female EVERYBODY says one thing \"Who was that singing ?\""]} -{"dataset_name": "AmazonReviewFull", "split": "train", "NUM_LINES": 3000000, "MD5": "57d28bd5d930e772930baddf36641c7c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA", "first_line": [3, "more like funchuck Gave this to my dad for a gag gift after directing \"Nunsense,\" he got a reall kick out of it!"]} -{"dataset_name": "AmazonReviewFull", "split": "test", "NUM_LINES": 650000, "MD5": "57d28bd5d930e772930baddf36641c7c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA", "first_line": [1, "mens ultrasheer This model may be ok for sedentary types, but I'm active and get around alot in my job - consistently found these stockings rolled up down by my ankles! Not Good!! Solution: go with the standard compression stocking, 20-30, stock #114622. Excellent support, stays up and gives me what I need. Both pair of these also tore as I struggled to pull them up all the time. Good riddance/bad investment!"]} -{"dataset_name": "UDPOS", "split": "train", "NUM_LINES": 12543, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": [["Al", "-", "Zaman", ":", "American", "forces", "killed", "Shaikh", "Abdullah", "al", "-", "Ani", ",", "the", "preacher", "at", "the", "mosque", "in", "the", "town", "of", "Qaim", ",", "near", "the", "Syrian", "border", "."], ["PROPN", "PUNCT", "PROPN", "PUNCT", "ADJ", "NOUN", "VERB", "PROPN", "PROPN", "PROPN", "PUNCT", "PROPN", "PUNCT", "DET", "NOUN", "ADP", "DET", "NOUN", "ADP", "DET", "NOUN", "ADP", "PROPN", "PUNCT", "ADP", "DET", "ADJ", "NOUN", "PUNCT"], ["NNP", "HYPH", "NNP", ":", "JJ", "NNS", "VBD", "NNP", "NNP", "NNP", "HYPH", "NNP", ",", "DT", "NN", "IN", "DT", "NN", "IN", "DT", "NN", "IN", "NNP", ",", "IN", "DT", "JJ", "NN", "."]]} -{"dataset_name": "UDPOS", "split": "valid", "NUM_LINES": 2002, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": [["From", "the", "AP", "comes", "this", "story", ":"], ["ADP", "DET", "PROPN", "VERB", "DET", "NOUN", "PUNCT"], ["IN", "DT", "NNP", "VBZ", "DT", "NN", ":"]]} -{"dataset_name": "UDPOS", "split": "test", "NUM_LINES": 2077, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": [["What", "if", "Google", "Morphed", "Into", "GoogleOS", "?"], ["PRON", "SCONJ", "PROPN", "VERB", "ADP", "PROPN", "PUNCT"], ["WP", "IN", "NNP", "VBD", "IN", "NNP", "."]]} -{"dataset_name": "CoNLL2000Chunking", "split": "train", "NUM_LINES": 8936, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": [["Confidence", "in", "the", "pound", "is", "widely", "expected", "to", "take", "another", "sharp", "dive", "if", "trade", "figures", "for", "September", ",", "due", "for", "release", "tomorrow", ",", "fail", "to", "show", "a", "substantial", "improvement", "from", "July", "and", "August", "'s", "near-record", "deficits", "."], ["NN", "IN", "DT", "NN", "VBZ", "RB", "VBN", "TO", "VB", "DT", "JJ", "NN", "IN", "NN", "NNS", "IN", "NNP", ",", "JJ", "IN", "NN", "NN", ",", "VB", "TO", "VB", "DT", "JJ", "NN", "IN", "NNP", "CC", "NNP", "POS", "JJ", "NNS", "."], ["B-NP", "B-PP", "B-NP", "I-NP", "B-VP", "I-VP", "I-VP", "I-VP", "I-VP", "B-NP", "I-NP", "I-NP", "B-SBAR", "B-NP", "I-NP", "B-PP", "B-NP", "O", "B-ADJP", "B-PP", "B-NP", "B-NP", "O", "B-VP", "I-VP", "I-VP", "B-NP", "I-NP", "I-NP", "B-PP", "B-NP", "I-NP", "I-NP", "B-NP", "I-NP", "I-NP", "O"]]} -{"dataset_name": "CoNLL2000Chunking", "split": "test", "NUM_LINES": 2012, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": [["Rockwell", "International", "Corp.", "'s", "Tulsa", "unit", "said", "it", "signed", "a", "tentative", "agreement", "extending", "its", "contract", "with", "Boeing", "Co.", "to", "provide", "structural", "parts", "for", "Boeing", "'s", "747", "jetliners", "."], ["NNP", "NNP", "NNP", "POS", "NNP", "NN", "VBD", "PRP", "VBD", "DT", "JJ", "NN", "VBG", "PRP$", "NN", "IN", "NNP", "NNP", "TO", "VB", "JJ", "NNS", "IN", "NNP", "POS", "CD", "NNS", "."], ["B-NP", "I-NP", "I-NP", "B-NP", "I-NP", "I-NP", "B-VP", "B-NP", "B-VP", "B-NP", "I-NP", "I-NP", "B-VP", "B-NP", "I-NP", "B-PP", "B-NP", "I-NP", "B-VP", "I-VP", "B-NP", "I-NP", "B-PP", "B-NP", "B-NP", "I-NP", "I-NP", "O"]]} -{"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": ["d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "62f36422bfab90fb42a560546b704009", "540da4566bb6dd35fdbc720218b742b7", "613eb4a3f0c2b13f0871ced946851b0e", "d848fe0ae8b9447209fb49c5c31cb3d2", "abc13b4042f4fef1cdff6de3b6c53b71", "cbf5bfc2147706f228d288e1b18bf4af", "bdfe4222f4692ccaa1e3389460f0890e", "0e1ee2b4145795bd180b193424db204b", "1cff688d1aadef7fdb22e9ad27d6fd2c", "3e10289959d0059952511c31df3c7550"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz"], "first_line": ["Zwei junge wei\u00dfe M\u00e4nner sind im Freien in der N\u00e4he vieler B\u00fcsche.\n", "Two young, White males are outside near many bushes.\n"]} -{"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": ["83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "b26486ede1d4436d5acf6e38c65bb44d", "16165248083beacebfe18866d5f4f0ae", "7180780822d4b600eb81c1ccf171c230", "8edb43c90cae66ec762748a968089b99", "873a377a348713d3ab84db1fb57cdede", "df57faf5f00d434d2559c021ef55f1aa", "9077a5127480cc799116384de501bd70", "c1f697c3b6dfb7305349db34e26b45fc", "acb5ea26a577ceccfae6337181c31716", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": ["Eine Gruppe von M\u00e4nnern l\u00e4dt Baumwolle auf einen Lastwagen\n", "A group of men are loading cotton onto a truck\n"]} -{"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "6a8d5c87f6ae19e3d35681aa6fd16571", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "ff2c0fcb4893a13bd73414306bc250ae", "005396bac545d880abe6f00bbb7dbbb4", "a7b684e0edbef1d4a23660c8e8e743fd", "a152878809942757a55ce087073486b8", "08dc7cd4a662f31718412de95ca9bfe3", "cb09af7d2b501f9112f2d6a59fa1360d", "4995d10954a804d3cdfd907b9fd093e8", "ac0c72653c140dd96707212a1baa4278", "6dfb42cae4e4fd9a3c40e62ff5398a55", "ece8cec6b87bf00dd12607f3062dae4c", "9a7e7b2dcc33135a32cd621c3b37d2d8", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "eec05227daba4bb8f3f8f25b1cb335f4", "9318fa08c0c0b96114eadb10eb2fc633", "088ec0765fa213a0eb937a62adfd4996", "5f7c8d0be0ac739856b47d32a9434998", "713ed720636622a54546d5f14f88b00f"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz"], "first_line": ["Ein Mann mit einem orangefarbenen Hut, der etwas anstarrt.\n", "A man in an orange hat starring at something.\n"]} -{"dataset_name": "IWSLT2016", "split": "train", "NUM_LINES": 196884, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["David Gallo: Das ist Bill Lange. Ich bin Dave Gallo.\n", "David Gallo: This is Bill Lange. I'm Dave Gallo.\n"]} -{"dataset_name": "IWSLT2016", "split": "valid", "NUM_LINES": 993, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich 11 Jahre alt war, wurde ich eines Morgens von den Kl\u00e4ngen heller Freude geweckt.\n", "When I was 11, I remember waking up one morning to the sound of joy in my house.\n"]} -{"dataset_name": "IWSLT2016", "split": "test", "NUM_LINES": 1305, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": ["Als ich in meinen 20ern war, hatte ich meine erste Psychotherapie-Patientin.\n", "When I was in my 20s, I saw my very first psychotherapy client.\n"]} -{"dataset_name": "IWSLT2017", "split": "train", "NUM_LINES": 206112, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Vielen Dank, Chris.\n", "Thank you so much, Chris.\n"]} -{"dataset_name": "IWSLT2017", "split": "valid", "NUM_LINES": 888, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Letztes Jahr habe ich diese beiden Folien gezeigt, um zu veranschaulichen, dass die arktische Eiskappe, die f\u00fcr ann\u00e4hernd drei Millionen Jahre die Gr\u00f6sse der unteren 48 Staaten hatte, um 40 Prozent geschrumpft ist.\n","Last year I showed these two slides so that demonstrate that the arctic ice cap, which for most of the last three million years has been the size of the lower 48 states, has shrunk by 40 percent.\n"]} -{"dataset_name": "IWSLT2017", "split": "test", "NUM_LINES": 1568, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": ["Vor einigen Jahren, hier bei TED, stellte Peter Skillman einen Design-Wettbewerb namens \"Die Marshmallow-Herausforderung\" vor.\n","Several years ago here at TED, Peter Skillman introduced a design challenge called the marshmallow challenge.\n"]} -{"dataset_name": "WMT14", "split": "train", "NUM_LINES": 4500966, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Wiederaufnahme der Sitzungsperiode\n", "Res@@ um@@ ption of the session\n"]} -{"dataset_name": "WMT14", "split": "valid", "NUM_LINES": 3000, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Eine repub@@ li@@ kanische Strategie , um der Wieder@@ wahl von Obama entgegen@@ zu@@ treten\n", "A Republic@@ an strategy to counter the re-@@ election of Obama\n"]} -{"dataset_name": "WMT14", "split": "test", "NUM_LINES": 3003, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": ["Gut@@ ach : Noch mehr Sicherheit f\u00fcr Fu\u00dfg\u00e4n@@ ger\n", "Gut@@ ach : Incre@@ ased safety for pedestri@@ ans\n"]} -{"dataset_name": "WikiText2", "split": "train", "NUM_LINES": 36718, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": " \n"} -{"dataset_name": "WikiText2", "split": "valid", "NUM_LINES": 3760, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": " \n"} -{"dataset_name": "WikiText2", "split": "test", "NUM_LINES": 4358, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": " \n"} -{"dataset_name": "WikiText103", "split": "train", "NUM_LINES": 1801350, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": " \n"} -{"dataset_name": "WikiText103", "split": "valid", "NUM_LINES": 3760, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": " \n"} -{"dataset_name": "WikiText103", "split": "test", "NUM_LINES": 4358, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": " \n"} -{"dataset_name": "PennTreebank", "split": "train", "NUM_LINES": 42068, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " aer banknote berlitz calloway centrust cluett fromstein gitano guterman hydro-quebec ipo kia memotec mlx nahb punts rake regatta rubens sim snack-food ssangyong swapo wachter \n"} -{"dataset_name": "PennTreebank", "split": "valid", "NUM_LINES": 3370, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " consumers may want to move their telephones a little closer to the tv set \n"} -{"dataset_name": "PennTreebank", "split": "test", "NUM_LINES": 3761, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": " no it was n't black monday \n"} -{"dataset_name": "SQuAD1", "split": "train", "NUM_LINES": 87599, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": ["Architecturally, the school has a Catholic character. Atop the Main Building's gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend \"Venite Ad Me Omnes\". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.", "To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?", ["Saint Bernadette Soubirous"], [515]]} -{"dataset_name": "SQuAD1", "split": "dev", "NUM_LINES": 10570, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": ["Super Bowl 50 was an American football game to determine the champion of the National Football League (NFL) for the 2015 season. The American Football Conference (AFC) champion Denver Broncos defeated the National Football Conference (NFC) champion Carolina Panthers 24\u201310 to earn their third Super Bowl title. The game was played on February 7, 2016, at Levi's Stadium in the San Francisco Bay Area at Santa Clara, California. As this was the 50th Super Bowl, the league emphasized the \"golden anniversary\" with various gold-themed initiatives, as well as temporarily suspending the tradition of naming each Super Bowl game with Roman numerals (under which the game would have been known as \"Super Bowl L\"), so that the logo could prominently feature the Arabic numerals 50.", "Which NFL team represented the AFC at Super Bowl 50?", ["Denver Broncos", "Denver Broncos", "Denver Broncos"], [177, 177, 177]]} -{"dataset_name": "SQuAD2", "split": "train", "NUM_LINES": 130319, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": ["Beyonc\u00e9 Giselle Knowles-Carter (/bi\u02d0\u02c8j\u0252nse\u026a/ bee-YON-say) (born September 4, 1981) is an American singer, songwriter, record producer and actress. Born and raised in Houston, Texas, she performed in various singing and dancing competitions as a child, and rose to fame in the late 1990s as lead singer of R&B girl-group Destiny's Child. Managed by her father, Mathew Knowles, the group became one of the world's best-selling girl groups of all time. Their hiatus saw the release of Beyonc\u00e9's debut album, Dangerously in Love (2003), which established her as a solo artist worldwide, earned five Grammy Awards and featured the Billboard Hot 100 number-one singles \"Crazy in Love\" and \"Baby Boy\".", "When did Beyonce start becoming popular?", ["in the late 1990s"], [269]]} -{"dataset_name": "SQuAD2", "split": "dev", "NUM_LINES": 11873, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": ["The Normans (Norman: Nourmands; French: Normands; Latin: Normanni) were the people who in the 10th and 11th centuries gave their name to Normandy, a region in France. They were descended from Norse (\"Norman\" comes from \"Norseman\") raiders and pirates from Denmark, Iceland and Norway who, under their leader Rollo, agreed to swear fealty to King Charles III of West Francia. Through generations of assimilation and mixing with the native Frankish and Roman-Gaulish populations, their descendants would gradually merge with the Carolingian-based cultures of West Francia. The distinct cultural and ethnic identity of the Normans emerged initially in the first half of the 10th century, and it continued to evolve over the succeeding centuries.", "In what country is Normandy located?", ["France", "France", "France", "France"], [159, 159, 159, 159]]} -{"dataset_name": "EnWik9", "split": "train", "NUM_LINES": 13147026, "MD5": "3e773f8a1577fda2e27f871ca17f31fd", "URL": "http://mattmahoney.net/dc/enwik9.zip", "first_line": "\n"} +{"dataset_name": "IMDB", "split": "train", "NUM_LINES": 25000, "MD5": "7c2ac02c03563afcf9b574c7e56c153a", "URL": "http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz", "first_line": "7d45c2c4463561748d304b9e53ea762a"} +{"dataset_name": "IMDB", "split": "test", "NUM_LINES": 25000, "MD5": "7c2ac02c03563afcf9b574c7e56c153a", "URL": "http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz", "first_line": "80dd1b651d74220e41f7c7c4d0be1d7c"} +{"dataset_name": "AG_NEWS", "split": "train", "NUM_LINES": 120000, "MD5": "b1a00f826fdfbd249f79597b59e1dc12", "URL": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", "first_line": "b34631d550696857784c780e75d1019b"} +{"dataset_name": "AG_NEWS", "split": "test", "NUM_LINES": 7600, "MD5": "d52ea96a97a2d943681189a97654912d", "URL": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv", "first_line": "4ec431dd3276af3ddaa26a18687e134f"} +{"dataset_name": "SogouNews", "split": "train", "NUM_LINES": 450000, "MD5": "0c1700ba70b73f964dd8de569d3fd03e", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE", "first_line": "296ef12b480391803d967ff3b1e6bf2f"} +{"dataset_name": "SogouNews", "split": "test", "NUM_LINES": 60000, "MD5": "0c1700ba70b73f964dd8de569d3fd03e", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbUkVqNEszd0pHaFE", "first_line": "e98c02d3434598ed5f2c526acea49b49"} +{"dataset_name": "DBpedia", "split": "train", "NUM_LINES": 560000, "MD5": "dca7b1ae12b1091090db52aa7ec5ca64", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k", "first_line": "6639f35b320ce28b049cc0d781fbcec3"} +{"dataset_name": "DBpedia", "split": "test", "NUM_LINES": 70000, "MD5": "dca7b1ae12b1091090db52aa7ec5ca64", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbQ2Vic1kxMmZZQ1k", "first_line": "48b9dbea275bfafeda43777028224056"} +{"dataset_name": "YelpReviewPolarity", "split": "train", "NUM_LINES": 560000, "MD5": "620c8ae4bd5a150b730f1ba9a7c6a4d3", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg", "first_line": "67aa2e1007ef828ff9a46dfbaff424c1"} +{"dataset_name": "YelpReviewPolarity", "split": "test", "NUM_LINES": 38000, "MD5": "620c8ae4bd5a150b730f1ba9a7c6a4d3", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbNUpYQ2N3SGlFaDg", "first_line": "06eb4f2e949c7ff3b3ad32471204a5c3"} +{"dataset_name": "YelpReviewFull", "split": "train", "NUM_LINES": 650000, "MD5": "f7ddfafed1033f68ec72b9267863af6c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0", "first_line": "54d1587157abe27f47c2a0e3b5fee28a"} +{"dataset_name": "YelpReviewFull", "split": "test", "NUM_LINES": 50000, "MD5": "f7ddfafed1033f68ec72b9267863af6c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZlU4dXhHTFhZQU0", "first_line": "c555a9e89bd0aa297c7063b6486b862c"} +{"dataset_name": "YahooAnswers", "split": "train", "NUM_LINES": 1400000, "MD5": "f3f9899b997a42beb24157e62e3eea8d", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU", "first_line": "4de4cb818d91c577c003f8407f7044a4"} +{"dataset_name": "YahooAnswers", "split": "test", "NUM_LINES": 60000, "MD5": "f3f9899b997a42beb24157e62e3eea8d", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9Qhbd2JNdDBsQUdocVU", "first_line": "c78f4e2e02649045b67500fadc0622b3"} +{"dataset_name": "AmazonReviewPolarity", "split": "train", "NUM_LINES": 3600000, "MD5": "fe39f8b653cada45afd5792e0f0e8f9b", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM", "first_line": "4716fc2a803320fc5e209ddeee668c9a"} +{"dataset_name": "AmazonReviewPolarity", "split": "test", "NUM_LINES": 400000, "MD5": "fe39f8b653cada45afd5792e0f0e8f9b", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbaW12WVVZS2drcnM", "first_line": "c553d41569a163927dfb8eec9019be36"} +{"dataset_name": "AmazonReviewFull", "split": "train", "NUM_LINES": 3000000, "MD5": "57d28bd5d930e772930baddf36641c7c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA", "first_line": "67a8ee762aa87a1e069ed7bbafea73dc"} +{"dataset_name": "AmazonReviewFull", "split": "test", "NUM_LINES": 650000, "MD5": "57d28bd5d930e772930baddf36641c7c", "URL": "https://drive.google.com/uc?export=download&id=0Bz8a_Dbh9QhbZVhsUnRWRDhETzA", "first_line": "72a7bd1407b9a00e9e147a5b07d4dcdb"} +{"dataset_name": "UDPOS", "split": "train", "NUM_LINES": 12543, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": "4ae412a6dd492715b1043d85057ab5a6"} +{"dataset_name": "UDPOS", "split": "valid", "NUM_LINES": 2002, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": "32b0524ae43937d1c36dcbca1cf4ee61"} +{"dataset_name": "UDPOS", "split": "test", "NUM_LINES": 2077, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": "c81f4ab7afe76c346680b81ab4cb0b36"} +{"dataset_name": "CoNLL2000Chunking", "split": "train", "NUM_LINES": 8936, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": "3d411e5490dfb95a9d0449fea4ece7c2"} +{"dataset_name": "CoNLL2000Chunking", "split": "test", "NUM_LINES": 2012, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": "b3f46baa5f096206547e5212de493214"} +{"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": ["d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "62f36422bfab90fb42a560546b704009", "540da4566bb6dd35fdbc720218b742b7", "613eb4a3f0c2b13f0871ced946851b0e", "d848fe0ae8b9447209fb49c5c31cb3d2", "abc13b4042f4fef1cdff6de3b6c53b71", "cbf5bfc2147706f228d288e1b18bf4af", "bdfe4222f4692ccaa1e3389460f0890e", "0e1ee2b4145795bd180b193424db204b", "1cff688d1aadef7fdb22e9ad27d6fd2c", "3e10289959d0059952511c31df3c7550"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz"], "first_line": "51cf1f8f5fd11c9299e1502e3ee3743a"} +{"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": ["83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "b26486ede1d4436d5acf6e38c65bb44d", "16165248083beacebfe18866d5f4f0ae", "7180780822d4b600eb81c1ccf171c230", "8edb43c90cae66ec762748a968089b99", "873a377a348713d3ab84db1fb57cdede", "df57faf5f00d434d2559c021ef55f1aa", "9077a5127480cc799116384de501bd70", "c1f697c3b6dfb7305349db34e26b45fc", "acb5ea26a577ceccfae6337181c31716", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": "496d7eab1215ebf8d40fa530dbf6debb"} +{"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "6a8d5c87f6ae19e3d35681aa6fd16571", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "ff2c0fcb4893a13bd73414306bc250ae", "005396bac545d880abe6f00bbb7dbbb4", "a7b684e0edbef1d4a23660c8e8e743fd", "a152878809942757a55ce087073486b8", "08dc7cd4a662f31718412de95ca9bfe3", "cb09af7d2b501f9112f2d6a59fa1360d", "4995d10954a804d3cdfd907b9fd093e8", "ac0c72653c140dd96707212a1baa4278", "6dfb42cae4e4fd9a3c40e62ff5398a55", "ece8cec6b87bf00dd12607f3062dae4c", "9a7e7b2dcc33135a32cd621c3b37d2d8", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "eec05227daba4bb8f3f8f25b1cb335f4", "9318fa08c0c0b96114eadb10eb2fc633", "088ec0765fa213a0eb937a62adfd4996", "5f7c8d0be0ac739856b47d32a9434998", "713ed720636622a54546d5f14f88b00f"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz"], "first_line": "5c5a9e6b599a340baf3aaec68dd43b0e"} +{"dataset_name": "IWSLT2016", "split": "train", "NUM_LINES": 196884, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": "0a57052d6042cc1e505779347c187174"} +{"dataset_name": "IWSLT2016", "split": "valid", "NUM_LINES": 993, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": "8a875fe03dee1988f21d2b9424e25957"} +{"dataset_name": "IWSLT2016", "split": "test", "NUM_LINES": 1305, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": "ec2842026c4ddf2ea7321e9566676554"} +{"dataset_name": "IWSLT2017", "split": "train", "NUM_LINES": 206112, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": "c75166d2ffde3978586af8a8ebdf6450"} +{"dataset_name": "IWSLT2017", "split": "valid", "NUM_LINES": 888, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": "c43021713268b2efc08a255c191f2c74"} +{"dataset_name": "IWSLT2017", "split": "test", "NUM_LINES": 1568, "MD5": "aca701032b1c4411afc4d9fa367796ba", "URL": "https://drive.google.com/u/0/uc?id=12ycYSzLIG253AFN35Y6qoyf9wtkOjakp", "first_line": "cfff6f23c564bc4cb372bee4987f6707"} +{"dataset_name": "WMT14", "split": "train", "NUM_LINES": 4500966, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": "27a5871c90db257250806f52ba6aff0c"} +{"dataset_name": "WMT14", "split": "valid", "NUM_LINES": 3000, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": "a302bd241b4c3138a400e38a846f93b0"} +{"dataset_name": "WMT14", "split": "test", "NUM_LINES": 3003, "MD5": "874ab6bbfe9c21ec987ed1b9347f95ec", "URL": "https://drive.google.com/uc?export=download&id=0B_bZck-ksdkpM25jRUN2X2UxMm8", "first_line": "140245f6a92f95225150f717e2d7a1a7"} +{"dataset_name": "WikiText2", "split": "train", "NUM_LINES": 36718, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": "c3e189c0ef8590f093c38b41bdba5239"} +{"dataset_name": "WikiText2", "split": "valid", "NUM_LINES": 3760, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": "c3e189c0ef8590f093c38b41bdba5239"} +{"dataset_name": "WikiText2", "split": "test", "NUM_LINES": 4358, "MD5": "542ccefacc6c27f945fb54453812b3cd", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-v1.zip", "first_line": "c3e189c0ef8590f093c38b41bdba5239"} +{"dataset_name": "WikiText103", "split": "train", "NUM_LINES": 1801350, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": "c3e189c0ef8590f093c38b41bdba5239"} +{"dataset_name": "WikiText103", "split": "valid", "NUM_LINES": 3760, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": "c3e189c0ef8590f093c38b41bdba5239"} +{"dataset_name": "WikiText103", "split": "test", "NUM_LINES": 4358, "MD5": "9ddaacaf6af0710eda8c456decff7832", "URL": "https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-v1.zip", "first_line": "c3e189c0ef8590f093c38b41bdba5239"} +{"dataset_name": "PennTreebank", "split": "train", "NUM_LINES": 42068, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": "7c2d3356b501bef852361e03da99841a"} +{"dataset_name": "PennTreebank", "split": "valid", "NUM_LINES": 3370, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": "fe23e20e56c04bcbafef379e984df1f2"} +{"dataset_name": "PennTreebank", "split": "test", "NUM_LINES": 3761, "MD5": {"train": "f26c4b92c5fdc7b3f8c7cdcb991d8420", "valid": "aa0affc06ff7c36e977d7cd49e3839bf", "test": "8b80168b89c18661a38ef683c0dc3721"}, "URL": {"train": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.train.txt", "test": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.test.txt", "valid": "https://raw.githubusercontent.com/wojzaremba/lstm/master/data/ptb.valid.txt"}, "first_line": "a1e01652513bd83a1925b0822ce19456"} +{"dataset_name": "SQuAD1", "split": "train", "NUM_LINES": 87599, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": "72d1162738e38d973ed20c9e70469ed4"} +{"dataset_name": "SQuAD1", "split": "dev", "NUM_LINES": 10570, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": "fd5bd80f392f3a03ec908508da3a4ea3"} +{"dataset_name": "SQuAD2", "split": "train", "NUM_LINES": 130319, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": "9b719a13e9ea95ab9700c5c631885fc8"} +{"dataset_name": "SQuAD2", "split": "dev", "NUM_LINES": 11873, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": "1e011c981d41cca284070532135eb9bd"} +{"dataset_name": "EnWik9", "split": "train", "NUM_LINES": 13147026, "MD5": "3e773f8a1577fda2e27f871ca17f31fd", "URL": "http://mattmahoney.net/dc/enwik9.zip", "first_line": "9ac868b1ea4f13083b6c923bc3134a70"} diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 278ef49c96..d229229e19 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -3,6 +3,8 @@ import os import torch import torchtext +import json +import hashlib from torchtext.legacy import data from parameterized import parameterized from ..common.torchtext_test_case import TorchtextTestCase @@ -181,7 +183,7 @@ def test_raw_text_classification(self, info): else: data_iter = torchtext.datasets.DATASETS[dataset_name](split=split) self.assertEqual(len(data_iter), info['NUM_LINES']) - self.assertEqual(next(data_iter), info['first_line']) + self.assertEqual(hashlib.md5(json.dumps(next(data_iter), sort_keys=True).encode('utf-8')).hexdigest(), info['first_line']) if dataset_name == "AG_NEWS": self.assertEqual(torchtext.datasets.URLS[dataset_name][split], info['URL']) self.assertEqual(torchtext.datasets.MD5[dataset_name][split], info['MD5']) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 4c3ef76399..e41783cef1 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -1,14 +1,14 @@ +#include #include #include #include -#include // @manual -#include // @manual +#include // @manual +#include // @manual #include // @manual -#include // @manual +#include // @manual #include #include // @manual #include // @manual - namespace torchtext { namespace py = pybind11; @@ -16,11 +16,11 @@ namespace py = pybind11; namespace { Vocab build_vocab_from_text_file(const std::string &file_path, const std::string &unk_token, - const int64_t min_freq, - const int64_t num_cpus, + const int64_t min_freq, const int64_t num_cpus, py::object fn) { torch::jit::script::Module module(*torch::jit::as_module(fn)); - return _build_vocab_from_text_file(file_path, unk_token, min_freq, num_cpus, module); + return _build_vocab_from_text_file(file_path, unk_token, min_freq, num_cpus, + module); } } // namespace @@ -40,7 +40,8 @@ PYBIND11_MODULE(_torchtext, m) { return _deserialize_regex(std::move(state)); })); - py::class_>(m, "RegexTokenizer") + py::class_>( + m, "RegexTokenizer") .def_readonly("patterns_", &RegexTokenizer::patterns_) .def_readonly("replacements_", &RegexTokenizer::replacements_) .def_readonly("to_lower_", &RegexTokenizer::to_lower_) @@ -48,15 +49,18 @@ PYBIND11_MODULE(_torchtext, m) { .def("forward", &RegexTokenizer::forward) .def(py::pickle( // __getstate__ - [](const c10::intrusive_ptr &self) -> RegexTokenizerStates { + [](const c10::intrusive_ptr &self) + -> RegexTokenizerStates { return _serialize_regex_tokenizer(self); }, // __setstate__ - [](RegexTokenizerStates states) -> c10::intrusive_ptr { + [](RegexTokenizerStates states) + -> c10::intrusive_ptr { return _deserialize_regex_tokenizer(std::move(states)); })); - py::class_>(m, "SentencePiece") + py::class_>(m, + "SentencePiece") .def(py::init()) .def("_return_content", [](const SentencePiece &self) { return py::bytes(self.content_); }) @@ -70,14 +74,14 @@ PYBIND11_MODULE(_torchtext, m) { .def("PieceToId", &SentencePiece::PieceToId) .def("IdToPiece", &SentencePiece::IdToPiece) .def(py::pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> py::bytes{ - return py::bytes(self->content_); - }, - // __setstate__ - [](py::bytes state) -> c10::intrusive_ptr { - return c10::make_intrusive(std::string(state)); - })); + // __getstate__ + [](const c10::intrusive_ptr &self) -> py::bytes { + return py::bytes(self->content_); + }, + // __setstate__ + [](py::bytes state) -> c10::intrusive_ptr { + return c10::make_intrusive(std::string(state)); + })); py::class_>(m, "Vectors") .def(py::init, std::vector, @@ -103,13 +107,30 @@ PYBIND11_MODULE(_torchtext, m) { .def(py::init, std::string>()) .def_readonly("itos_", &Vocab::itos_) .def_readonly("unk_token_", &Vocab::unk_token_) - .def("__getitem__", &Vocab::__getitem__) + .def("__getitem__", + [](c10::intrusive_ptr &self, const py::str &item) -> int64_t { + ssize_t length; + const char *buffer = PyUnicode_AsUTF8AndSize(item.ptr(), &length); + return self->__getitem__(c10::string_view{buffer, (size_t)length}); + }) .def("__len__", &Vocab::__len__) .def("insert_token", &Vocab::insert_token) .def("append_token", &Vocab::append_token) .def("lookup_token", &Vocab::lookup_token) .def("lookup_tokens", &Vocab::lookup_tokens) - .def("lookup_indices", &Vocab::lookup_indices) + .def("lookup_indices", + [](const c10::intrusive_ptr &self, const py::list &items) { + std::vector indices(items.size()); + int64_t counter = 0; + for (const auto &item : items) { + ssize_t length; + const char *buffer = + PyUnicode_AsUTF8AndSize(item.ptr(), &length); + indices[counter++] = + self->__getitem__(c10::string_view{buffer, (size_t)length}); + } + return indices; + }) .def("get_stoi", &Vocab::get_stoi) .def("get_itos", &Vocab::get_itos) .def(py::pickle( @@ -131,96 +152,112 @@ PYBIND11_MODULE(_torchtext, m) { TORCH_LIBRARY_FRAGMENT(torchtext, m) { m.class_("Regex") - .def(torch::init()) - .def("Sub", &Regex::Sub) - .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> std::string { - return _serialize_regex(self); - }, - // __setstate__ - [](std::string state) -> c10::intrusive_ptr { - return _deserialize_regex(std::move(state)); - }); + .def(torch::init()) + .def("Sub", &Regex::Sub) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> std::string { + return _serialize_regex(self); + }, + // __setstate__ + [](std::string state) -> c10::intrusive_ptr { + return _deserialize_regex(std::move(state)); + }); m.class_("RegexTokenizer") - .def(torch::init, std::vector, bool>()) - .def("forward", &RegexTokenizer::forward) - .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> RegexTokenizerStates { - return _serialize_regex_tokenizer(self); - }, - // __setstate__ - [](RegexTokenizerStates states) -> c10::intrusive_ptr { - return _deserialize_regex_tokenizer(std::move(states)); - }); + .def(torch::init, std::vector, + bool>()) + .def("forward", &RegexTokenizer::forward) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) + -> RegexTokenizerStates { + return _serialize_regex_tokenizer(self); + }, + // __setstate__ + [](RegexTokenizerStates states) + -> c10::intrusive_ptr { + return _deserialize_regex_tokenizer(std::move(states)); + }); m.class_("SentencePiece") - .def(torch::init()) - .def("Encode", &SentencePiece::Encode) - .def("EncodeAsIds", &SentencePiece::EncodeAsIds) - .def("DecodeIds", &SentencePiece::DecodeIds) - .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) - .def("DecodePieces", &SentencePiece::DecodePieces) - .def("GetPieceSize", &SentencePiece::GetPieceSize) - .def("unk_id", &SentencePiece::unk_id) - .def("PieceToId", &SentencePiece::PieceToId) - .def("IdToPiece", &SentencePiece::IdToPiece) - .def_pickle( - // The underlying content of SentencePiece contains byte string, - // and returing it as std::string cause UTF8 decoding error. - // Since TorchScript does not support byte string, we use byte Tensor to - // pass around the data. - // __getstate__ - [](const c10::intrusive_ptr &self) -> torch::Tensor { - auto *data = static_cast(const_cast(self->content_.data())); - auto numel = static_cast(self->content_.size()); - return torch::from_blob(data, {numel}, {torch::kUInt8}).clone(); - }, - // __setstate__ - [](torch::Tensor state) -> c10::intrusive_ptr { - auto *data = static_cast(state.data_ptr()); - auto numel = state.size(0); - return c10::make_intrusive(std::string(data, numel)); - }); + .def(torch::init()) + .def("Encode", &SentencePiece::Encode) + .def("EncodeAsIds", &SentencePiece::EncodeAsIds) + .def("DecodeIds", &SentencePiece::DecodeIds) + .def("EncodeAsPieces", &SentencePiece::EncodeAsPieces) + .def("DecodePieces", &SentencePiece::DecodePieces) + .def("GetPieceSize", &SentencePiece::GetPieceSize) + .def("unk_id", &SentencePiece::unk_id) + .def("PieceToId", &SentencePiece::PieceToId) + .def("IdToPiece", &SentencePiece::IdToPiece) + .def_pickle( + // The underlying content of SentencePiece contains byte string, + // and returing it as std::string cause UTF8 decoding error. + // Since TorchScript does not support byte string, we use byte Tensor + // to pass around the data. + // __getstate__ + [](const c10::intrusive_ptr &self) -> torch::Tensor { + auto *data = + static_cast(const_cast(self->content_.data())); + auto numel = static_cast(self->content_.size()); + return torch::from_blob(data, {numel}, {torch::kUInt8}).clone(); + }, + // __setstate__ + [](torch::Tensor state) -> c10::intrusive_ptr { + auto *data = static_cast(state.data_ptr()); + auto numel = state.size(0); + return c10::make_intrusive(std::string(data, numel)); + }); m.class_("Vectors") - .def(torch::init, std::vector, torch::Tensor, torch::Tensor>()) - .def("__getitem__", &Vectors::__getitem__) - .def("lookup_vectors", &Vectors::lookup_vectors) - .def("__setitem__", &Vectors::__setitem__) - .def("__len__", &Vectors::__len__) - .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> VectorsStates { - return _serialize_vectors(self); - }, - // __setstate__ - [](VectorsStates states) -> c10::intrusive_ptr { - return _deserialize_vectors(states); - }); + .def(torch::init, std::vector, + torch::Tensor, torch::Tensor>()) + .def("__getitem__", &Vectors::__getitem__) + .def("lookup_vectors", &Vectors::lookup_vectors) + .def("__setitem__", &Vectors::__setitem__) + .def("__len__", &Vectors::__len__) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> VectorsStates { + return _serialize_vectors(self); + }, + // __setstate__ + [](VectorsStates states) -> c10::intrusive_ptr { + return _deserialize_vectors(states); + }); m.class_("Vocab") - .def(torch::init()) - .def("__getitem__", &Vocab::__getitem__) - .def("__len__", &Vocab::__len__) - .def("insert_token", &Vocab::insert_token) - .def("append_token", &Vocab::append_token) - .def("lookup_token", &Vocab::lookup_token) - .def("lookup_tokens", &Vocab::lookup_tokens) - .def("lookup_indices", &Vocab::lookup_indices) - .def("get_stoi", &Vocab::get_stoi) - .def("get_itos", &Vocab::get_itos) - .def_pickle( - // __getstate__ - [](const c10::intrusive_ptr &self) -> VocabStates { - return _serialize_vocab(self); - }, - // __setstate__ - [](VocabStates states) -> c10::intrusive_ptr { - return _deserialize_vocab(states); - }); + .def(torch::init()) + .def("__getitem__", + [](const c10::intrusive_ptr &self, const std::string &item) + -> int64_t { return self->__getitem__(c10::string_view{item}); }) + .def("__len__", &Vocab::__len__) + .def("insert_token", &Vocab::insert_token) + .def("append_token", &Vocab::append_token) + .def("lookup_token", &Vocab::lookup_token) + .def("lookup_tokens", &Vocab::lookup_tokens) + .def("lookup_indices", + [](const c10::intrusive_ptr &self, + const std::vector &items) { + std::vector indices(items.size()); + int64_t counter = 0; + for (const auto &item : items) { + indices[counter++] = self->__getitem__(c10::string_view{item}); + } + return indices; + }) + .def("get_stoi", &Vocab::get_stoi) + .def("get_itos", &Vocab::get_itos) + .def_pickle( + // __getstate__ + [](const c10::intrusive_ptr &self) -> VocabStates { + return _serialize_vocab(self); + }, + // __setstate__ + [](VocabStates states) -> c10::intrusive_ptr { + return _deserialize_vocab(states); + }); m.def("torchtext::generate_sp_model", &generate_sp_model); m.def("torchtext::load_sp_model", &load_sp_model); diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 0e324dbbf5..b6fa2099d7 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -1,23 +1,19 @@ #include // @manual #include +#include #include #include -#include // @manual -#include // @manual - +#include // @manual +#include // @manual namespace torchtext { -Vocab::Vocab(const StringList &tokens, const IndexDict &stoi, - const std::string &unk_token, const int64_t unk_index) - : unk_index_(std::move(unk_index)), stoi_(std::move(stoi)), - itos_(std::move(tokens)), unk_token_(std::move(unk_token)) {} - Vocab::Vocab(const StringList &tokens, const std::string &unk_token) - : itos_(std::move(tokens)), unk_token_(std::move(unk_token)) { - stoi_.reserve(tokens.size()); + : stoi_(MAX_VOCAB_SIZE, -1), unk_token_(std::move(unk_token)) { for (std::size_t i = 0; i < tokens.size(); i++) { // tokens should not have any duplicates - if (stoi_.find(tokens[i]) != stoi_.end()) { + auto token_position = + _find(c10::string_view{tokens[i].data(), tokens[i].size()}); + if (stoi_[token_position] != -1) { #ifdef _MSC_VER std::cerr << "[RuntimeError] Duplicate token found in tokens list: " << tokens[i] << std::endl; @@ -25,35 +21,27 @@ Vocab::Vocab(const StringList &tokens, const std::string &unk_token) throw std::runtime_error("Duplicate token found in tokens list: " + tokens[i]); } - stoi_[std::move(tokens[i])] = i; + _add(tokens[i]); } - unk_index_ = stoi_.find(unk_token)->second; + + unk_index_ = + stoi_[_find(c10::string_view{unk_token.data(), unk_token.size()})]; } -int64_t Vocab::__len__() const { return stoi_.size(); } +int64_t Vocab::__len__() const { return itos_.size(); } -int64_t Vocab::__getitem__(const std::string &token) const { - const auto &item = stoi_.find(token); - if (item != stoi_.end()) { - return item->second; +int64_t Vocab::__getitem__(const c10::string_view &token) const { + int64_t id = _find(token); + if (stoi_[id] != -1) { + return stoi_[id]; } return unk_index_; } -void Vocab::append_token(const std::string &token) { - if (stoi_.find(token) == stoi_.end()) { - // Note: we can't do `stoi_[token] = stoi_.size()` because of a bug - // on Windows where the size gets updated before the assign occurs. - // For example if the size of `stoi_` is 2, doing - // `stoi_["test"] = stoi_.size()` will set `stoi_["test"]` to a - // value of 3 instead of 2 on Windows stoi_[token] = itos_.size(); - stoi_[token] = itos_.size(); - itos_.push_back(token); - } -} +void Vocab::append_token(const std::string &token) { _add(token); } void Vocab::insert_token(const std::string &token, const int64_t &index) { - if (index < 0 || index > static_cast(stoi_.size())) { + if (index < 0 || index > itos_.size()) { #ifdef _MSC_VER std::cerr << "[RuntimeError] Specified index " << index << " is out of bounds of the size of stoi dictionary: " @@ -65,30 +53,31 @@ void Vocab::insert_token(const std::string &token, const int64_t &index) { std::to_string(stoi_.size()) + "."); } - const auto &item = stoi_.find(token); // if item already in stoi we throw an error - if (item != stoi_.end()) { + auto token_position = _find(c10::string_view{token.data(), token.size()}); + if (stoi_[token_position] != -1) { #ifdef _MSC_VER std::cerr << "[RuntimeError] Token " << token - << " already exists in the Vocab with index: " << item->second - << std::endl; + << " already exists in the Vocab with index: " + << stoi_[token_position] << std::endl; #endif throw std::runtime_error("Token " + token + " already exists in the Vocab with index: " + - std::to_string(item->second) + "."); + std::to_string(stoi_[token_position]) + "."); } // need to offset all tokens greater than or equal index by 1 for (size_t i = index; i < itos_.size(); i++) { - stoi_[itos_[i]] = i + 1; + stoi_[_find(c10::string_view{itos_[i].data(), itos_[i].size()})] = i + 1; } - stoi_[token] = index; itos_.insert(itos_.begin() + index, token); + stoi_[_find(c10::string_view{token.data(), token.size()})] = index; // need to update unk_index in case token equals unk_token or token // inserted before unk_token - unk_index_ = stoi_.find(unk_token_)->second; + unk_index_ = + stoi_[_find(c10::string_view{unk_token_.data(), unk_token_.size()})]; } std::string Vocab::lookup_token(const int64_t &index) { @@ -96,7 +85,7 @@ std::string Vocab::lookup_token(const int64_t &index) { #ifdef _MSC_VER std::cerr << "[RuntimeError] Specified index " << index << " is out of bounds of the size of itos dictionary: " - << stoi_.size() << std::endl; + << itos_.size() << std::endl; #endif throw std::runtime_error( "Specified index " + std::to_string(index) + @@ -115,7 +104,8 @@ StringList Vocab::lookup_tokens(const std::vector &indices) { return tokens; } -std::vector Vocab::lookup_indices(const StringList &tokens) { +std::vector +Vocab::lookup_indices(const std::vector &tokens) { std::vector indices(tokens.size()); for (int64_t i = 0; i < static_cast(tokens.size()); i++) { indices[i] = __getitem__(tokens[i]); @@ -125,11 +115,9 @@ std::vector Vocab::lookup_indices(const StringList &tokens) { std::unordered_map Vocab::get_stoi() const { std::unordered_map stoi; - stoi.reserve(stoi_.size()); - // construct tokens and index list - for (const auto &item : stoi_) { - stoi[item.first] = item.second; + for (const auto &item : itos_) { + stoi[item] = __getitem__(c10::string_view{item}); } return stoi; } @@ -150,8 +138,11 @@ int64_t _infer_lines(const std::string &file_path) { void parse_vocab_file_chunk(const std::string &file_path, size_t offset, const int64_t start_line, const int64_t end_line, std::shared_ptr counter) { - std::ifstream fin; - fin.open(file_path, std::ios::in); + std::ifstream fin(file_path, std::ios::in); + if (!fin.is_open()) { + throw std::runtime_error("Cannot open input file " + file_path + "\n"); + } + fin.seekg(offset); for (int64_t i = start_line; i < end_line; i++) { @@ -171,8 +162,11 @@ void parse_raw_text_file_chunk(const std::string &file_path, size_t offset, const int64_t start_line, const int64_t end_line, std::shared_ptr counter, torch::jit::script::Module &module) { - std::ifstream fin; - fin.open(file_path, std::ios::in); + std::ifstream fin(file_path, std::ios::in); + if (!fin.is_open()) { + throw std::runtime_error("Cannot open input file " + file_path + "\n"); + } + fin.seekg(offset); std::string line; @@ -205,7 +199,7 @@ struct CompareTokens { } }; -std::tuple +StringList _concat_tokens(std::vector> chunk_counters, const std::string &unk_token, const int64_t min_freq, const int64_t num_lines, const bool sort_tokens) { @@ -264,17 +258,7 @@ _concat_tokens(std::vector> chunk_counters, unique_tokens.insert(unique_tokens.begin(), unk_token); } - // create stoi - IndexDict stoi; - stoi.reserve(num_lines); - int64_t index = 0; - - for (const auto &token : unique_tokens) { - stoi[token] = index; - index++; - } - - return std::make_tuple(std::move(stoi), std::move(unique_tokens)); + return unique_tokens; } constexpr int64_t GRAIN_SIZE = 13107; @@ -319,14 +303,10 @@ Vocab _load_vocab_from_file(const std::string &file_path, std::unique_lock lock(m); cv.wait(lock, [&thread_count] { return thread_count == 0; }); - IndexDict stoi; - StringList tokens; - std::tie(stoi, tokens) = + StringList tokens = _concat_tokens(chunk_counters, unk_token, min_freq, num_lines, false); - int64_t unk_index = stoi.find(unk_token)->second; - - return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); + return Vocab(std::move(tokens), unk_token); } Vocab _build_vocab_from_text_file(const std::string &file_path, @@ -370,13 +350,10 @@ Vocab _build_vocab_from_text_file(const std::string &file_path, std::unique_lock lock(m); cv.wait(lock, [&thread_count] { return thread_count == 0; }); - IndexDict stoi; - StringList tokens; - std::tie(stoi, tokens) = + StringList tokens = _concat_tokens(chunk_counters, unk_token, min_freq, num_lines, true); - int64_t unk_index = stoi.find(unk_token)->second; - return Vocab(std::move(tokens), std::move(stoi), unk_token, unk_index); + return Vocab(std::move(tokens), unk_token); } VocabStates _serialize_vocab(const c10::intrusive_ptr &self) { diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h index 0da660a633..660f6145d4 100644 --- a/torchtext/csrc/vocab.h +++ b/torchtext/csrc/vocab.h @@ -1,5 +1,5 @@ +#include #include - namespace torchtext { typedef std::vector StringList; @@ -10,29 +10,52 @@ typedef std::tuple, std::vector, VocabStates; struct Vocab : torch::CustomClassHolder { -private: + static const int32_t MAX_VOCAB_SIZE = 30000000; int64_t unk_index_; - IndexDict stoi_; - -public: + std::vector stoi_; const std::string version_str_ = "0.0.1"; StringList itos_; std::string unk_token_; explicit Vocab(const std::vector &tokens, const std::string &unk_token); - explicit Vocab(const StringList &tokens, const IndexDict &stoi, - - const std::string &unk_token, const int64_t unk_index); int64_t __len__() const; - int64_t __getitem__(const std::string &token) const; + int64_t __getitem__(const c10::string_view &token) const; void append_token(const std::string &token); void insert_token(const std::string &token, const int64_t &index); std::string lookup_token(const int64_t &index); std::vector lookup_tokens(const std::vector &indices); - std::vector lookup_indices(const std::vector &tokens); + std::vector + lookup_indices(const std::vector &tokens); std::unordered_map get_stoi() const; std::vector get_itos() const; + +protected: + uint32_t _hash(const c10::string_view &str) const { + uint32_t h = 2166136261; + for (size_t i = 0; i < str.size(); i++) { + h = h ^ uint32_t(uint8_t(str[i])); + h = h * 16777619; + } + return h; + } + + uint32_t _find(const c10::string_view &w) const { + uint32_t stoi_size = stoi_.size(); + uint32_t id = _hash(w) % stoi_size; + while (stoi_[id] != -1 && itos_[stoi_[id]]!= w) { + id = (id + 1) % stoi_size; + } + return id; + } + + void _add(const std::string &w) { + uint32_t h = _find(c10::string_view{w.data(), w.size()}); + if (stoi_[h] == -1) { + itos_.push_back(w); + stoi_[h] = itos_.size() - 1; + } + } }; VocabStates _serialize_vocab(const c10::intrusive_ptr &self); diff --git a/torchtext/data/__init__.py b/torchtext/data/__init__.py index e403cd8483..e5a5cccf71 100644 --- a/torchtext/data/__init__.py +++ b/torchtext/data/__init__.py @@ -14,5 +14,5 @@ "sentencepiece_numericalizer", "sentencepiece_tokenizer", "custom_replace", "simple_space_split", "numericalize_tokens_from_iterator", - "Batch" #tmp compatability hack for old lightning -] + "Batch" # tmp compatibility hack for old lightning + ] diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index c25fc0728e..1431e2f5d4 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -261,11 +261,11 @@ def IWSLT2017(language_pair=('de', 'en'), get_tokenizer("spacy", language='en_core_web_sm')) Examples: - >>> from torchtext.experimental.datasets import IWSLT + >>> from torchtext.experimental.datasets import IWSLT2017 >>> from torchtext.data.utils import get_tokenizer - >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') >>> tgt_tokenizer = get_tokenizer("basic_english") - >>> train_dataset, valid_dataset, test_dataset = IWSLT(tokenizer=(src_tokenizer, + >>> train_dataset, valid_dataset, test_dataset = IWSLT2017(tokenizer=(src_tokenizer, tgt_tokenizer)) >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] @@ -332,11 +332,11 @@ def IWSLT2016(language_pair=('de', 'en'), Examples: - >>> from torchtext.experimental.datasets import IWSLT + >>> from torchtext.experimental.datasets import IWSLT2016 >>> from torchtext.data.utils import get_tokenizer - >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') >>> tgt_tokenizer = get_tokenizer("basic_english") - >>> train_dataset, valid_dataset, test_dataset = IWSLT(tokenizer=(src_tokenizer, + >>> train_dataset, valid_dataset, test_dataset = IWSLT2016(tokenizer=(src_tokenizer, tgt_tokenizer)) >>> src_vocab, tgt_vocab = train_dataset.get_vocab() >>> src_data, tgt_data = train_dataset[10] @@ -397,7 +397,7 @@ def WMT14(language_pair=('de', 'en'), Examples: >>> from torchtext.experimental.datasets import WMT14 >>> from torchtext.data.utils import get_tokenizer - >>> src_tokenizer = get_tokenizer("spacy", language='de') + >>> src_tokenizer = get_tokenizer("spacy", language='de_core_news_sm') >>> tgt_tokenizer = get_tokenizer("basic_english") >>> train_dataset, valid_dataset, test_dataset = WMT14(tokenizer=(src_tokenizer, tgt_tokenizer)) From f96f374b681cbf983c3d38e21762ce310772ead5 Mon Sep 17 00:00:00 2001 From: Parmeet Singh Bhatia Date: Fri, 2 Apr 2021 09:10:53 -0700 Subject: [PATCH 53/68] Import torchtext #1267 93b03e4 Summary: Imported latest from github Master PR#1267 Reviewed By: cpuhrsch Differential Revision: D27503970 fbshipit-source-id: 853ff895ba42b1feb7442abe1c87478e43d62e5b --- docs/source/nn_modules.rst | 6 +++--- torchtext/nn/modules/multiheadattention.py | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/source/nn_modules.rst b/docs/source/nn_modules.rst index 064f51488a..5b979581e0 100644 --- a/docs/source/nn_modules.rst +++ b/docs/source/nn_modules.rst @@ -1,11 +1,11 @@ .. role:: hidden :class: hidden-section -torchtext.nn.modules.multiheadattention +torchtext.nn ======================================= -.. automodule:: torchtext.nn.modules.multiheadattention -.. currentmodule:: torchtext.nn.modules.multiheadattention +.. automodule:: torchtext.nn +.. currentmodule:: torchtext.nn :hidden:`MultiheadAttentionContainer` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/torchtext/nn/modules/multiheadattention.py b/torchtext/nn/modules/multiheadattention.py index b581d245c4..e0909d70b3 100644 --- a/torchtext/nn/modules/multiheadattention.py +++ b/torchtext/nn/modules/multiheadattention.py @@ -20,6 +20,7 @@ def __init__(self, nhead, in_proj_container, attention_layer, out_proj, batch_fi Examples:: >>> import torch + >>> from torchtext.nn import MultiheadAttentionContainer, InProjContainer, ScaledDotProduct >>> embed_dim, num_heads, bsz = 10, 5, 64 >>> in_proj_container = InProjContainer(torch.nn.Linear(embed_dim, embed_dim), torch.nn.Linear(embed_dim, embed_dim), @@ -122,6 +123,7 @@ def __init__(self, dropout=0.0, batch_first=False): as `(batch, seq, feature)`. Default: ``False`` Examples:: + >>> import torch, torchtext >>> SDP = torchtext.nn.ScaledDotProduct(dropout=0.1) >>> q = torch.randn(21, 256, 3) >>> k = v = torch.randn(21, 256, 3) @@ -245,6 +247,7 @@ def forward(self, value (Tensor): The values to be projected. Examples:: + >>> import torch >>> from torchtext.nn import InProjContainer >>> embed_dim, bsz = 10, 64 >>> in_proj_container = InProjContainer(torch.nn.Linear(embed_dim, embed_dim), From 6a46a5c3e44235966d5aef845e53a32a0b4e3341 Mon Sep 17 00:00:00 2001 From: Moto Hira Date: Thu, 15 Apr 2021 17:52:45 -0700 Subject: [PATCH 54/68] Import torchtext #1266 ba0bf52 Summary: Import torchtext from github Reviewed By: parmeet Differential Revision: D27803909 fbshipit-source-id: 9cb0f15858b1417cb5868d5651513eb2df998fbe --- .circleci/regenerate.py | 3 +- .../unittest/linux/scripts/generate_cache.sh | 8 ++++ .../windows/scripts/generate_cache.sh | 8 ++++ .circleci/utils/test_sort_yaml.py | 2 +- .github/ISSUE_TEMPLATE/bug-report.md | 48 +++++++++++++++++++ .github/ISSUE_TEMPLATE/documentation.md | 10 ++++ .github/ISSUE_TEMPLATE/feature-request.md | 24 ++++++++++ .../ISSUE_TEMPLATE/questions-help-support.md | 10 ++++ .github/pytorch-probot.yml | 1 + .github/workflows/bandit.yml | 23 +++++++++ .github/workflows/codeql.yml | 43 +++++++++++++++++ .python3 | 0 requirements.txt | 3 ++ torchtext/data/datasets_utils.py | 5 +- torchtext/legacy/datasets/translation.py | 5 +- 15 files changed, 189 insertions(+), 4 deletions(-) create mode 100755 .circleci/unittest/linux/scripts/generate_cache.sh create mode 100644 .circleci/unittest/windows/scripts/generate_cache.sh create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/documentation.md create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md create mode 100644 .github/ISSUE_TEMPLATE/questions-help-support.md create mode 100644 .github/pytorch-probot.yml create mode 100644 .github/workflows/bandit.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .python3 diff --git a/.circleci/regenerate.py b/.circleci/regenerate.py index f963469c58..d3fd6131f7 100755 --- a/.circleci/regenerate.py +++ b/.circleci/regenerate.py @@ -15,6 +15,7 @@ """ import jinja2 +from jinja2 import select_autoescape import yaml import os.path @@ -184,7 +185,7 @@ def unittest_workflows(indentation=6): env = jinja2.Environment( loader=jinja2.FileSystemLoader(d), lstrip_blocks=True, - autoescape=False, + autoescape=select_autoescape(enabled_extensions=('html', 'xml')), ) with open(os.path.join(d, 'config.yml'), 'w') as f: diff --git a/.circleci/unittest/linux/scripts/generate_cache.sh b/.circleci/unittest/linux/scripts/generate_cache.sh new file mode 100755 index 0000000000..c14bb6121e --- /dev/null +++ b/.circleci/unittest/linux/scripts/generate_cache.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e + +eval "$(./conda/bin/conda shell.bash hook)" +conda activate ./env + +python -m test.common.cache_utils diff --git a/.circleci/unittest/windows/scripts/generate_cache.sh b/.circleci/unittest/windows/scripts/generate_cache.sh new file mode 100644 index 0000000000..8c3e559a48 --- /dev/null +++ b/.circleci/unittest/windows/scripts/generate_cache.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e + +eval "$(./conda/Scripts/conda.exe 'shell.bash' 'hook')" +conda activate ./env + +python -m test.common.cache_utils diff --git a/.circleci/utils/test_sort_yaml.py b/.circleci/utils/test_sort_yaml.py index dc6db481dd..44ed29af6d 100755 --- a/.circleci/utils/test_sort_yaml.py +++ b/.circleci/utils/test_sort_yaml.py @@ -11,4 +11,4 @@ import sys import yaml -sys.stdout.write(yaml.dump(yaml.load(sys.stdin, Loader=yaml.FullLoader), sort_keys=True)) +sys.stdout.write(yaml.dump(yaml.safe_load(sys.stdin, Loader=yaml.FullLoader), sort_keys=True)) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000000..15104939bf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,48 @@ +--- +name: "\U0001F41B Bug Report" +about: Submit a bug report to help us improve TorchText + +--- + +## 🐛 Bug +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Environment** + +Please copy and paste the output from our +[environment collection script](https://raw.githubusercontent.com/pytorch/text/master/torchtext/utils/collect_env.py) +(or fill out the checklist below manually). + +You can get the script and run it with: +``` +wget https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect_env.py +# For security purposes, please check the contents of collect_env.py before running it. +python collect_env.py +python -c "import torchtext; print(\"torchtext version is \", torchtext.__version__)" +``` + + - PyTorch Version (e.g., 1.0): + - OS (e.g., Linux): + - How you installed PyTorch (`conda`, `pip`, source): + - Build command you used (if compiling from source): + - Python version: + - CUDA/cuDNN version: + - GPU models and configuration: + - Any other relevant information: + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 0000000000..b9e37a2774 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,10 @@ +--- +name: "\U0001F4DA Documentation" +about: Report an issue related to TorchText + +--- + +## 📚 Documentation + +**Description** + diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 0000000000..4872607a45 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,24 @@ +--- +name: "\U0001F680Feature Request" +about: Submit a proposal/request for a new TorchText feature + +--- + +## 🚀 Feature + + +**Motivation** + + + +**Pitch** + + + +**Alternatives** + + + +**Additional context** + + diff --git a/.github/ISSUE_TEMPLATE/questions-help-support.md b/.github/ISSUE_TEMPLATE/questions-help-support.md new file mode 100644 index 0000000000..d1e8eab0dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/questions-help-support.md @@ -0,0 +1,10 @@ +--- +name: "❓Questions/Help/Support" +about: Do you need support? We have resources. + +--- + +## ❓ Questions and Help + +**Description** + diff --git a/.github/pytorch-probot.yml b/.github/pytorch-probot.yml new file mode 100644 index 0000000000..2928abba18 --- /dev/null +++ b/.github/pytorch-probot.yml @@ -0,0 +1 @@ +tracking_issue: 876 diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml new file mode 100644 index 0000000000..93bae80f9b --- /dev/null +++ b/.github/workflows/bandit.yml @@ -0,0 +1,23 @@ +# GitHub Actions Bandit Workflow + +name: Bandit + +on: + pull_request: + branches: [ master ] + + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + # Task will fail if any high-severity issues are found + # Ignoring submodules + - name: Run Bandit Security Analysis + run: | + python -m pip install bandit + python -m bandit -r . -x ./third_party -lll diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..b983ccaab7 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,43 @@ +# GitHub Actions CodeQL Workflow + +name: CodeQL + +on: + pull_request: + branches: [ master ] + + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: python, cpp + + - name: Install Ninja + run: | + sudo apt-get update -y + sudo apt-get install -y ninja-build + + - name: Update submodules + run: git submodule update --init --recursive + + - name: Install Torch + run: | + python -m pip install cmake + python -m pip install torch==1.8.1+cpu -f https://download.pytorch.org/whl/torch_stable.html + sudo ln -s /usr/bin/ninja /usr/bin/ninja-build + + - name: Build TorchText + run: python setup.py develop --user + + # If any code scanning alerts are found, they will be under Security -> CodeQL + # Link: https://github.com/pytorch/text/security/code-scanning + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.python3 b/.python3 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/requirements.txt b/requirements.txt index c9c761c82d..fd100b8eb3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,3 +28,6 @@ pytest-pythonpath # Coverage statistics pytest-cov codecov + +# To parse untrusted XML data +defusedxml diff --git a/torchtext/data/datasets_utils.py b/torchtext/data/datasets_utils.py index 1baef44e70..b17df76354 100644 --- a/torchtext/data/datasets_utils.py +++ b/torchtext/data/datasets_utils.py @@ -11,7 +11,10 @@ unicode_csv_reader, ) import codecs -import xml.etree.ElementTree as ET +try: + import defusedxml.ElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET """ These functions and classes are meant solely for use in torchtext.datasets and not for public consumption yet. diff --git a/torchtext/legacy/datasets/translation.py b/torchtext/legacy/datasets/translation.py index 275e7cea90..6e6bfeb36e 100644 --- a/torchtext/legacy/datasets/translation.py +++ b/torchtext/legacy/datasets/translation.py @@ -1,5 +1,8 @@ import os -import xml.etree.ElementTree as ET +try: + import defusedxml.ElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET import glob import io import codecs From bc5e6e39288aa0fbcb6a9175c99f1c272fe9d48f Mon Sep 17 00:00:00 2001 From: Artyom Astafurov Date: Thu, 22 Apr 2021 07:45:06 -0700 Subject: [PATCH 55/68] Import torchtext #1287 fab63ed Reviewed By: parmeet Differential Revision: D27922562 fbshipit-source-id: 3c18cd9e2583e03471461ad8a22ac6b0ceb596a2 --- .circleci/config.yml | 3 +++ .circleci/config.yml.in | 3 +++ docs/requirements.txt | 1 - docs/source/conf.py | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bb04316f56..32f99b26ff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -559,6 +559,9 @@ jobs: root: ./ paths: - "*" + - store_artifacts: + path: ./docs/build/html + destination: docs upload_docs: <<: *binary_common diff --git a/.circleci/config.yml.in b/.circleci/config.yml.in index e83a4e8c33..3830d7f881 100644 --- a/.circleci/config.yml.in +++ b/.circleci/config.yml.in @@ -559,6 +559,9 @@ jobs: root: ./ paths: - "*" + - store_artifacts: + path: ./docs/build/html + destination: docs upload_docs: <<: *binary_common diff --git a/docs/requirements.txt b/docs/requirements.txt index c4dae765eb..560a2b3600 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,2 @@ sphinx==2.4.4 -sphinxcontrib-googleanalytics -e git+git://github.com/pytorch/pytorch_sphinx_theme.git#egg=pytorch_sphinx_theme diff --git a/docs/source/conf.py b/docs/source/conf.py index 2116258ead..8f8c5fa6e2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -111,6 +111,7 @@ 'collapse_navigation': False, 'display_version': True, 'logo_only': True, + 'analytics_id': 'UA-117752657-2', } html_logo = '_static/img/pytorch-logo-dark.svg' From dac4b9c1fd3172e3d50e8150a6e270f13fb6ba15 Mon Sep 17 00:00:00 2001 From: Parmeet Singh Bhatia Date: Mon, 26 Apr 2021 15:04:19 -0700 Subject: [PATCH 56/68] Import torchtext #1293 d2a0776 Summary: Importing torchtext from github for regular sync. Reviewed By: cpuhrsch Differential Revision: D27983819 fbshipit-source-id: 5806421d788afaa872f5320b5f4cbcd913e103ea --- setup.py | 18 +++++----- test/data/test_builtin_datasets.py | 31 ---------------- test/experimental/test_vocab.py | 2 +- test/experimental/test_with_asset.py | 54 +++++++++++++--------------- test/legacy/data/test_dataset.py | 32 +++++++++++++++++ torchtext/experimental/vocab.py | 24 ++++++------- version.txt | 1 + 7 files changed, 78 insertions(+), 84 deletions(-) create mode 100644 version.txt diff --git a/setup.py b/setup.py index 95fffe4035..5db3388053 100644 --- a/setup.py +++ b/setup.py @@ -18,19 +18,19 @@ def read(*names, **kwargs): def _get_version(): - version = '0.10.0a0' - sha = None - try: cmd = ['git', 'rev-parse', 'HEAD'] sha = subprocess.check_output(cmd, cwd=str(ROOT_DIR)).decode('ascii').strip() except Exception: - pass - - if os.getenv('BUILD_VERSION'): - version = os.getenv('BUILD_VERSION') - elif sha is not None: - version += '+' + sha[:7] + sha = None + + if 'BUILD_VERSION' in os.environ: + version = os.environ['BUILD_VERSION'] + else: + with open(os.path.join(ROOT_DIR, 'version.txt'), 'r') as f: + version = f.readline().strip() + if sha is not None: + version += '+' + sha[:7] if sha is None: sha = 'Unknown' diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index d229229e19..b5c36a84da 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -5,7 +5,6 @@ import torchtext import json import hashlib -from torchtext.legacy import data from parameterized import parameterized from ..common.torchtext_test_case import TorchtextTestCase from ..common.parameterized_utils import load_params @@ -35,23 +34,6 @@ def _helper_test_func(self, length, target_length, results, target_results): target_results = tuple(torch.tensor(item, dtype=torch.int64) for item in target_results) self.assertEqual(results, target_results) - def test_wikitext2_legacy(self): - from torchtext.legacy.datasets import WikiText2 - cachedir = os.path.join(self.project_root, ".data", "wikitext-2") - conditional_remove(cachedir) - - ds = WikiText2 - TEXT = data.Field(lower=True, batch_first=True) - train, valid, test = ds.splits(TEXT) - TEXT.build_vocab(train) - train_iter, valid_iter, test_iter = data.BPTTIterator.splits( - (train, valid, test), batch_size=3, bptt_len=30) - - train_iter, valid_iter, test_iter = ds.iters(batch_size=4, - bptt_len=30) - - conditional_remove(cachedir) - def test_wikitext2(self): from torchtext.experimental.datasets import WikiText2 cachedir = os.path.join(self.project_root, ".data", "wikitext-2") @@ -91,19 +73,6 @@ def test_wikitext2(self): conditional_remove(cachedir) conditional_remove(cachefile) - def test_penntreebank_legacy(self): - from torchtext.legacy.datasets import PennTreebank - # smoke test to ensure penn treebank works properly - TEXT = data.Field(lower=True, batch_first=True) - ds = PennTreebank - train, valid, test = ds.splits(TEXT) - TEXT.build_vocab(train) - train_iter, valid_iter, test_iter = data.BPTTIterator.splits( - (train, valid, test), batch_size=3, bptt_len=30) - - train_iter, valid_iter, test_iter = ds.iters(batch_size=4, - bptt_len=30) - def test_penntreebank(self): from torchtext.experimental.datasets import PennTreebank # smoke test to ensure penn treebank works properly diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 879c03e72d..85c58ea67d 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -219,7 +219,7 @@ def test_vocab_load_and_save(self): def test_build_vocab_iterator(self): iterator = [['hello', 'hello', 'hello', 'freq_low', 'hello', 'world', 'world', 'world', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'freq_low', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T']] + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'freq_low', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T']] v = build_vocab_from_iterator(iterator) expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} diff --git a/test/experimental/test_with_asset.py b/test/experimental/test_with_asset.py index a9be86d81b..2055e0ab57 100644 --- a/test/experimental/test_with_asset.py +++ b/test/experimental/test_with_asset.py @@ -78,13 +78,12 @@ class TestTransformsWithAsset(TorchtextTestCase): def test_vocab_transform(self): asset_name = 'vocab_test2.txt' asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: - vocab_transform = VocabTransform(load_vocab_from_file(f)) - self.assertEqual(vocab_transform(['of', 'that', 'new']), - [7, 18, 24]) - jit_vocab_transform = torch.jit.script(vocab_transform) - self.assertEqual(jit_vocab_transform(['of', 'that', 'new', 'that']), - [7, 18, 24, 18]) + vocab_transform = VocabTransform(load_vocab_from_file(asset_path)) + self.assertEqual(vocab_transform(['of', 'that', 'new']), + [7, 18, 24]) + jit_vocab_transform = torch.jit.script(vocab_transform) + self.assertEqual(jit_vocab_transform(['of', 'that', 'new', 'that']), + [7, 18, 24, 18]) def test_errors_vectors_python(self): tokens = [] @@ -179,27 +178,25 @@ def test_glove_different_dims(self): def test_vocab_from_file(self): asset_name = 'vocab_test.txt' asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: - v = load_vocab_from_file(f, unk_token='') - expected_itos = ['', 'b', 'a', 'c'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) + v = load_vocab_from_file(asset_path, unk_token='') + expected_itos = ['', 'b', 'a', 'c'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) def test_vocab_from_raw_text_file(self): asset_name = 'vocab_raw_text_test.txt' asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: - tokenizer = basic_english_normalize() - jit_tokenizer = torch.jit.script(tokenizer) - v = build_vocab_from_text_file(f, jit_tokenizer, unk_token='') - expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', - 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', - 'pension', 'representing', 'say', 'stricken', 't', 'they', 'turner', - 'unions', 'with', 'workers'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) + tokenizer = basic_english_normalize() + jit_tokenizer = torch.jit.script(tokenizer) + v = build_vocab_from_text_file(asset_path, jit_tokenizer, unk_token='') + expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', + 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', + 'pension', 'representing', 'say', 'stricken', 't', 'they', 'turner', + 'unions', 'with', 'workers'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) def test_builtin_pretrained_sentencepiece_processor(self): sp_model_path = download_from_url(PRETRAINED_SP_MODEL['text_unigram_25000']) @@ -241,11 +238,10 @@ def batch_func(data): def test_text_sequential_transform(self): asset_name = 'vocab_test2.txt' asset_path = get_asset_path(asset_name) - with open(asset_path, 'r') as f: - pipeline = TextSequentialTransforms(basic_english_normalize(), load_vocab_from_file(f)) - jit_pipeline = torch.jit.script(pipeline) - self.assertEqual(pipeline('of that new'), [7, 18, 24]) - self.assertEqual(jit_pipeline('of that new'), [7, 18, 24]) + pipeline = TextSequentialTransforms(basic_english_normalize(), load_vocab_from_file(asset_path)) + jit_pipeline = torch.jit.script(pipeline) + self.assertEqual(pipeline('of that new'), [7, 18, 24]) + self.assertEqual(jit_pipeline('of that new'), [7, 18, 24]) def test_vectors_from_file(self): asset_name = 'vectors_test.csv' diff --git a/test/legacy/data/test_dataset.py b/test/legacy/data/test_dataset.py index 4f5a05c67e..80484b126b 100644 --- a/test/legacy/data/test_dataset.py +++ b/test/legacy/data/test_dataset.py @@ -8,9 +8,41 @@ import pytest from ...common.torchtext_test_case import TorchtextTestCase +from ...common.assets import conditional_remove class TestDataset(TorchtextTestCase): + + def test_wikitext2_legacy(self): + from torchtext.legacy.datasets import WikiText2 + cachedir = os.path.join(self.project_root, ".data", "wikitext-2") + conditional_remove(cachedir) + + ds = WikiText2 + TEXT = data.Field(lower=True, batch_first=True) + train, valid, test = ds.splits(TEXT) + TEXT.build_vocab(train) + train_iter, valid_iter, test_iter = data.BPTTIterator.splits( + (train, valid, test), batch_size=3, bptt_len=30) + + train_iter, valid_iter, test_iter = ds.iters(batch_size=4, + bptt_len=30) + + conditional_remove(cachedir) + + def test_penntreebank_legacy(self): + from torchtext.legacy.datasets import PennTreebank + # smoke test to ensure penn treebank works properly + TEXT = data.Field(lower=True, batch_first=True) + ds = PennTreebank + train, valid, test = ds.splits(TEXT) + TEXT.build_vocab(train) + train_iter, valid_iter, test_iter = data.BPTTIterator.splits( + (train, valid, test), batch_size=3, bptt_len=30) + + train_iter, valid_iter, test_iter = ds.iters(batch_size=4, + bptt_len=30) + def test_tabular_simple_data(self): for data_format in ["csv", "tsv", "json"]: self.write_test_ppid_dataset(data_format=data_format) diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 2f13b083d6..7045ba65b0 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -19,12 +19,11 @@ logger = logging.getLogger(__name__) -def build_vocab_from_text_file(file_object, jited_tokenizer, min_freq=1, unk_token='', num_cpus=4): +def build_vocab_from_text_file(file_path, jited_tokenizer, min_freq=1, unk_token='', num_cpus=4): r"""Create a `Vocab` object from a raw text file. - The `file_object` can contain any raw text. This function applies a generic JITed tokenizer in - parallel to the text. Note that the vocab will be created in the order that the tokens first appear - in the file (and not by the frequency of tokens). + The `file_path` can contain any raw text. This function applies a generic JITed tokenizer in + parallel to the text. Args: file_object (FileObject): a file object to read data from. @@ -40,20 +39,18 @@ def build_vocab_from_text_file(file_object, jited_tokenizer, min_freq=1, unk_tok Examples: >>> from torchtext.experimental.vocab import build_vocab_from_text_file >>> from torchtext.experimental.transforms import basic_english_normalize - >>> f = open('vocab.txt', 'r') - >>> tokenizer = basic_english_normalize() + >>> tokenizer = basic_english_normalize() >>> tokenizer = basic_english_normalize() >>> jit_tokenizer = torch.jit.script(tokenizer) - >>> v = build_vocab_from_text_file(f, jit_tokenizer) + >>> v = build_vocab_from_text_file('vocab.txt', jit_tokenizer) """ - vocab_obj = _build_vocab_from_text_file(file_object.name, unk_token, min_freq, num_cpus, jited_tokenizer) + vocab_obj = _build_vocab_from_text_file(file_path, unk_token, min_freq, num_cpus, jited_tokenizer) return Vocab(vocab_obj) -def load_vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4): +def load_vocab_from_file(file_path, min_freq=1, unk_token='', num_cpus=4): r"""Create a `Vocab` object from a text file. - The `file_object` should contain tokens separated by new lines. Note that the vocab - will be created in the order that the tokens first appear in the file (and not by the frequency of tokens). + The `file_path` should contain tokens separated by new lines. Format for txt file: token1 @@ -73,11 +70,10 @@ def load_vocab_from_file(file_object, min_freq=1, unk_token='', num_cpus=4) Examples: >>> from torchtext.experimental.vocab import load_vocab_from_file - >>> f = open('vocab.txt', 'r') - >>> v = load_vocab_from_file(f) + >>> v = load_vocab_from_file('vocab.txt') """ - vocab_obj = _load_vocab_from_file(file_object.name, unk_token, min_freq, num_cpus) + vocab_obj = _load_vocab_from_file(file_path, unk_token, min_freq, num_cpus) return Vocab(vocab_obj) diff --git a/version.txt b/version.txt new file mode 100644 index 0000000000..37f1777fc3 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.10.0a0 From b9a38f2af0824e39a49d17bc1f867e71e59e0a4b Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Thu, 29 Apr 2021 13:33:03 -0700 Subject: [PATCH 57/68] Import torchtext #1291 0790ce6 Reviewed By: parmeet Differential Revision: D28101664 fbshipit-source-id: a8643b3ecf85de2cb815dcfa5789a4a5d246d80f --- benchmark/benchmark_experimental_vocab.py | 43 +++++++++++++++++++++-- version.txt | 2 +- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 3cd4e49a1d..1be3e190eb 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -1,7 +1,10 @@ import argparse from collections import (Counter, OrderedDict) import time - +import random +import string +from timeit import default_timer as timer +from matplotlib import pyplot as plt import torch from torchtext.experimental.datasets import DATASETS from torchtext.experimental.vocab import ( @@ -16,6 +19,42 @@ from torchtext.experimental.transforms import basic_english_normalize +def compare_legacy_and_experimental_batch_lookup(): + num_tokens = 1000 + num_letters = 6 + num_lines = 100000 + vocab = [''.join(random.sample(string.ascii_letters * num_letters, num_letters)) for _ in range(num_tokens)] + counter = Counter() + counter.update(vocab) + legacy_vocab = Vocab(counter) + experimental_vocab = VocabExperimental(counter) + speed_ups = [] + token_lengths = [i for i in range(2, 100)] + for i in token_lengths: + lines = [random.sample(vocab, i) for _ in range(num_lines)] + start_time = timer() + for text in lines: + legacy_vocab.lookup_indices(text) + legacy_time = timer() - start_time + + start_time = timer() + for text in lines: + experimental_vocab.lookup_indices(text) + + experimental_time = timer() - start_time + + speed_ups.append(legacy_time / experimental_time) + print("speed-up={} for average length={}".format(legacy_time / experimental_time, i)) + del lines + + plt.close() + fig, ax = plt.subplots(1, 1) + ax.plot(token_lengths, speed_ups) + ax.set_xlabel('Average Tokens per line') + ax.set_ylabel('Speed-up') + plt.savefig("speedup.jpg") + + def legacy_vocab_from_file_object(file_like_object, **kwargs): r"""Create a `Vocab` object from a file like object. @@ -76,7 +115,7 @@ def benchmark_experimental_vocab_construction(vocab_file_path, is_raw_text=True, print("Construction time:", time.monotonic() - t0) -def benchmark_experimental_vocab_lookup(vocab_file_path=None, dataset = 'AG_NEWS'): +def benchmark_experimental_vocab_lookup(vocab_file_path=None, dataset='AG_NEWS'): def _run_benchmark_lookup(tokens, vocab): t0 = time.monotonic() # list lookup diff --git a/version.txt b/version.txt index 37f1777fc3..7e4490fc70 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.10.0a0 +0.10.0a0 \ No newline at end of file From 9b3a0af5f8b2dbf9f3eb32d343a4fb8095f4f886 Mon Sep 17 00:00:00 2001 From: Parmeet Singh Bhatia Date: Fri, 30 Apr 2021 06:42:58 -0700 Subject: [PATCH 58/68] adding __contains__ method to experimental vocab (#1297) Reviewed By: cpuhrsch Differential Revision: D28111696 fbshipit-source-id: fef195941492493a399adb37339cfa64795e22a0 --- test/experimental/test_vocab.py | 11 +++++++++++ torchtext/csrc/register_bindings.cpp | 9 +++++++++ torchtext/csrc/vocab.cpp | 9 +++++++++ torchtext/csrc/vocab.h | 1 + torchtext/experimental/vocab.py | 11 +++++++++++ version.txt | 2 +- 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index 85c58ea67d..d091d7796b 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -33,6 +33,17 @@ def test_new_unk(self): self.assertEqual(v[''], 0) self.assertEqual(v['not_in_it'], 0) + def test_vocab_membership(self): + token_to_freq = {'': 2, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=2) + + self.assertTrue('' in v) + self.assertTrue('a' in v) + self.assertTrue('b' in v) + self.assertFalse('c' in v) + def test_vocab_get_item(self): token_to_freq = {'': 2, 'a': 2, 'b': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index e41783cef1..0b325bcda6 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -107,6 +107,12 @@ PYBIND11_MODULE(_torchtext, m) { .def(py::init, std::string>()) .def_readonly("itos_", &Vocab::itos_) .def_readonly("unk_token_", &Vocab::unk_token_) + .def("__contains__", + [](c10::intrusive_ptr &self, const py::str &item) -> bool { + ssize_t length; + const char *buffer = PyUnicode_AsUTF8AndSize(item.ptr(), &length); + return self->__contains__(c10::string_view{buffer, (size_t)length}); + }) .def("__getitem__", [](c10::intrusive_ptr &self, const py::str &item) -> int64_t { ssize_t length; @@ -229,6 +235,9 @@ TORCH_LIBRARY_FRAGMENT(torchtext, m) { m.class_("Vocab") .def(torch::init()) + .def("__contains__", + [](const c10::intrusive_ptr &self, const std::string &item) + -> bool { return self->__contains__(c10::string_view{item}); }) .def("__getitem__", [](const c10::intrusive_ptr &self, const std::string &item) -> int64_t { return self->__getitem__(c10::string_view{item}); }) diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index b6fa2099d7..1831d46f39 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -30,6 +30,15 @@ Vocab::Vocab(const StringList &tokens, const std::string &unk_token) int64_t Vocab::__len__() const { return itos_.size(); } +bool Vocab::__contains__(const c10::string_view &token) const { + int64_t id = _find(token); + if (stoi_[id] != -1) { + return true; + } + return false; +} + + int64_t Vocab::__getitem__(const c10::string_view &token) const { int64_t id = _find(token); if (stoi_[id] != -1) { diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h index 660f6145d4..d915c7de27 100644 --- a/torchtext/csrc/vocab.h +++ b/torchtext/csrc/vocab.h @@ -21,6 +21,7 @@ struct Vocab : torch::CustomClassHolder { const std::string &unk_token); int64_t __len__() const; int64_t __getitem__(const c10::string_view &token) const; + bool __contains__(const c10::string_view &token) const; void append_token(const std::string &token); void insert_token(const std::string &token, const int64_t &index); std::string lookup_token(const int64_t &index); diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 7045ba65b0..26f393ce36 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -175,6 +175,17 @@ def __len__(self) -> int: """ return len(self.vocab) + @torch.jit.export + def __contains__(self, token: str) -> bool: + r""" + Args: + token (str): the token for which to check the membership + + Returns: + membership (bool): whether the token is member of vocab or not + """ + return self.vocab.__contains__(token) + @torch.jit.export def __getitem__(self, token: str) -> int: r""" diff --git a/version.txt b/version.txt index 7e4490fc70..37f1777fc3 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.10.0a0 \ No newline at end of file +0.10.0a0 From 37a41de812f548fae43669d705db54fd9db4ae72 Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Mon, 10 May 2021 09:50:18 -0700 Subject: [PATCH 59/68] Import torchtext #1292 ede6ce65eb5405ff1f8801ff6b354bb1cd242108 Summary: This diff syncs torchtext GH with fbcode Reviewed By: cpuhrsch Differential Revision: D28321356 fbshipit-source-id: 7736f0d100941627b58424911a1329b1ce66c123 --- docs/source/data_functional.rst | 11 ++++ docs/source/datasets.rst | 14 ++++- torchtext/data/__init__.py | 18 ++++-- torchtext/data/functional.py | 106 +++++++++++++++++++++++++++++++- 4 files changed, 139 insertions(+), 10 deletions(-) diff --git a/docs/source/data_functional.rst b/docs/source/data_functional.rst index 347f3b4333..d044025477 100644 --- a/docs/source/data_functional.rst +++ b/docs/source/data_functional.rst @@ -41,3 +41,14 @@ torchtext.data.functional ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autofunction:: numericalize_tokens_from_iterator + + +:hidden:`filter_wikipedia_xml` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: filter_wikipedia_xml + +:hidden:`to_map_style_dataset` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: to_map_style_dataset diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index adead6c4a4..4f45d217a1 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -27,9 +27,6 @@ The following datasets are available: Text Classification ^^^^^^^^^^^^^^^^^^^ -TextClassificationDataset -~~~~~~~~~~~~~~~~~~~~~~~~~ - AG_NEWS ~~~~~~~ @@ -126,6 +123,7 @@ CoNLL2000Chunking .. autofunction:: CoNLL2000Chunking + Question Answer ^^^^^^^^^^^^^^^ @@ -139,3 +137,13 @@ SQuAD 2.0 ~~~~~~~~~ .. autofunction:: SQuAD2 + + +Unsupervised Learning +^^^^^^^^^^^^^^^^^^^^^ + +EnWik9 +~~~~~~ + +.. autofunction:: EnWik9 + diff --git a/torchtext/data/__init__.py b/torchtext/data/__init__.py index e5a5cccf71..d2aa64ccaf 100644 --- a/torchtext/data/__init__.py +++ b/torchtext/data/__init__.py @@ -1,10 +1,16 @@ from .metrics import bleu_score from .utils import get_tokenizer, interleave_keys -from .functional import generate_sp_model, \ - load_sp_model, \ - sentencepiece_numericalizer, \ - sentencepiece_tokenizer, custom_replace, simple_space_split, \ - numericalize_tokens_from_iterator +from .functional import ( + generate_sp_model, + load_sp_model, + sentencepiece_numericalizer, + sentencepiece_tokenizer, + custom_replace, + simple_space_split, + numericalize_tokens_from_iterator, + filter_wikipedia_xml, + to_map_style_dataset, +) from ..legacy.data import Batch @@ -14,5 +20,7 @@ "sentencepiece_numericalizer", "sentencepiece_tokenizer", "custom_replace", "simple_space_split", "numericalize_tokens_from_iterator", + "filter_wikipedia_xml", + "to_map_style_dataset", "Batch" # tmp compatibility hack for old lightning ] diff --git a/torchtext/data/functional.py b/torchtext/data/functional.py index 995025e929..73ec50fa6c 100644 --- a/torchtext/data/functional.py +++ b/torchtext/data/functional.py @@ -2,11 +2,12 @@ import io import torch - __all__ = [ "generate_sp_model", "load_sp_model", "sentencepiece_numericalizer", "sentencepiece_tokenizer", - "numericalize_tokens_from_iterator" + "numericalize_tokens_from_iterator", + "filter_wikipedia_xml", + "to_map_style_dataset", ] @@ -180,3 +181,104 @@ def numericalize_tokens_from_iterator(vocab, iterator, removed_tokens=None): else: yield iter(map(lambda x: vocab[x], filter(lambda x: x not in removed_tokens, tokens))) + + +_patterns = [(r'<.*>', ''), + (r'&', '&'), + (r'<', '<'), + (r'>', '>'), + (r'', ''), + (r'<[^>]*>', ''), + (r'\[http:[^] ]*', '['), + (r'\|thumb', ''), + (r'\|left', ''), + (r'\|right', ''), + (r'\|\d+px', ''), + (r'\[\[image:[^\[\]]*\|', ''), + (r'\[\[category:([^|\]]*)[^]]*\]\]', '[[$1]]'), + (r'\[\[[a-z\-]*:[^\]]*\]\]', ''), + (r'\[\[[^\|\]]*\|', '[['), + (r'\{\{[^\}]*\}\}', ''), + (r'\{[^\}]*\}', ''), + (r'\[', ''), + (r'\]', ''), + (r'&[^;]*;', ' '), + (r'A', 'a'), (r'B', 'b'), (r'C', 'c'), + (r'D', 'd'), (r'E', 'e'), (r'F', 'f'), + (r'G', 'g'), (r'H', 'h'), (r'I', 'i'), + (r'J', 'j'), (r'K', 'k'), (r'L', 'l'), + (r'M', 'm'), (r'N', 'n'), (r'O', 'o'), + (r'P', 'p'), (r'Q', 'q'), (r'R', 'r'), + (r'S', 's'), (r'T', 't'), (r'U', 'u'), + (r'V', 'v'), (r'W', 'w'), (r'X', 'x'), + (r'Y', 'y'), (r'Z', 'z'), + (r'0', ' zero '), (r'1', ' one '), (r'2', ' two '), + (r'3', ' three '), (r'4', ' four '), (r'5', ' five '), + (r'6', ' six '), (r'7', ' seven '), (r'8', ' eight '), + (r'9', ' nine '), + (r'[^a-z\n]+', ' '), + (r'\n ', ''), + (r'\s+', ' '), + (r'\n\s*\n', r'\n') + ] + + +def filter_wikipedia_xml(text_iterator): + r"""Filter wikipedia xml lines according to https://github.com/facebookresearch/fastText/blob/master/wikifil.pl + + args: + text_iterator: An iterator type object that yields strings. Examples include string list, text io, generators etc. + + Examples: + >>> from torchtext.data.functional import filter_wikipedia_xml + >>> from torchtext.datasets import EnWik9 + >>> data_iter = EnWik9(split='train') + >>> filter_data_iter = filter_wikipedia_xml(data_iter) + >>> file_name = '.data/EnWik9/enwik9' + >>> filter_data_iter = filter_wikipedia_xml(open(file_name,'r')) + """ + + try: + iter(text_iterator) + except: + raise TypeError("Input {} must support iterator semantics".format(text_iterator)) + + norm_transform = custom_replace(_patterns) + for line in text_iterator: + if '#redirect' in line or '#REDIRECT' in line: + continue + line = list(norm_transform([line]))[0].strip() + if line: + yield line + + +def to_map_style_dataset(iter_data): + r"""Convert iterable-style dataset to map-style dataset. + + args: + iter_data: An iterator type object. Examples include Iterable datasets, string list, text io, generators etc. + + + Examples: + >>> from torchtext.datasets import IMDB + >>> from torchtext.data import to_map_style_dataset + >>> train_iter = IMDB(split='train') + >>> train_dataset = to_map_style_dataset(train_iter) + >>> file_name = '.data/EnWik9/enwik9' + >>> data_iter = to_map_style_dataset(open(file_name,'r')) + """ + + # Inner class to convert iterable-style to map-style dataset + class _MapStyleDataset(torch.utils.data.Dataset): + + def __init__(self, iter_data): + # TODO Avoid list issue #1296 + self._data = list(iter_data) + + def __len__(self): + return len(self._data) + + def __getitem__(self, idx): + return self._data[idx] + + return _MapStyleDataset(iter_data) From 6231993d381e2a16b39045b4e0a71daf93042527 Mon Sep 17 00:00:00 2001 From: Christian Puhrsch Date: Mon, 17 May 2021 11:49:18 -0700 Subject: [PATCH 60/68] Added APIs for default index and removed unk token (#1302) Reviewed By: parmeet Differential Revision: D28478153 fbshipit-source-id: bfcaffe8fe48e96d8df454f7df0d25ec39d5d4a6 --- test/experimental/test_vocab.py | 79 ++++++---- torchtext/csrc/register_bindings.cpp | 33 ++-- torchtext/csrc/vocab.cpp | 222 ++++++++++++--------------- torchtext/csrc/vocab.h | 30 +++- torchtext/experimental/vocab.py | 58 +++++-- 5 files changed, 238 insertions(+), 184 deletions(-) diff --git a/test/experimental/test_vocab.py b/test/experimental/test_vocab.py index d091d7796b..afb140c71e 100644 --- a/test/experimental/test_vocab.py +++ b/test/experimental/test_vocab.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- from collections import OrderedDict import os -import platform import torch -import unittest from test.common.torchtext_test_case import TorchtextTestCase from torchtext.experimental.vocab import ( vocab, @@ -20,18 +18,12 @@ def tearDown(self): def test_has_unk(self): c = OrderedDict() v = vocab(c) - - # check if unk is mapped to the first index - self.assertEqual(v['not_in_it'], 0) self.assertEqual(v[''], 0) def test_new_unk(self): c = OrderedDict() v = vocab(c, unk_token="") - - # check if new_unk is mapped to the first index self.assertEqual(v[''], 0) - self.assertEqual(v['not_in_it'], 0) def test_vocab_membership(self): token_to_freq = {'': 2, 'a': 2, 'b': 2} @@ -54,6 +46,50 @@ def test_vocab_get_item(self): self.assertEqual(v['a'], 1) self.assertEqual(v['b'], 2) + def test_reassign_token(self): + token_to_freq = {'': 1, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=1) + + self.assertEqual(v[''], 2) + self.assertEqual(v['a'], 0) + self.assertEqual(v['b'], 1) + v.reassign_token('', 0) + self.assertEqual(v[''], 0) + self.assertEqual(v['a'], 1) + self.assertEqual(v['b'], 2) + + self.assertEqual(v.get_itos(), ['', 'a', 'b']) + + with self.assertRaises(RuntimeError): + v.reassign_token('not in vocab', 0) + + with self.assertRaises(RuntimeError): + v.reassign_token('', 3) + + def test_default_index(self): + token_to_freq = {'': 2, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=2) + + self.assertTrue(v.get_default_index() is None) + with self.assertRaises(RuntimeError): + v['not in vocab'] + + v.set_default_index(0) + self.assertEqual(v['not in vocab'], 0) + + def test_default_index_jit(self): + token_to_freq = {'': 2, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=2) + v.set_default_index(0) + v_jit = torch.jit.script(v) + self.assertEqual(v_jit['not in vocab'], 0) + def test_vocab_insert_token(self): c = OrderedDict({'': 2, 'a': 2}) @@ -88,6 +124,10 @@ def test_vocab_append_token(self): self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) + # token must not exist to be appended + with self.assertRaises(RuntimeError): + v.append_token('b') + def test_vocab_len(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) @@ -149,6 +189,8 @@ def test_vocab_lookup_token(self): v = vocab(c) self.assertEqual(v.lookup_token(1), 'a') + with self.assertRaises(RuntimeError): + v.lookup_token(100) def test_vocab_lookup_tokens(self): token_to_freq = {'a': 2, 'b': 2, 'c': 2} @@ -172,24 +214,6 @@ def test_vocab_lookup_indices(self): self.assertEqual(v.lookup_indices(tokens), expected_indices) - # we separate out these errors because Windows runs into seg faults when propagating - # exceptions from C++ using pybind11 - @unittest.skipIf(platform.system() == "Windows", "Test is known to fail on Windows.") - def test_errors_vocab_cpp(self): - token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - - with self.assertRaises(RuntimeError): - # Test proper error raised when setting a token out of bounds - v = vocab(c, min_freq=3) - v.insert_token('new_token', 100) - - with self.assertRaises(RuntimeError): - # Test proper error raised when looking up a token out of bounds - v = vocab(c) - v.lookup_token(100) - def test_errors_vocab_python(self): token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) @@ -205,6 +229,7 @@ def test_vocab_load_and_save(self): c = OrderedDict(sorted_by_freq_tuples) v = vocab(c, min_freq=3) + v.set_default_index(0) expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} @@ -218,6 +243,7 @@ def test_vocab_load_and_save(self): loaded_v = torch.load(vocab_path) self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + self.assertEqual(v['not in vocab'], 0) with self.subTest('torchscript'): vocab_path = os.path.join(self.test_dir, 'vocab_torchscript.pt') @@ -227,6 +253,7 @@ def test_vocab_load_and_save(self): loaded_v = torch.load(vocab_path) self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + self.assertEqual(v['not in vocab'], 0) def test_build_vocab_iterator(self): iterator = [['hello', 'hello', 'hello', 'freq_low', 'hello', 'world', 'world', 'world', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index 0b325bcda6..cf6656d12a 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -15,12 +15,10 @@ namespace py = pybind11; namespace { Vocab build_vocab_from_text_file(const std::string &file_path, - const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus, py::object fn) { torch::jit::script::Module module(*torch::jit::as_module(fn)); - return _build_vocab_from_text_file(file_path, unk_token, min_freq, num_cpus, - module); + return _build_vocab_from_text_file(file_path, min_freq, num_cpus, module); } } // namespace @@ -104,23 +102,27 @@ PYBIND11_MODULE(_torchtext, m) { })); py::class_>(m, "Vocab") - .def(py::init, std::string>()) + .def(py::init>()) .def_readonly("itos_", &Vocab::itos_) - .def_readonly("unk_token_", &Vocab::unk_token_) - .def("__contains__", - [](c10::intrusive_ptr &self, const py::str &item) -> bool { - ssize_t length; - const char *buffer = PyUnicode_AsUTF8AndSize(item.ptr(), &length); - return self->__contains__(c10::string_view{buffer, (size_t)length}); - }) + .def_readonly("default_index_", &Vocab::default_index_) + .def( + "__contains__", + [](c10::intrusive_ptr &self, const py::str &item) -> bool { + ssize_t length; + const char *buffer = PyUnicode_AsUTF8AndSize(item.ptr(), &length); + return self->__contains__(c10::string_view{buffer, (size_t)length}); + }) .def("__getitem__", [](c10::intrusive_ptr &self, const py::str &item) -> int64_t { ssize_t length; const char *buffer = PyUnicode_AsUTF8AndSize(item.ptr(), &length); return self->__getitem__(c10::string_view{buffer, (size_t)length}); }) - .def("__len__", &Vocab::__len__) + .def("reassign_token", &Vocab::reassign_token) .def("insert_token", &Vocab::insert_token) + .def("set_default_index", &Vocab::set_default_index) + .def("get_default_index", &Vocab::get_default_index) + .def("__len__", &Vocab::__len__) .def("append_token", &Vocab::append_token) .def("lookup_token", &Vocab::lookup_token) .def("lookup_tokens", &Vocab::lookup_tokens) @@ -234,15 +236,18 @@ TORCH_LIBRARY_FRAGMENT(torchtext, m) { }); m.class_("Vocab") - .def(torch::init()) + .def(torch::init>()) .def("__contains__", [](const c10::intrusive_ptr &self, const std::string &item) -> bool { return self->__contains__(c10::string_view{item}); }) .def("__getitem__", [](const c10::intrusive_ptr &self, const std::string &item) -> int64_t { return self->__getitem__(c10::string_view{item}); }) - .def("__len__", &Vocab::__len__) + .def("reassign_token", &Vocab::reassign_token) .def("insert_token", &Vocab::insert_token) + .def("__len__", &Vocab::__len__) + .def("set_default_index", &Vocab::set_default_index) + .def("get_default_index", &Vocab::get_default_index) .def("append_token", &Vocab::append_token) .def("lookup_token", &Vocab::lookup_token) .def("lookup_tokens", &Vocab::lookup_tokens) diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index 1831d46f39..e659fbdb70 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -7,27 +7,21 @@ #include // @manual namespace torchtext { -Vocab::Vocab(const StringList &tokens, const std::string &unk_token) - : stoi_(MAX_VOCAB_SIZE, -1), unk_token_(std::move(unk_token)) { - for (std::size_t i = 0; i < tokens.size(); i++) { - // tokens should not have any duplicates - auto token_position = - _find(c10::string_view{tokens[i].data(), tokens[i].size()}); - if (stoi_[token_position] != -1) { -#ifdef _MSC_VER - std::cerr << "[RuntimeError] Duplicate token found in tokens list: " - << tokens[i] << std::endl; -#endif - throw std::runtime_error("Duplicate token found in tokens list: " + - tokens[i]); - } +Vocab::Vocab(const StringList &tokens, + const c10::optional &default_index) + : stoi_(MAX_VOCAB_SIZE, -1), default_index_{default_index} { + for (size_t i = 0; i < tokens.size(); i++) { + // throw error if duplicate token is found + auto id = _find(c10::string_view{tokens[i].data(), tokens[i].size()}); + TORCH_CHECK(stoi_[id] == -1, + "Duplicate token found in tokens list: " + tokens[i]); + _add(tokens[i]); } - - unk_index_ = - stoi_[_find(c10::string_view{unk_token.data(), unk_token.size()})]; } +Vocab::Vocab(const StringList &tokens) : Vocab(tokens, {}) {} + int64_t Vocab::__len__() const { return itos_.size(); } bool Vocab::__contains__(const c10::string_view &token) const { @@ -38,77 +32,92 @@ bool Vocab::__contains__(const c10::string_view &token) const { return false; } - int64_t Vocab::__getitem__(const c10::string_view &token) const { int64_t id = _find(token); - if (stoi_[id] != -1) { + if (stoi_[id] != -1) return stoi_[id]; - } - return unk_index_; + + // throw error if default_index_ is not set + TORCH_CHECK(default_index_.has_value(), + "Token " + std::string(token) + + " not found and default index is not set"); + + // return default index if token is OOV + return default_index_.value(); } -void Vocab::append_token(const std::string &token) { _add(token); } +void Vocab::set_default_index(int64_t index) { default_index_ = index; } + +c10::optional Vocab::get_default_index() const { + return default_index_; +} + +void Vocab::append_token(const std::string &token) { + // throw error if token already exist in vocab + auto id = _find(c10::string_view{token.data(), token.size()}); + TORCH_CHECK(stoi_[id] == -1, "Token " + token + + " already exists in the Vocab with index: " + + std::to_string(stoi_[id])); + + _add(token); +} + +void Vocab::reassign_token(const std::string &token, const int64_t &index) { + // throw error if index is not valid + TORCH_CHECK(index >= 0 && index < __len__(), + "Specified index " + std::to_string(index) + + " is out of bounds for vocab of size " + + std::to_string(__len__())); + + // throw error if token not found + TORCH_CHECK(__contains__(token), "Token " + token + " not found in Vocab"); + + _remove(token); + insert_token(token, index); +} void Vocab::insert_token(const std::string &token, const int64_t &index) { - if (index < 0 || index > itos_.size()) { -#ifdef _MSC_VER - std::cerr << "[RuntimeError] Specified index " << index - << " is out of bounds of the size of stoi dictionary: " - << stoi_.size() << std::endl; -#endif - throw std::runtime_error( - "Specified index " + std::to_string(index) + - " is out of bounds of the size of stoi dictionary: " + - std::to_string(stoi_.size()) + "."); - } + // throw error if index is not valid + TORCH_CHECK(index >= 0 && index <= __len__(), + "Specified index " + std::to_string(index) + + " is out of bounds for vocab of size " + + std::to_string(__len__())); - // if item already in stoi we throw an error - auto token_position = _find(c10::string_view{token.data(), token.size()}); - if (stoi_[token_position] != -1) { -#ifdef _MSC_VER - std::cerr << "[RuntimeError] Token " << token - << " already exists in the Vocab with index: " - << stoi_[token_position] << std::endl; -#endif - throw std::runtime_error("Token " + token + - " already exists in the Vocab with index: " + - std::to_string(stoi_[token_position]) + "."); - } + // throw error if token already present + TORCH_CHECK(!__contains__(token), "Token " + token + " not found in Vocab"); // need to offset all tokens greater than or equal index by 1 - for (size_t i = index; i < itos_.size(); i++) { + for (size_t i = index; i < __len__(); i++) { stoi_[_find(c10::string_view{itos_[i].data(), itos_[i].size()})] = i + 1; } itos_.insert(itos_.begin() + index, token); stoi_[_find(c10::string_view{token.data(), token.size()})] = index; - - // need to update unk_index in case token equals unk_token or token - // inserted before unk_token - unk_index_ = - stoi_[_find(c10::string_view{unk_token_.data(), unk_token_.size()})]; } std::string Vocab::lookup_token(const int64_t &index) { - if (index < 0 || index > static_cast(itos_.size())) { -#ifdef _MSC_VER - std::cerr << "[RuntimeError] Specified index " << index - << " is out of bounds of the size of itos dictionary: " - << itos_.size() << std::endl; -#endif - throw std::runtime_error( - "Specified index " + std::to_string(index) + - " is out of bounds of the size of itos dictionary: " + - std::to_string(itos_.size()) + "."); - } + // throw error if index is not valid + TORCH_CHECK(index >= 0 && index < __len__(), + "Specified index " + std::to_string(index) + + " is out of bounds for vocab of size " + + std::to_string(__len__())); return itos_[index]; } StringList Vocab::lookup_tokens(const std::vector &indices) { + // throw error if indices are not valid + for (size_t i = 0; i < indices.size(); i++) { + TORCH_CHECK(indices[i] >= 0 && indices[i] < __len__(), + "Specified index " + std::to_string(indices[i]) + + " at position " + std::to_string(i) + + " is out of bounds for vocab of size " + + std::to_string(__len__())); + } + std::vector tokens(indices.size()); - for (int64_t i = 0; i < static_cast(indices.size()); i++) { - tokens[i] = lookup_token(indices[i]); + for (size_t i = 0; i < indices.size(); i++) { + tokens[i] = itos_[indices[i]]; } return tokens; } @@ -116,7 +125,7 @@ StringList Vocab::lookup_tokens(const std::vector &indices) { std::vector Vocab::lookup_indices(const std::vector &tokens) { std::vector indices(tokens.size()); - for (int64_t i = 0; i < static_cast(tokens.size()); i++) { + for (size_t i = 0; i < tokens.size(); i++) { indices[i] = __getitem__(tokens[i]); } return indices; @@ -148,9 +157,7 @@ void parse_vocab_file_chunk(const std::string &file_path, size_t offset, const int64_t start_line, const int64_t end_line, std::shared_ptr counter) { std::ifstream fin(file_path, std::ios::in); - if (!fin.is_open()) { - throw std::runtime_error("Cannot open input file " + file_path + "\n"); - } + TORCH_CHECK(fin.is_open(), "Cannot open input file " + file_path); fin.seekg(offset); @@ -172,9 +179,7 @@ void parse_raw_text_file_chunk(const std::string &file_path, size_t offset, std::shared_ptr counter, torch::jit::script::Module &module) { std::ifstream fin(file_path, std::ios::in); - if (!fin.is_open()) { - throw std::runtime_error("Cannot open input file " + file_path + "\n"); - } + TORCH_CHECK(fin.is_open(), "Cannot open input file " + file_path); fin.seekg(offset); @@ -210,8 +215,9 @@ struct CompareTokens { StringList _concat_tokens(std::vector> chunk_counters, - const std::string &unk_token, const int64_t min_freq, - const int64_t num_lines, const bool sort_tokens) { + const int64_t min_freq, const int64_t num_lines, + const bool sort_tokens) { + TORCH_CHECK(chunk_counters.size() > 0, "There must be at least 1 chunk to concatenate!"); @@ -257,24 +263,12 @@ _concat_tokens(std::vector> chunk_counters, unique_tokens.push_back(token_freq_pair.first); } - // insert unk_token if not present - if (tokens_freq.find(unk_token) == tokens_freq.end()) { - std::cerr << "The `unk_token` " << unk_token - << " wasn't found in the `ordered_dict`. Adding the `unk_token` " - "to the beginning of the Vocab." - << std::endl; - - unique_tokens.insert(unique_tokens.begin(), unk_token); - } - return unique_tokens; } constexpr int64_t GRAIN_SIZE = 13107; Vocab _load_vocab_from_file(const std::string &file_path, - const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus) { - std::cerr << "[INFO] Reading file " << file_path << std::endl; int64_t num_lines = _infer_lines(file_path); int64_t chunk_size = impl::divup(num_lines, num_cpus); @@ -313,17 +307,15 @@ Vocab _load_vocab_from_file(const std::string &file_path, cv.wait(lock, [&thread_count] { return thread_count == 0; }); StringList tokens = - _concat_tokens(chunk_counters, unk_token, min_freq, num_lines, false); + _concat_tokens(chunk_counters, min_freq, num_lines, false); - return Vocab(std::move(tokens), unk_token); + return Vocab(std::move(tokens)); } Vocab _build_vocab_from_text_file(const std::string &file_path, - const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus, torch::jit::script::Module tokenizer) { - std::cerr << "[INFO] Reading file " << file_path << std::endl; int64_t num_lines = _infer_lines(file_path); int64_t chunk_size = impl::divup(num_lines, num_cpus); // Launching a thread on less lines than this likely has too much overhead. @@ -359,18 +351,20 @@ Vocab _build_vocab_from_text_file(const std::string &file_path, std::unique_lock lock(m); cv.wait(lock, [&thread_count] { return thread_count == 0; }); - StringList tokens = - _concat_tokens(chunk_counters, unk_token, min_freq, num_lines, true); + StringList tokens = _concat_tokens(chunk_counters, min_freq, num_lines, true); - return Vocab(std::move(tokens), unk_token); + return Vocab(std::move(tokens)); } VocabStates _serialize_vocab(const c10::intrusive_ptr &self) { std::vector integers; StringList strings = self->itos_; - strings.push_back(self->unk_token_); std::vector tensors; + if (self->default_index_.has_value()) { + integers.push_back(self->default_index_.value()); + } + VocabStates states = std::make_tuple(self->version_str_, std::move(integers), std::move(strings), std::move(tensors)); return states; @@ -378,45 +372,27 @@ VocabStates _serialize_vocab(const c10::intrusive_ptr &self) { c10::intrusive_ptr _deserialize_vocab(VocabStates states) { auto state_size = std::tuple_size::value; - if (state_size != 4) { -#ifdef _MSC_VER - std::cerr << "[RuntimeError] Expected deserialized Vocab to have 4 states " - "but found " - << state_size << " states." << std::endl; -#endif - throw std::runtime_error( - "Expected deserialized Vocab to have 4 states but found " + - std::to_string(state_size) + " states."); - } + TORCH_CHECK(state_size == 4, + "Expected deserialized Vocab to have 4 states but found " + + std::to_string(state_size) + " states"); auto &version_str = std::get<0>(states); auto &integers = std::get<1>(states); auto &strings = std::get<2>(states); auto &tensors = std::get<3>(states); - // check integers and tensors are empty - if (integers.size() != 0 || tensors.size() != 0) { -#ifdef _MSC_VER - std::cerr << "[RuntimeError] Expected `integers` and `tensors` states to " - "be empty." - << std::endl; -#endif - throw std::runtime_error( - "Expected `integers` and `tensors` states to be empty."); - } + // check tensors are empty + TORCH_CHECK(tensors.size() == 0, "Expected `tensors` states to be empty"); - if (version_str.compare("0.0.1") >= 0) { - std::string unk_token = strings.back(); - strings.pop_back(); // remove last element which is unk_token + // throw error if version is not compatible + TORCH_CHECK(version_str.compare("0.0.2") >= 0, + "Found unexpected version for serialized Vocab: " + version_str); - return c10::make_intrusive(std::move(strings), std::move(unk_token)); + c10::optional default_index = {}; + if (integers.size() > 0) { + default_index = integers[0]; } -#ifdef _MSC_VER - std::cerr << "[RuntimeError] Found unexpected version for serialized Vocab: " - << version_str << std::endl; -#endif - throw std::runtime_error( - "Found unexpected version for serialized Vocab: " + version_str + "."); + return c10::make_intrusive(std::move(strings), default_index); } } // namespace torchtext diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h index d915c7de27..06f98865d3 100644 --- a/torchtext/csrc/vocab.h +++ b/torchtext/csrc/vocab.h @@ -1,3 +1,4 @@ +#include #include #include namespace torchtext { @@ -13,17 +14,24 @@ struct Vocab : torch::CustomClassHolder { static const int32_t MAX_VOCAB_SIZE = 30000000; int64_t unk_index_; std::vector stoi_; - const std::string version_str_ = "0.0.1"; + const std::string version_str_ = "0.0.2"; StringList itos_; - std::string unk_token_; + c10::optional default_index_ = {}; - explicit Vocab(const std::vector &tokens, - const std::string &unk_token); + // TODO: [can we remove this?] we need to keep this constructor, otherwise + // torch binding gets compilation error: no matching constructor for + // initialization of 'torchtext::Vocab' + explicit Vocab(const StringList &tokens); + explicit Vocab(const StringList &tokens, + const c10::optional &default_index); int64_t __len__() const; int64_t __getitem__(const c10::string_view &token) const; bool __contains__(const c10::string_view &token) const; - void append_token(const std::string &token); + void set_default_index(int64_t index); + c10::optional get_default_index() const; + void reassign_token(const std::string &token, const int64_t &index); void insert_token(const std::string &token, const int64_t &index); + void append_token(const std::string &token); std::string lookup_token(const int64_t &index); std::vector lookup_tokens(const std::vector &indices); std::vector @@ -44,7 +52,7 @@ struct Vocab : torch::CustomClassHolder { uint32_t _find(const c10::string_view &w) const { uint32_t stoi_size = stoi_.size(); uint32_t id = _hash(w) % stoi_size; - while (stoi_[id] != -1 && itos_[stoi_[id]]!= w) { + while (stoi_[id] != -1 && itos_[stoi_[id]] != w) { id = (id + 1) % stoi_size; } return id; @@ -57,16 +65,22 @@ struct Vocab : torch::CustomClassHolder { stoi_[h] = itos_.size() - 1; } } + + void _remove(const std::string &w) { + uint32_t h = _find(c10::string_view{w.data(), w.size()}); + if (stoi_[h] != -1) { + stoi_[h] = -1; + itos_.erase(std::find(itos_.begin(), itos_.end(), w)); + } + } }; VocabStates _serialize_vocab(const c10::intrusive_ptr &self); c10::intrusive_ptr _deserialize_vocab(VocabStates states); Vocab _load_vocab_from_file(const std::string &file_path, - const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus); Vocab _build_vocab_from_text_file(const std::string &file_path, - const std::string &unk_token, const int64_t min_freq, const int64_t num_cpus, torch::jit::script::Module tokenizer); diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index 26f393ce36..a1aa2290d9 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -1,6 +1,5 @@ import logging -from typing import Dict, List -import warnings +from typing import Dict, List, Optional from collections import Counter, OrderedDict import torch import torch.nn as nn @@ -30,7 +29,7 @@ def build_vocab_from_text_file(file_path, jited_tokenizer, min_freq=1, unk_token jited_tokenizer (ScriptModule): a tokenizer that has been JITed using `torch.jit.script` min_freq: The minimum frequency needed to include a token in the vocabulary. Values less than 1 will be set to 1. Default: 1. - unk_token: The default unknown token to use. Default: ''. + unk_token: The default unknown token to use. Default: ''. If not found in text file, it will be inserted to index 0. num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. Returns: @@ -44,7 +43,9 @@ def build_vocab_from_text_file(file_path, jited_tokenizer, min_freq=1, unk_token >>> jit_tokenizer = torch.jit.script(tokenizer) >>> v = build_vocab_from_text_file('vocab.txt', jit_tokenizer) """ - vocab_obj = _build_vocab_from_text_file(file_path, unk_token, min_freq, num_cpus, jited_tokenizer) + vocab_obj = _build_vocab_from_text_file(file_path, min_freq, num_cpus, jited_tokenizer) + if unk_token not in vocab_obj: + vocab_obj.insert_token(unk_token, 0) return Vocab(vocab_obj) @@ -62,7 +63,7 @@ def load_vocab_from_file(file_path, min_freq=1, unk_token='', num_cpus=4): file_object (FileObject): a file like object to read data from. min_freq: The minimum frequency needed to include a token in the vocabulary. Values less than 1 will be set to 1. Default: 1. - unk_token: The default unknown token to use. Default: ''. + unk_token: The default unknown token to use. Default: ''. If not found in vocab file, it will be inserted to index 0. num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. Returns: @@ -73,7 +74,9 @@ def load_vocab_from_file(file_path, min_freq=1, unk_token='', num_cpus=4): >>> v = load_vocab_from_file('vocab.txt') """ - vocab_obj = _load_vocab_from_file(file_path, unk_token, min_freq, num_cpus) + vocab_obj = _load_vocab_from_file(file_path, min_freq, num_cpus) + if unk_token not in vocab_obj: + vocab_obj.insert_token(unk_token, 0) return Vocab(vocab_obj) @@ -108,7 +111,7 @@ def vocab(ordered_dict, min_freq=1, unk_token=''): ordered_dict (collections.OrderedDict): object holding the frequencies of each token found in the data. min_freq: The minimum frequency needed to include a token in the vocabulary. Values less than 1 will be set to 1. Default: 1. - unk_token: The default unknown token to use. Default: ''. + unk_token: The default unknown token to use. Default: ''. If not found in ordered_dict, it will be inserted at index 0. Raises: ValueError: if a default `unk_token` isn't provided. @@ -134,9 +137,7 @@ def vocab(ordered_dict, min_freq=1, unk_token=''): if unk_token not in tokens: tokens.insert(0, unk_token) - warnings.warn("The `unk_token` '{}' wasn't found in the `ordered_dict`. Adding the `unk_token` " - "to the beginning of the Vocab.".format(unk_token), RuntimeWarning) - return Vocab(VocabPybind(tokens, unk_token)) + return Vocab(VocabPybind(tokens, None)) class Vocab(nn.Module): @@ -198,12 +199,38 @@ def __getitem__(self, token: str) -> int: return self.vocab[token] @torch.jit.export - def insert_token(self, token: str, index: int) -> None: + def set_default_index(self, index: int) -> None: + r""" + Args: + index: Value of default index. This index will be returned when OOV token is queried + """ + self.vocab.set_default_index(index) + + @torch.jit.export + def get_default_index(self) -> Optional[int]: + r""" + Returns: + index (optional[int]): Value of default index if it is set. + """ + return self.vocab.get_default_index() + + @torch.jit.export + def reassign_token(self, token: str, index: int) -> None: r""" Args: token (str): the token used to lookup the corresponding index. index (int): the index corresponding to the associated token. + Raises: + RuntimeError: If `index` is not range [0,Vocab.size()) or if token is not present in Vocab + """ + self.vocab.reassign_token(token, index) + @torch.jit.export + def insert_token(self, token: str, index: int) -> None: + r""" + Args: + token (str): the token used to lookup the corresponding index. + index (int): the index corresponding to the associated token. Raises: RuntimeError: if `index` not between [0, Vocab.size()] or if token already exists in the vocab. """ @@ -214,6 +241,9 @@ def append_token(self, token: str) -> None: r""" Args: token (str): the token used to lookup the corresponding index. + + Raises: + RuntimeError: if token already exists in the vocab """ self.vocab.append_token(token) @@ -275,5 +305,7 @@ def get_itos(self) -> List[str]: def __prepare_scriptable__(self): r"""Return a JITable Vocab. """ - cpp_vocab = torch.classes.torchtext.Vocab(self.vocab.itos_, self.vocab.unk_token_) - return Vocab(cpp_vocab) + if not self.is_jitable: + cpp_vocab = torch.classes.torchtext.Vocab(self.vocab.itos_, self.vocab.default_index_) + return Vocab(cpp_vocab) + return self From c8bced10ed2aec8ad4cd76d95c492345b0395b6c Mon Sep 17 00:00:00 2001 From: Parmeet Singh Bhatia Date: Wed, 19 May 2021 15:52:13 -0700 Subject: [PATCH 61/68] Swapping experimental Vocab and retiring current Vocab into legacy (#1289) Summary: allow-large-files to commit wikitext103_vocab.pt Reviewed By: cpuhrsch Differential Revision: D28478152 fbshipit-source-id: c2a871439f054024b95c05f7664a84028aacaca3 --- benchmark/benchmark_experimental_vocab.py | 2 +- docs/source/experimental_vocab.rst | 7 - docs/source/vocab.rst | 17 +- examples/BERT/mlm_task.py | 2 +- examples/BERT/qa_task.py | 2 +- examples/data_pipeline/pipelines.py | 4 +- examples/vocab/pytext_vocab.py | 3 +- examples/vocab/vocab.py | 2 +- test/asset/wikitext103_vocab.pt | Bin 7718255 -> 7718255 bytes test/data/test_builtin_datasets.py | 6 +- test/experimental/test_vocab.py | 265 ------------ test/legacy/test_vocab.py | 131 ++++++ test/test_build.py | 12 +- test/test_vocab.py | 358 +++++++++++----- .../datasets/language_modeling.py | 2 +- .../experimental/datasets/question_answer.py | 2 +- .../experimental/datasets/sequence_tagging.py | 2 +- .../datasets/text_classification.py | 2 +- .../experimental/datasets/translation.py | 4 +- torchtext/experimental/vocab.py | 176 +------- torchtext/legacy/__init__.py | 2 +- torchtext/legacy/data/field.py | 2 +- .../legacy/datasets/text_classification.py | 4 +- .../legacy/datasets/unsupervised_learning.py | 2 +- torchtext/legacy/vocab.py | 294 +++++++++++++ torchtext/vocab.py | 395 +++++++----------- 26 files changed, 842 insertions(+), 856 deletions(-) delete mode 100644 test/experimental/test_vocab.py create mode 100644 test/legacy/test_vocab.py create mode 100755 torchtext/legacy/vocab.py diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 1be3e190eb..92729ddf1a 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -12,7 +12,7 @@ load_vocab_from_file, build_vocab_from_text_file ) -from torchtext.vocab import ( +from torchtext.legacy.vocab import ( Vocab, build_vocab_from_iterator ) diff --git a/docs/source/experimental_vocab.rst b/docs/source/experimental_vocab.rst index 91ae03d40f..2803b0e1c2 100644 --- a/docs/source/experimental_vocab.rst +++ b/docs/source/experimental_vocab.rst @@ -7,13 +7,6 @@ torchtext.experimental.vocab .. automodule:: torchtext.experimental.vocab .. currentmodule:: torchtext.experimental.vocab -:hidden:`Vocab` -~~~~~~~~~~~~~~~ - -.. autoclass:: Vocab - :members: - :special-members: - :hidden:`vocab` ~~~~~~~~~~~~~~~ diff --git a/docs/source/vocab.rst b/docs/source/vocab.rst index a981725e02..3dd9882831 100644 --- a/docs/source/vocab.rst +++ b/docs/source/vocab.rst @@ -12,14 +12,8 @@ torchtext.vocab .. autoclass:: Vocab :members: - :special-members: __init__ - -:hidden:`SubwordVocab` -~~~~~~~~~~~~~~~~~~~~~~ + :special-members: -.. autoclass:: SubwordVocab - :members: - :special-members: __init__ :hidden:`Vectors` ~~~~~~~~~~~~~~~~~ @@ -48,12 +42,3 @@ Pretrained Word Embeddings .. autoclass:: CharNGram :members: - -Misc. ------ - -:hidden:`build_vocab_from_iterator` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: build_vocab_from_iterator - diff --git a/examples/BERT/mlm_task.py b/examples/BERT/mlm_task.py index 57962e23be..aaf61a8e87 100644 --- a/examples/BERT/mlm_task.py +++ b/examples/BERT/mlm_task.py @@ -125,7 +125,7 @@ def run_main(args, rank=None): except: train_dataset, valid_dataset, test_dataset = WLMDataset() old_vocab = train_dataset.vocab - vocab = torchtext.vocab.Vocab(counter=old_vocab.freqs, + vocab = torchtext.legacy.vocab.Vocab(counter=old_vocab.freqs, specials=['', '', '']) with open(args.save_vocab, 'wb') as f: torch.save(vocab, f) diff --git a/examples/BERT/qa_task.py b/examples/BERT/qa_task.py index b2239bc612..c11d4561c0 100644 --- a/examples/BERT/qa_task.py +++ b/examples/BERT/qa_task.py @@ -163,7 +163,7 @@ def train(): except: train_dataset, dev_dataset = SQuAD1() old_vocab = train_dataset.vocab - vocab = torchtext.vocab.Vocab(counter=old_vocab.freqs, + vocab = torchtext.legacy.vocab.Vocab(counter=old_vocab.freqs, specials=['', '', '']) with open(args.save_vocab, 'wb') as f: torch.save(vocab, f) diff --git a/examples/data_pipeline/pipelines.py b/examples/data_pipeline/pipelines.py index a0680f6f98..1b5e742163 100644 --- a/examples/data_pipeline/pipelines.py +++ b/examples/data_pipeline/pipelines.py @@ -45,7 +45,7 @@ def build_sp_pipeline(args): def build_legacy_torchtext_vocab_pipeline(args): vocab_file = args.vocab_filename tokenizer = get_tokenizer("basic_english") - from torchtext.vocab import build_vocab_from_iterator + from torchtext.legacy.vocab import build_vocab_from_iterator def token_iterator(vocab_file): f = open(vocab_file, 'r') @@ -72,7 +72,7 @@ def build_experimental_torchtext_pipeline(args): def build_legacy_batch_torchtext_vocab_pipeline(args): vocab_file = args.vocab_filename tokenizer = get_tokenizer("basic_english") - from torchtext.vocab import build_vocab_from_iterator + from torchtext.legacy.vocab import build_vocab_from_iterator def token_iterator(vocab_file): f = open(vocab_file, 'r') diff --git a/examples/vocab/pytext_vocab.py b/examples/vocab/pytext_vocab.py index d20d652b74..09af582133 100644 --- a/examples/vocab/pytext_vocab.py +++ b/examples/vocab/pytext_vocab.py @@ -2,7 +2,8 @@ from fairseq.data.dictionary import Dictionary import torch -from torchtext.experimental.vocab import vocab, Vocab +from torchtext.experimental.vocab import vocab +from torchtext.vocab import Vocab from typing import Dict, List, Optional diff --git a/examples/vocab/vocab.py b/examples/vocab/vocab.py index a14b6771e6..d76bfd94e4 100755 --- a/examples/vocab/vocab.py +++ b/examples/vocab/vocab.py @@ -4,7 +4,7 @@ import torch import io -from torchtext.vocab import build_vocab_from_iterator +from torchtext.legacy.vocab import build_vocab_from_iterator from torchtext.data.utils import ngrams_iterator from torchtext.data.utils import get_tokenizer from torchtext.utils import unicode_csv_reader diff --git a/test/asset/wikitext103_vocab.pt b/test/asset/wikitext103_vocab.pt index 8974e7fd302aa32f3253d05ef6da72a217f127ae..b9b2e4cefd38954bf4b61eb85415ce917b00c0b5 100644 GIT binary patch delta 446 zcmYk%%RZC=06_6^X-&RECOjtyENwm_%2XF(#%&4WHkyT^46!W%s>6ty;Hg z>05b$9>W9JWZB{@|BG|D`?uimxV?$^T4p7c{+bUBfWA*?n|f`c`TzcCQsz4Jd<%bew>i!GAUD% zlov8BFJ(q%<(0gaH}Y2A$$OcTd0CJ}Ny(C=Wmz)vK~`i{vhqO!O zDO!Tw*u`n40iEuFr;^Frw SX!+0lih{|!`tT?Uw*CQ#1f*pE delta 441 zcmX}nIaX5v06@_Iil89MAfp2~0~$n7L6nFXaEORLW`{(G5}88aQ)}@WE4se{JI}GB zvGe5b!DX-j8?mvtIVM$7EytxsPRL2A zl{%@H200~-(j?8&BCXOUr{#>Cm2=WA9dceS$VIs%m*t9Fl}_oBZn-AcB`!U3Lwe<= z^hv+mlG}1e24qm~%8=ZX`!XyEc_1V5P)6mEBxOv-<*_`Gr}9iv@?0k5g-pszc_jz$ zQ!*_xGAna3FAMTo-pE^dCuzyZds&nv$;t=$D9e(QPqHGbvL@@YA$i%9f^5n59>LFI z)vs?q^2K5h`)9YMu_l&?WeSVSxt(l$CtKLcZLB9phGOAl6vV@H6jX'], 0) - - def test_new_unk(self): - c = OrderedDict() - v = vocab(c, unk_token="") - self.assertEqual(v[''], 0) - - def test_vocab_membership(self): - token_to_freq = {'': 2, 'a': 2, 'b': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=2) - - self.assertTrue('' in v) - self.assertTrue('a' in v) - self.assertTrue('b' in v) - self.assertFalse('c' in v) - - def test_vocab_get_item(self): - token_to_freq = {'': 2, 'a': 2, 'b': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=2) - - self.assertEqual(v[''], 0) - self.assertEqual(v['a'], 1) - self.assertEqual(v['b'], 2) - - def test_reassign_token(self): - token_to_freq = {'': 1, 'a': 2, 'b': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=1) - - self.assertEqual(v[''], 2) - self.assertEqual(v['a'], 0) - self.assertEqual(v['b'], 1) - v.reassign_token('', 0) - self.assertEqual(v[''], 0) - self.assertEqual(v['a'], 1) - self.assertEqual(v['b'], 2) - - self.assertEqual(v.get_itos(), ['', 'a', 'b']) - - with self.assertRaises(RuntimeError): - v.reassign_token('not in vocab', 0) - - with self.assertRaises(RuntimeError): - v.reassign_token('', 3) - - def test_default_index(self): - token_to_freq = {'': 2, 'a': 2, 'b': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=2) - - self.assertTrue(v.get_default_index() is None) - with self.assertRaises(RuntimeError): - v['not in vocab'] - - v.set_default_index(0) - self.assertEqual(v['not in vocab'], 0) - - def test_default_index_jit(self): - token_to_freq = {'': 2, 'a': 2, 'b': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=2) - v.set_default_index(0) - v_jit = torch.jit.script(v) - self.assertEqual(v_jit['not in vocab'], 0) - - def test_vocab_insert_token(self): - c = OrderedDict({'': 2, 'a': 2}) - - # add item to end - v = vocab(c) - v.insert_token('b', 2) - - expected_itos = ['', 'a', 'b'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) - - # add item to middle - v = vocab(c) - v.insert_token('b', 0) - - expected_itos = ['b', '', 'a'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) - - def test_vocab_append_token(self): - c = OrderedDict({'a': 2}) - v = vocab(c) - v.append_token('b') - - expected_itos = ['', 'a', 'b'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) - - # token must not exist to be appended - with self.assertRaises(RuntimeError): - v.append_token('b') - - def test_vocab_len(self): - token_to_freq = {'a': 2, 'b': 2, 'c': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c) - - self.assertEqual(len(v), 4) - - def test_vocab_basic(self): - token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=3) - - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) - - def test_vocab_jit(self): - token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=3) - jit_v = torch.jit.script(v) - - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - assert not v.is_jitable - # Call the __prepare_scriptable__() func and convert the building block to the torbhind version - # Not expect users to use the torchbind version on eager mode but still need a CI test here. - assert v.__prepare_scriptable__().is_jitable - - self.assertEqual(jit_v.get_itos(), expected_itos) - self.assertEqual(dict(jit_v.get_stoi()), expected_stoi) - - def test_vocab_forward(self): - token_to_freq = {'a': 2, 'b': 2, 'c': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c) - jit_v = torch.jit.script(v) - - tokens = ['b', 'a', 'c'] - expected_indices = [2, 1, 3] - - self.assertEqual(v(tokens), expected_indices) - self.assertEqual(jit_v(tokens), expected_indices) - - def test_vocab_lookup_token(self): - token_to_freq = {'a': 2, 'b': 2, 'c': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c) - - self.assertEqual(v.lookup_token(1), 'a') - with self.assertRaises(RuntimeError): - v.lookup_token(100) - - def test_vocab_lookup_tokens(self): - token_to_freq = {'a': 2, 'b': 2, 'c': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c) - - indices = [2, 1, 3] - expected_tokens = ['b', 'a', 'c'] - - self.assertEqual(v.lookup_tokens(indices), expected_tokens) - - def test_vocab_lookup_indices(self): - token_to_freq = {'a': 2, 'b': 2, 'c': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c) - - tokens = ['b', 'a', 'c'] - expected_indices = [2, 1, 3] - - self.assertEqual(v.lookup_indices(tokens), expected_indices) - - def test_errors_vocab_python(self): - token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - - with self.assertRaises(ValueError): - # Test proper error raised when setting unk token to None - vocab(c, unk_token=None) - - def test_vocab_load_and_save(self): - token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=3) - v.set_default_index(0) - - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) - - with self.subTest('pybind'): - vocab_path = os.path.join(self.test_dir, 'vocab_pybind.pt') - torch.save(v, vocab_path) - loaded_v = torch.load(vocab_path) - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) - self.assertEqual(v['not in vocab'], 0) - - with self.subTest('torchscript'): - vocab_path = os.path.join(self.test_dir, 'vocab_torchscript.pt') - # Call the __prepare_scriptable__() func and convert the building block to the torbhind version - # Not expect users to use the torchbind version on eager mode but still need a CI test here. - torch.save(v.__prepare_scriptable__(), vocab_path) - loaded_v = torch.load(vocab_path) - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) - self.assertEqual(v['not in vocab'], 0) - - def test_build_vocab_iterator(self): - iterator = [['hello', 'hello', 'hello', 'freq_low', 'hello', 'world', 'world', 'world', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'freq_low', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T']] - v = build_vocab_from_iterator(iterator) - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] - expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/test/legacy/test_vocab.py b/test/legacy/test_vocab.py new file mode 100644 index 0000000000..00c2027d37 --- /dev/null +++ b/test/legacy/test_vocab.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +from collections import Counter +import os +import pickle + + +import numpy as np +import torch +from torchtext.legacy import vocab + +from ..common.torchtext_test_case import TorchtextTestCase + + +def conditional_remove(f): + if os.path.isfile(f): + os.remove(f) + + +class TestVocab(TorchtextTestCase): + + def test_vocab_basic(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + v = vocab.Vocab(c, min_freq=3, specials=['', '', '']) + + expected_itos = ['', '', '', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.itos, expected_itos) + self.assertEqual(dict(v.stoi), expected_stoi) + + def test_vocab_specials_first(self): + c = Counter("a a b b c c".split()) + + # add specials into vocabulary at first + v = vocab.Vocab(c, max_size=2, specials=['', '']) + expected_itos = ['', '', 'a', 'b'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.itos, expected_itos) + self.assertEqual(dict(v.stoi), expected_stoi) + + # add specials into vocabulary at last + v = vocab.Vocab(c, max_size=2, specials=['', ''], specials_first=False) + expected_itos = ['a', 'b', '', ''] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.itos, expected_itos) + self.assertEqual(dict(v.stoi), expected_stoi) + + def test_vocab_without_unk(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + oov_word = 'OOVWORD' + self.assertNotIn(oov_word, c) + + # tests for specials_first=True + v_first = vocab.Vocab(c, min_freq=3, specials=[''], specials_first=True) + expected_itos_first = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi_first = {x: index for index, x in enumerate(expected_itos_first)} + self.assertEqual(v_first.itos, expected_itos_first) + self.assertEqual(dict(v_first.stoi), expected_stoi_first) + self.assertNotIn(oov_word, v_first.itos) + self.assertNotIn(oov_word, v_first.stoi) + + # tests for specials_first=False + v_last = vocab.Vocab(c, min_freq=3, specials=[''], specials_first=False) + expected_itos_last = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] + expected_stoi_last = {x: index for index, x in enumerate(expected_itos_last)} + self.assertEqual(v_last.itos, expected_itos_last) + self.assertEqual(dict(v_last.stoi), expected_stoi_last) + self.assertNotIn(oov_word, v_last.itos) + self.assertNotIn(oov_word, v_last.stoi) + + # check if pad is mapped to the first index + self.assertEqual(v_first.stoi[''], 0) + # check if pad is mapped to the last index + self.assertEqual(v_last.stoi[''], max(v_last.stoi.values())) + + # check if an oovword is not in vocab and a default unk_id is not assigned to it + self.assertRaises(KeyError, v_first.stoi.__getitem__, oov_word) + self.assertRaises(KeyError, v_last.stoi.__getitem__, oov_word) + + def test_vocab_set_vectors(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, + 'test': 4, 'freq_too_low': 2}) + v = vocab.Vocab(c, min_freq=3, specials=['', '', '']) + stoi = {"hello": 0, "world": 1, "test": 2} + vectors = torch.FloatTensor([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]) + dim = 2 + v.set_vectors(stoi, vectors, dim) + expected_vectors = np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], + [0.0, 0.0], [0.1, 0.2], [0.5, 0.6], + [0.3, 0.4]]) + self.assertEqual(v.vectors, expected_vectors) + + def test_errors(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + with self.assertRaises(ValueError): + # Test proper error raised when using unknown string alias + vocab.Vocab(c, min_freq=3, specials=['', '', ''], + vectors=["fasttext.english.300d"]) + vocab.Vocab(c, min_freq=3, specials=['', '', ''], + vectors="fasttext.english.300d") + with self.assertRaises(ValueError): + # Test proper error is raised when vectors argument is + # non-string or non-Vectors + vocab.Vocab(c, min_freq=3, specials=['', '', ''], + vectors={"word": [1, 2, 3]}) + + def test_serialization(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + v = vocab.Vocab(c, min_freq=3, specials=['', '', '']) + pickle_path = os.path.join(self.test_dir, "vocab.pkl") + pickle.dump(v, open(pickle_path, "wb")) + v_loaded = pickle.load(open(pickle_path, "rb")) + assert v == v_loaded + + def test_serialization_backcompat(self): + # Test whether loading works on models saved in which + # the state was not required to have an "unk_index". + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + v = vocab.Vocab(c, min_freq=3, specials=['', '']) # no unk special + # Mock old vocabulary + del v.__dict__["unk_index"] + + pickle_path = os.path.join(self.test_dir, "vocab.pkl") + pickle.dump(v, open(pickle_path, "wb")) + v_loaded = pickle.load(open(pickle_path, "rb")) + assert v == v_loaded + + def test_has_unk(self): + c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) + v = vocab.Vocab(c) + self.assertEqual(v['not_in_it'], 0) diff --git a/test/test_build.py b/test/test_build.py index fe4cb51cb6..ad3781c6c4 100644 --- a/test/test_build.py +++ b/test/test_build.py @@ -150,7 +150,7 @@ def test_download_charngram_vectors(self): vectors = "charngram.100d" else: vectors = torchtext.vocab.CharNGram() - v = torchtext.vocab.Vocab( + v = torchtext.legacy.vocab.Vocab( c, min_freq=3, specials=['', '', ''], vectors=vectors) expected_itos = ['', '', '', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] @@ -177,7 +177,7 @@ def test_download_custom_vectors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) # Build a vocab and get vectors twice to test caching. for _ in range(2): - v = torchtext.vocab.Vocab( + v = torchtext.legacy.vocab.Vocab( c, min_freq=3, specials=['', '', ''], vectors=torchtext.vocab.Vectors( 'wiki.simple.vec', @@ -211,7 +211,7 @@ def test_download_fasttext_vectors(self): else: vectors = torchtext.vocab.FastText(language='simple') - v = torchtext.vocab.Vocab( + v = torchtext.legacy.vocab.Vocab( c, min_freq=3, specials=['', '', ''], vectors=vectors) expected_itos = ['', '', '', @@ -244,7 +244,7 @@ def test_download_glove_vectors(self): vectors = "glove.twitter.27B.25d" else: vectors = torchtext.vocab.GloVe(name='twitter.27B', dim='25') - v = torchtext.vocab.Vocab( + v = torchtext.legacy.vocab.Vocab( c, min_freq=3, specials=['', '', ''], vectors=vectors) expected_itos = ['', '', '', @@ -273,7 +273,7 @@ def test_extend(self): # Build a vocab and get vectors twice to test caching. for _ in range(2): f = torchtext.vocab.FastText(language='simple') - v = torchtext.vocab.Vocab( + v = torchtext.legacy.vocab.Vocab( c, min_freq=3, specials=['', '', ''], vectors=f) n_vocab = len(v) v.extend(f) # extend the vocab with the words contained in f.itos @@ -304,7 +304,7 @@ def test_vectors_custom_cache(self): if i == 1: self.assertTrue(os.path.exists(vector_cache)) - v = torchtext.vocab.Vocab( + v = torchtext.legacy.vocab.Vocab( c, min_freq=3, specials=['', '', ''], vectors=torchtext.vocab.Vectors( 'wiki.simple.vec', cache=vector_cache, diff --git a/test/test_vocab.py b/test/test_vocab.py index c9b863d37a..afb140c71e 100644 --- a/test/test_vocab.py +++ b/test/test_vocab.py @@ -1,131 +1,265 @@ # -*- coding: utf-8 -*- -from collections import Counter +from collections import OrderedDict import os -import pickle +import torch +from test.common.torchtext_test_case import TorchtextTestCase +from torchtext.experimental.vocab import ( + vocab, + build_vocab_from_iterator, +) -import numpy as np -import torch -from torchtext import vocab +class TestVocab(TorchtextTestCase): + def tearDown(self): + super().tearDown() + torch._C._jit_clear_class_registry() + torch.jit._recursive.concrete_type_store = torch.jit._recursive.ConcreteTypeStore() + + def test_has_unk(self): + c = OrderedDict() + v = vocab(c) + self.assertEqual(v[''], 0) -from .common.torchtext_test_case import TorchtextTestCase + def test_new_unk(self): + c = OrderedDict() + v = vocab(c, unk_token="") + self.assertEqual(v[''], 0) + def test_vocab_membership(self): + token_to_freq = {'': 2, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=2) -def conditional_remove(f): - if os.path.isfile(f): - os.remove(f) + self.assertTrue('' in v) + self.assertTrue('a' in v) + self.assertTrue('b' in v) + self.assertFalse('c' in v) + def test_vocab_get_item(self): + token_to_freq = {'': 2, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=2) -class TestVocab(TorchtextTestCase): + self.assertEqual(v[''], 0) + self.assertEqual(v['a'], 1) + self.assertEqual(v['b'], 2) - def test_vocab_basic(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - v = vocab.Vocab(c, min_freq=3, specials=['', '', '']) + def test_reassign_token(self): + token_to_freq = {'': 1, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=1) + + self.assertEqual(v[''], 2) + self.assertEqual(v['a'], 0) + self.assertEqual(v['b'], 1) + v.reassign_token('', 0) + self.assertEqual(v[''], 0) + self.assertEqual(v['a'], 1) + self.assertEqual(v['b'], 2) + + self.assertEqual(v.get_itos(), ['', 'a', 'b']) + + with self.assertRaises(RuntimeError): + v.reassign_token('not in vocab', 0) + + with self.assertRaises(RuntimeError): + v.reassign_token('', 3) + + def test_default_index(self): + token_to_freq = {'': 2, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=2) + + self.assertTrue(v.get_default_index() is None) + with self.assertRaises(RuntimeError): + v['not in vocab'] + + v.set_default_index(0) + self.assertEqual(v['not in vocab'], 0) + + def test_default_index_jit(self): + token_to_freq = {'': 2, 'a': 2, 'b': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=2) + v.set_default_index(0) + v_jit = torch.jit.script(v) + self.assertEqual(v_jit['not in vocab'], 0) - expected_itos = ['', '', '', - 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + def test_vocab_insert_token(self): + c = OrderedDict({'': 2, 'a': 2}) + + # add item to end + v = vocab(c) + v.insert_token('b', 2) + + expected_itos = ['', 'a', 'b'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.itos, expected_itos) - self.assertEqual(dict(v.stoi), expected_stoi) - def test_vocab_specials_first(self): - c = Counter("a a b b c c".split()) + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) - # add specials into vocabulary at first - v = vocab.Vocab(c, max_size=2, specials=['', '']) - expected_itos = ['', '', 'a', 'b'] + # add item to middle + v = vocab(c) + v.insert_token('b', 0) + + expected_itos = ['b', '', 'a'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.itos, expected_itos) - self.assertEqual(dict(v.stoi), expected_stoi) - # add specials into vocabulary at last - v = vocab.Vocab(c, max_size=2, specials=['', ''], specials_first=False) - expected_itos = ['a', 'b', '', ''] + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + def test_vocab_append_token(self): + c = OrderedDict({'a': 2}) + v = vocab(c) + v.append_token('b') + + expected_itos = ['', 'a', 'b'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.itos, expected_itos) - self.assertEqual(dict(v.stoi), expected_stoi) - - def test_vocab_without_unk(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - oov_word = 'OOVWORD' - self.assertNotIn(oov_word, c) - - # tests for specials_first=True - v_first = vocab.Vocab(c, min_freq=3, specials=[''], specials_first=True) - expected_itos_first = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] - expected_stoi_first = {x: index for index, x in enumerate(expected_itos_first)} - self.assertEqual(v_first.itos, expected_itos_first) - self.assertEqual(dict(v_first.stoi), expected_stoi_first) - self.assertNotIn(oov_word, v_first.itos) - self.assertNotIn(oov_word, v_first.stoi) - - # tests for specials_first=False - v_last = vocab.Vocab(c, min_freq=3, specials=[''], specials_first=False) - expected_itos_last = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', ''] - expected_stoi_last = {x: index for index, x in enumerate(expected_itos_last)} - self.assertEqual(v_last.itos, expected_itos_last) - self.assertEqual(dict(v_last.stoi), expected_stoi_last) - self.assertNotIn(oov_word, v_last.itos) - self.assertNotIn(oov_word, v_last.stoi) - - # check if pad is mapped to the first index - self.assertEqual(v_first.stoi[''], 0) - # check if pad is mapped to the last index - self.assertEqual(v_last.stoi[''], max(v_last.stoi.values())) - - # check if an oovword is not in vocab and a default unk_id is not assigned to it - self.assertRaises(KeyError, v_first.stoi.__getitem__, oov_word) - self.assertRaises(KeyError, v_last.stoi.__getitem__, oov_word) - - def test_vocab_set_vectors(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, - 'test': 4, 'freq_too_low': 2}) - v = vocab.Vocab(c, min_freq=3, specials=['', '', '']) - stoi = {"hello": 0, "world": 1, "test": 2} - vectors = torch.FloatTensor([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]) - dim = 2 - v.set_vectors(stoi, vectors, dim) - expected_vectors = np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], - [0.0, 0.0], [0.1, 0.2], [0.5, 0.6], - [0.3, 0.4]]) - self.assertEqual(v.vectors, expected_vectors) - - def test_errors(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - with self.assertRaises(ValueError): - # Test proper error raised when using unknown string alias - vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors=["fasttext.english.300d"]) - vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors="fasttext.english.300d") + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + # token must not exist to be appended + with self.assertRaises(RuntimeError): + v.append_token('b') + + def test_vocab_len(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c) + + self.assertEqual(len(v), 4) + + def test_vocab_basic(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=3) + + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + def test_vocab_jit(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=3) + jit_v = torch.jit.script(v) + + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + assert not v.is_jitable + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + assert v.__prepare_scriptable__().is_jitable + + self.assertEqual(jit_v.get_itos(), expected_itos) + self.assertEqual(dict(jit_v.get_stoi()), expected_stoi) + + def test_vocab_forward(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c) + jit_v = torch.jit.script(v) + + tokens = ['b', 'a', 'c'] + expected_indices = [2, 1, 3] + + self.assertEqual(v(tokens), expected_indices) + self.assertEqual(jit_v(tokens), expected_indices) + + def test_vocab_lookup_token(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c) + + self.assertEqual(v.lookup_token(1), 'a') + with self.assertRaises(RuntimeError): + v.lookup_token(100) + + def test_vocab_lookup_tokens(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c) + + indices = [2, 1, 3] + expected_tokens = ['b', 'a', 'c'] + + self.assertEqual(v.lookup_tokens(indices), expected_tokens) + + def test_vocab_lookup_indices(self): + token_to_freq = {'a': 2, 'b': 2, 'c': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c) + + tokens = ['b', 'a', 'c'] + expected_indices = [2, 1, 3] + + self.assertEqual(v.lookup_indices(tokens), expected_indices) + + def test_errors_vocab_python(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + c = OrderedDict(sorted_by_freq_tuples) + with self.assertRaises(ValueError): - # Test proper error is raised when vectors argument is - # non-string or non-Vectors - vocab.Vocab(c, min_freq=3, specials=['', '', ''], - vectors={"word": [1, 2, 3]}) - - def test_serialization(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - v = vocab.Vocab(c, min_freq=3, specials=['', '', '']) - pickle_path = os.path.join(self.test_dir, "vocab.pkl") - pickle.dump(v, open(pickle_path, "wb")) - v_loaded = pickle.load(open(pickle_path, "rb")) - assert v == v_loaded - - def test_serialization_backcompat(self): - # Test whether loading works on models saved in which - # the state was not required to have an "unk_index". - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - v = vocab.Vocab(c, min_freq=3, specials=['', '']) # no unk special - # Mock old vocabulary - del v.__dict__["unk_index"] - - pickle_path = os.path.join(self.test_dir, "vocab.pkl") - pickle.dump(v, open(pickle_path, "wb")) - v_loaded = pickle.load(open(pickle_path, "rb")) - assert v == v_loaded + # Test proper error raised when setting unk token to None + vocab(c, unk_token=None) - def test_has_unk(self): - c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) - v = vocab.Vocab(c) - self.assertEqual(v['not_in_it'], 0) + def test_vocab_load_and_save(self): + token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} + sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) + + c = OrderedDict(sorted_by_freq_tuples) + v = vocab(c, min_freq=3) + v.set_default_index(0) + + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + + with self.subTest('pybind'): + vocab_path = os.path.join(self.test_dir, 'vocab_pybind.pt') + torch.save(v, vocab_path) + loaded_v = torch.load(vocab_path) + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + self.assertEqual(v['not in vocab'], 0) + + with self.subTest('torchscript'): + vocab_path = os.path.join(self.test_dir, 'vocab_torchscript.pt') + # Call the __prepare_scriptable__() func and convert the building block to the torbhind version + # Not expect users to use the torchbind version on eager mode but still need a CI test here. + torch.save(v.__prepare_scriptable__(), vocab_path) + loaded_v = torch.load(vocab_path) + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(loaded_v.get_stoi()), expected_stoi) + self.assertEqual(v['not in vocab'], 0) + + def test_build_vocab_iterator(self): + iterator = [['hello', 'hello', 'hello', 'freq_low', 'hello', 'world', 'world', 'world', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', + 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'freq_low', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T']] + v = build_vocab_from_iterator(iterator) + expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index c9a3b05c2c..f94af3b03a 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -1,7 +1,7 @@ import torch import logging from torchtext.data.utils import get_tokenizer -from torchtext.vocab import build_vocab_from_iterator +from torchtext.legacy.vocab import build_vocab_from_iterator from torchtext import datasets as raw from torchtext.experimental.datasets import raw as experimental_raw from torchtext.data.datasets_utils import _check_default_set diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index e65d174327..6c6d7bb194 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -1,7 +1,7 @@ import torch import logging from torchtext.data.utils import get_tokenizer -from torchtext.vocab import build_vocab_from_iterator +from torchtext.legacy.vocab import build_vocab_from_iterator from torchtext import datasets as raw from torchtext.data.datasets_utils import _check_default_set from torchtext.data.datasets_utils import _wrap_datasets diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index edcf11048e..f33e8e265f 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -3,7 +3,7 @@ from torchtext.data.datasets_utils import _check_default_set from torchtext.data.datasets_utils import _wrap_datasets from torchtext import datasets as raw -from torchtext.vocab import build_vocab_from_iterator +from torchtext.legacy.vocab import build_vocab_from_iterator from torchtext.experimental.functional import ( vocab_func, totensor, diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index d3834868db..4a5b4d670c 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -1,7 +1,7 @@ import torch import logging from torchtext.data.utils import get_tokenizer -from torchtext.vocab import build_vocab_from_iterator +from torchtext.legacy.vocab import build_vocab_from_iterator from torchtext import datasets as raw from torchtext.data.datasets_utils import _check_default_set from torchtext.data.datasets_utils import _wrap_datasets diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index 1431e2f5d4..fc2bc48024 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -4,7 +4,7 @@ from torchtext.data.datasets_utils import _wrap_datasets from torchtext import datasets as raw from torchtext.experimental.datasets import raw as experimental_raw -from torchtext.vocab import Vocab, build_vocab_from_iterator +from torchtext.legacy.vocab import Vocab, build_vocab_from_iterator from torchtext.data.utils import get_tokenizer from ..functional import vocab_func, totensor, sequential_transforms @@ -107,7 +107,7 @@ def __init__(self, data, vocab, transforms): transforms: a tuple of source and target string transforms. Examples: - >>> from torchtext.vocab import build_vocab_from_iterator + >>> from torchtext.legacy.vocab import build_vocab_from_iterator >>> src_data = torch.Tensor([token_id_s1, token_id_s2, token_id_s3, token_id_s1]).long() >>> tgt_data = torch.Tensor([token_id_t1, token_id_t2, diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py index a1aa2290d9..c69d26db97 100644 --- a/torchtext/experimental/vocab.py +++ b/torchtext/experimental/vocab.py @@ -1,8 +1,6 @@ import logging -from typing import Dict, List, Optional from collections import Counter, OrderedDict -import torch -import torch.nn as nn +from torchtext.vocab import Vocab from torchtext._torchtext import ( Vocab as VocabPybind, _load_vocab_from_file, @@ -13,7 +11,6 @@ 'build_vocab_from_text_file', 'load_vocab_from_file', 'vocab', - 'Vocab', ] logger = logging.getLogger(__name__) @@ -138,174 +135,3 @@ def vocab(ordered_dict, min_freq=1, unk_token=''): if unk_token not in tokens: tokens.insert(0, unk_token) return Vocab(VocabPybind(tokens, None)) - - -class Vocab(nn.Module): - __jit_unused_properties__ = ["is_jitable"] - r"""Creates a vocab object which maps tokens to indices. - - Args: - vocab (torch.classes.torchtext.Vocab or torchtext._torchtext.Vocab): a cpp vocab object. - """ - - def __init__(self, vocab): - super(Vocab, self).__init__() - self.vocab = vocab - - @property - def is_jitable(self): - return not isinstance(self.vocab, VocabPybind) - - @torch.jit.export - def forward(self, tokens: List[str]) -> List[int]: - r"""Calls the `lookup_indices` method - - Args: - tokens (List[str]): a list of tokens used to lookup their corresponding `indices`. - - Returns: - indices (List[int]): the 'indices` associated with a list of tokens`. - """ - return self.vocab.lookup_indices(tokens) - - @torch.jit.export - def __len__(self) -> int: - r""" - Returns: - length (int): the length of the vocab - """ - return len(self.vocab) - - @torch.jit.export - def __contains__(self, token: str) -> bool: - r""" - Args: - token (str): the token for which to check the membership - - Returns: - membership (bool): whether the token is member of vocab or not - """ - return self.vocab.__contains__(token) - - @torch.jit.export - def __getitem__(self, token: str) -> int: - r""" - Args: - token (str): the token used to lookup the corresponding index. - - Returns: - index (int): the index corresponding to the associated token. - """ - return self.vocab[token] - - @torch.jit.export - def set_default_index(self, index: int) -> None: - r""" - Args: - index: Value of default index. This index will be returned when OOV token is queried - """ - self.vocab.set_default_index(index) - - @torch.jit.export - def get_default_index(self) -> Optional[int]: - r""" - Returns: - index (optional[int]): Value of default index if it is set. - """ - return self.vocab.get_default_index() - - @torch.jit.export - def reassign_token(self, token: str, index: int) -> None: - r""" - Args: - token (str): the token used to lookup the corresponding index. - index (int): the index corresponding to the associated token. - Raises: - RuntimeError: If `index` is not range [0,Vocab.size()) or if token is not present in Vocab - """ - self.vocab.reassign_token(token, index) - - @torch.jit.export - def insert_token(self, token: str, index: int) -> None: - r""" - Args: - token (str): the token used to lookup the corresponding index. - index (int): the index corresponding to the associated token. - Raises: - RuntimeError: if `index` not between [0, Vocab.size()] or if token already exists in the vocab. - """ - self.vocab.insert_token(token, index) - - @torch.jit.export - def append_token(self, token: str) -> None: - r""" - Args: - token (str): the token used to lookup the corresponding index. - - Raises: - RuntimeError: if token already exists in the vocab - """ - self.vocab.append_token(token) - - @torch.jit.export - def lookup_token(self, index: int) -> str: - r""" - Args: - index (int): the index corresponding to the associated token. - - Returns: - token (str): the token used to lookup the corresponding index. - - Raises: - RuntimeError: if `index` not between [0, itos.size()]. - """ - return self.vocab.lookup_token(index) - - @torch.jit.export - def lookup_tokens(self, indices: List[int]) -> List[str]: - r""" - Args: - indices (List[int]): the `indices` used to lookup their corresponding`tokens`. - - Returns: - tokens (List[str]): the `tokens` associated with `indices`. - - Raises: - RuntimeError: if an index within `indices` is not between [0, itos.size()]. - """ - return self.vocab.lookup_tokens(indices) - - @torch.jit.export - def lookup_indices(self, tokens: List[str]) -> List[int]: - r""" - Args: - tokens (List[str]): the tokens used to lookup their corresponding `indices`. - - Returns: - indices (List[int]): the 'indices` associated with `tokens`. - """ - return self.vocab.lookup_indices(tokens) - - @torch.jit.export - def get_stoi(self) -> Dict[str, int]: - r""" - Returns: - stoi (dict): dictionary mapping tokens to indices. - """ - return self.vocab.get_stoi() - - @torch.jit.export - def get_itos(self) -> List[str]: - r""" - Returns: - itos (dict): dictionary mapping indices to tokens. - """ - return self.vocab.get_itos() - - def __prepare_scriptable__(self): - r"""Return a JITable Vocab. - """ - if not self.is_jitable: - cpp_vocab = torch.classes.torchtext.Vocab(self.vocab.itos_, self.vocab.default_index_) - return Vocab(cpp_vocab) - return self diff --git a/torchtext/legacy/__init__.py b/torchtext/legacy/__init__.py index f9eeec6e10..5ff23f46d3 100644 --- a/torchtext/legacy/__init__.py +++ b/torchtext/legacy/__init__.py @@ -2,7 +2,7 @@ from .. import nn # Not in the legacy folder from . import datasets from .. import utils # Not in the legacy folder -from .. import vocab # Not in the legacy folder +from . import vocab __all__ = ['data', 'nn', diff --git a/torchtext/legacy/data/field.py b/torchtext/legacy/data/field.py index 39da51da72..efbf888666 100644 --- a/torchtext/legacy/data/field.py +++ b/torchtext/legacy/data/field.py @@ -6,7 +6,7 @@ from .dataset import Dataset from .pipeline import Pipeline from torchtext.data.utils import get_tokenizer, dtype_to_attr, is_tokenizer_serializable -from torchtext.vocab import Vocab, SubwordVocab +from torchtext.legacy.vocab import Vocab, SubwordVocab class RawField(object): diff --git a/torchtext/legacy/datasets/text_classification.py b/torchtext/legacy/datasets/text_classification.py index f50c3b9d8b..6c5f47b4ee 100644 --- a/torchtext/legacy/datasets/text_classification.py +++ b/torchtext/legacy/datasets/text_classification.py @@ -4,8 +4,8 @@ from torchtext.utils import download_from_url, extract_archive, unicode_csv_reader from torchtext.data.utils import ngrams_iterator from torchtext.data.utils import get_tokenizer -from torchtext.vocab import build_vocab_from_iterator -from torchtext.vocab import Vocab +from torchtext.legacy.vocab import build_vocab_from_iterator +from torchtext.legacy.vocab import Vocab from tqdm import tqdm URLS = { diff --git a/torchtext/legacy/datasets/unsupervised_learning.py b/torchtext/legacy/datasets/unsupervised_learning.py index 1babf1bfca..8235b40c87 100644 --- a/torchtext/legacy/datasets/unsupervised_learning.py +++ b/torchtext/legacy/datasets/unsupervised_learning.py @@ -1,7 +1,7 @@ from torchtext.data.functional import custom_replace import torch from torchtext.utils import download_from_url, extract_archive -from torchtext.vocab import build_vocab_from_iterator +from torchtext.legacy.vocab import build_vocab_from_iterator from torchtext.data.functional import simple_space_split import os diff --git a/torchtext/legacy/vocab.py b/torchtext/legacy/vocab.py new file mode 100755 index 0000000000..a28ec440ae --- /dev/null +++ b/torchtext/legacy/vocab.py @@ -0,0 +1,294 @@ +from collections import defaultdict +import logging +import torch +from tqdm import tqdm +from collections import Counter +from torchtext.vocab import ( + pretrained_aliases, # not in legacy + Vectors, # not in legacy +) + +logger = logging.getLogger(__name__) + + +class Vocab(object): + """Defines a vocabulary object that will be used to numericalize a field. + + Attributes: + freqs: A collections.Counter object holding the frequencies of tokens + in the data used to build the Vocab. + stoi: A collections.defaultdict instance mapping token strings to + numerical identifiers. + itos: A list of token strings indexed by their numerical identifiers. + """ + + # TODO (@mttk): Populate classs with default values of special symbols + UNK = '' + + def __init__(self, counter, max_size=None, min_freq=1, specials=('', ''), + vectors=None, unk_init=None, vectors_cache=None, specials_first=True): + """Create a Vocab object from a collections.Counter. + + Args: + counter: collections.Counter object holding the frequencies of + each value found in the data. + max_size: The maximum size of the vocabulary, or None for no + maximum. Default: None. + min_freq: The minimum frequency needed to include a token in the + vocabulary. Values less than 1 will be set to 1. Default: 1. + specials: The list of special tokens (e.g., padding or eos) that + will be prepended to the vocabulary. Default: [', ''] + vectors: One of either the available pretrained vectors + or custom pretrained vectors (see Vocab.load_vectors); + or a list of aforementioned vectors + unk_init (callback): by default, initialize out-of-vocabulary word vectors + to zero vectors; can be any function that takes in a Tensor and + returns a Tensor of the same size. Default: 'torch.zeros' + vectors_cache: directory for cached vectors. Default: '.vector_cache' + specials_first: Whether to add special tokens into the vocabulary at first. + If it is False, they are added into the vocabulary at last. + Default: True. + """ + self.freqs = counter + counter = counter.copy() + min_freq = max(min_freq, 1) + + self.itos = list() + self.unk_index = None + if specials_first: + self.itos = list(specials) + # only extend max size if specials are prepended + max_size = None if max_size is None else max_size + len(specials) + + # frequencies of special tokens are not counted when building vocabulary + # in frequency order + for tok in specials: + del counter[tok] + + # sort by frequency, then alphabetically + words_and_frequencies = sorted(counter.items(), key=lambda tup: tup[0]) + words_and_frequencies.sort(key=lambda tup: tup[1], reverse=True) + + for word, freq in words_and_frequencies: + if freq < min_freq or len(self.itos) == max_size: + break + self.itos.append(word) + + if Vocab.UNK in specials: # hard-coded for now + unk_index = specials.index(Vocab.UNK) # position in list + # account for ordering of specials, set variable + self.unk_index = unk_index if specials_first else len(self.itos) + unk_index + self.stoi = defaultdict(self._default_unk_index) + else: + self.stoi = defaultdict() + + if not specials_first: + self.itos.extend(list(specials)) + + # stoi is simply a reverse dict for itos + self.stoi.update({tok: i for i, tok in enumerate(self.itos)}) + + self.vectors = None + if vectors is not None: + self.load_vectors(vectors, unk_init=unk_init, cache=vectors_cache) + else: + assert unk_init is None and vectors_cache is None + + def _default_unk_index(self): + return self.unk_index + + def __getitem__(self, token): + return self.stoi.get(token, self.stoi.get(Vocab.UNK)) + + def __getstate__(self): + # avoid picking defaultdict + attrs = dict(self.__dict__) + # cast to regular dict + attrs['stoi'] = dict(self.stoi) + return attrs + + def __setstate__(self, state): + if state.get("unk_index", None) is None: + stoi = defaultdict() + else: + stoi = defaultdict(self._default_unk_index) + stoi.update(state['stoi']) + state['stoi'] = stoi + self.__dict__.update(state) + + def __eq__(self, other): + if self.freqs != other.freqs: + return False + if self.stoi != other.stoi: + return False + if self.itos != other.itos: + return False + if self.vectors != other.vectors: + return False + return True + + def __len__(self): + return len(self.itos) + + def lookup_indices(self, tokens): + indices = [self.__getitem__(token) for token in tokens] + return indices + + def extend(self, v, sort=False): + words = sorted(v.itos) if sort else v.itos + for w in words: + if w not in self.stoi: + self.itos.append(w) + self.stoi[w] = len(self.itos) - 1 + + def load_vectors(self, vectors, **kwargs): + """ + Args: + vectors: one of or a list containing instantiations of the + GloVe, CharNGram, or Vectors classes. Alternatively, one + of or a list of available pretrained vectors: + + charngram.100d + fasttext.en.300d + fasttext.simple.300d + glove.42B.300d + glove.840B.300d + glove.twitter.27B.25d + glove.twitter.27B.50d + glove.twitter.27B.100d + glove.twitter.27B.200d + glove.6B.50d + glove.6B.100d + glove.6B.200d + glove.6B.300d + + Remaining keyword arguments: Passed to the constructor of Vectors classes. + """ + if not isinstance(vectors, list): + vectors = [vectors] + for idx, vector in enumerate(vectors): + if isinstance(vector, str): + # Convert the string pretrained vector identifier + # to a Vectors object + if vector not in pretrained_aliases: + raise ValueError( + "Got string input vector {}, but allowed pretrained " + "vectors are {}".format( + vector, list(pretrained_aliases.keys()))) + vectors[idx] = pretrained_aliases[vector](**kwargs) + elif not isinstance(vector, Vectors): + raise ValueError( + "Got input vectors of type {}, expected str or " + "Vectors object".format(type(vector))) + + tot_dim = sum(v.dim for v in vectors) + self.vectors = torch.Tensor(len(self), tot_dim) + for i, token in enumerate(self.itos): + start_dim = 0 + for v in vectors: + end_dim = start_dim + v.dim + self.vectors[i][start_dim:end_dim] = v[token.strip()] + start_dim = end_dim + assert(start_dim == tot_dim) + + def set_vectors(self, stoi, vectors, dim, unk_init=torch.Tensor.zero_): + """ + Set the vectors for the Vocab instance from a collection of Tensors. + + Args: + stoi: A dictionary of string to the index of the associated vector + in the `vectors` input argument. + vectors: An indexed iterable (or other structure supporting __getitem__) that + given an input index, returns a FloatTensor representing the vector + for the token associated with the index. For example, + vector[stoi["string"]] should return the vector for "string". + dim: The dimensionality of the vectors. + unk_init (callback): by default, initialize out-of-vocabulary word vectors + to zero vectors; can be any function that takes in a Tensor and + returns a Tensor of the same size. Default: 'torch.zeros' + """ + self.vectors = torch.Tensor(len(self), dim) + for i, token in enumerate(self.itos): + wv_index = stoi.get(token, None) + if wv_index is not None: + self.vectors[i] = vectors[wv_index] + else: + self.vectors[i] = unk_init(self.vectors[i]) + + +class SubwordVocab(Vocab): + + def __init__(self, counter, max_size=None, specials=(''), + vectors=None, unk_init=torch.Tensor.zero_): + """Create a revtok subword vocabulary from a collections.Counter. + + Args: + counter: collections.Counter object holding the frequencies of + each word found in the data. + max_size: The maximum size of the subword vocabulary, or None for no + maximum. Default: None. + specials: The list of special tokens (e.g., padding or eos) that + will be prepended to the vocabulary in addition to an + token. + vectors: One of either the available pretrained vectors + or custom pretrained vectors (see Vocab.load_vectors); + or a list of aforementioned vectors + unk_init (callback): by default, initialize out-of-vocabulary word vectors + to zero vectors; can be any function that takes in a Tensor and + returns a Tensor of the same size. Default: 'torch.zeros + """ + try: + import revtok + except ImportError: + print("Please install revtok.") + raise + + # Hardcode unk_index as subword_vocab has no specials_first argument + self.unk_index = (specials.index(SubwordVocab.UNK) + if SubwordVocab.UNK in specials else None) + + if self.unk_index is None: + self.stoi = defaultdict() + else: + self.stoi = defaultdict(self._default_unk_index) + + self.stoi.update({tok: i for i, tok in enumerate(specials)}) + self.itos = specials.copy() + + self.segment = revtok.SubwordSegmenter(counter, max_size) + + max_size = None if max_size is None else max_size + len(self.itos) + + # sort by frequency/entropy, then alphabetically + toks = sorted(self.segment.vocab.items(), + key=lambda tup: (len(tup[0]) != 1, -tup[1], tup[0])) + + for tok, _ in toks: + if len(self.itos) == max_size: + break + self.itos.append(tok) + self.stoi[tok] = len(self.itos) - 1 + + if vectors is not None: + self.load_vectors(vectors, unk_init=unk_init) + + +def build_vocab_from_iterator(iterator, num_lines=None): + """ + Build a Vocab from an iterator. + + Args: + iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. + num_lines: The expected number of elements returned by the iterator. + (Default: None) + Optionally, if known, the expected number of elements can be passed to + this factory function for improved progress reporting. + """ + + counter = Counter() + with tqdm(unit_scale=0, unit='lines', total=num_lines) as t: + for tokens in iterator: + counter.update(tokens) + t.update(1) + word_vocab = Vocab(counter) + return word_vocab diff --git a/torchtext/vocab.py b/torchtext/vocab.py index 516f158a16..07378c46a4 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -1,282 +1,190 @@ -from collections import defaultdict from functools import partial import logging import os import zipfile import gzip - -from urllib.request import urlretrieve import torch +import torch.nn as nn +from urllib.request import urlretrieve from tqdm import tqdm import tarfile +from typing import Optional, List, Dict +from torchtext._torchtext import Vocab as VocabPybind from .utils import reporthook -from collections import Counter - logger = logging.getLogger(__name__) -class Vocab(object): - """Defines a vocabulary object that will be used to numericalize a field. +class Vocab(nn.Module): + __jit_unused_properties__ = ["is_jitable"] + r"""Creates a vocab object which maps tokens to indices. - Attributes: - freqs: A collections.Counter object holding the frequencies of tokens - in the data used to build the Vocab. - stoi: A collections.defaultdict instance mapping token strings to - numerical identifiers. - itos: A list of token strings indexed by their numerical identifiers. + Args: + vocab (torch.classes.torchtext.Vocab or torchtext._torchtext.Vocab): a cpp vocab object. """ - # TODO (@mttk): Populate classs with default values of special symbols - UNK = '' + def __init__(self, vocab): + super(Vocab, self).__init__() + self.vocab = vocab - def __init__(self, counter, max_size=None, min_freq=1, specials=('', ''), - vectors=None, unk_init=None, vectors_cache=None, specials_first=True): - """Create a Vocab object from a collections.Counter. + @property + def is_jitable(self): + return not isinstance(self.vocab, VocabPybind) - Args: - counter: collections.Counter object holding the frequencies of - each value found in the data. - max_size: The maximum size of the vocabulary, or None for no - maximum. Default: None. - min_freq: The minimum frequency needed to include a token in the - vocabulary. Values less than 1 will be set to 1. Default: 1. - specials: The list of special tokens (e.g., padding or eos) that - will be prepended to the vocabulary. Default: [', ''] - vectors: One of either the available pretrained vectors - or custom pretrained vectors (see Vocab.load_vectors); - or a list of aforementioned vectors - unk_init (callback): by default, initialize out-of-vocabulary word vectors - to zero vectors; can be any function that takes in a Tensor and - returns a Tensor of the same size. Default: 'torch.zeros' - vectors_cache: directory for cached vectors. Default: '.vector_cache' - specials_first: Whether to add special tokens into the vocabulary at first. - If it is False, they are added into the vocabulary at last. - Default: True. - """ - self.freqs = counter - counter = counter.copy() - min_freq = max(min_freq, 1) - - self.itos = list() - self.unk_index = None - if specials_first: - self.itos = list(specials) - # only extend max size if specials are prepended - max_size = None if max_size is None else max_size + len(specials) - - # frequencies of special tokens are not counted when building vocabulary - # in frequency order - for tok in specials: - del counter[tok] - - # sort by frequency, then alphabetically - words_and_frequencies = sorted(counter.items(), key=lambda tup: tup[0]) - words_and_frequencies.sort(key=lambda tup: tup[1], reverse=True) - - for word, freq in words_and_frequencies: - if freq < min_freq or len(self.itos) == max_size: - break - self.itos.append(word) - - if Vocab.UNK in specials: # hard-coded for now - unk_index = specials.index(Vocab.UNK) # position in list - # account for ordering of specials, set variable - self.unk_index = unk_index if specials_first else len(self.itos) + unk_index - self.stoi = defaultdict(self._default_unk_index) - else: - self.stoi = defaultdict() + @torch.jit.export + def forward(self, tokens: List[str]) -> List[int]: + r"""Calls the `lookup_indices` method - if not specials_first: - self.itos.extend(list(specials)) + Args: + tokens: a list of tokens used to lookup their corresponding `indices`. - # stoi is simply a reverse dict for itos - self.stoi.update({tok: i for i, tok in enumerate(self.itos)}) + Returns: + The indices associated with a list of `tokens`. + """ + return self.vocab.lookup_indices(tokens) - self.vectors = None - if vectors is not None: - self.load_vectors(vectors, unk_init=unk_init, cache=vectors_cache) - else: - assert unk_init is None and vectors_cache is None + @torch.jit.export + def __len__(self) -> int: + r""" + Returns: + The length of the vocab. + """ + return len(self.vocab) - def _default_unk_index(self): - return self.unk_index + @torch.jit.export + def __contains__(self, token: str) -> bool: + r""" + Args: + token: The token for which to check the membership. - def __getitem__(self, token): - return self.stoi.get(token, self.stoi.get(Vocab.UNK)) - - def __getstate__(self): - # avoid picking defaultdict - attrs = dict(self.__dict__) - # cast to regular dict - attrs['stoi'] = dict(self.stoi) - return attrs - - def __setstate__(self, state): - if state.get("unk_index", None) is None: - stoi = defaultdict() - else: - stoi = defaultdict(self._default_unk_index) - stoi.update(state['stoi']) - state['stoi'] = stoi - self.__dict__.update(state) - - def __eq__(self, other): - if self.freqs != other.freqs: - return False - if self.stoi != other.stoi: - return False - if self.itos != other.itos: - return False - if self.vectors != other.vectors: - return False - return True + Returns: + Whether the token is member of vocab or not. + """ + return self.vocab.__contains__(token) - def __len__(self): - return len(self.itos) + @torch.jit.export + def __getitem__(self, token: str) -> int: + r""" + Args: + token: The token used to lookup the corresponding index. - def lookup_indices(self, tokens): - indices = [self.__getitem__(token) for token in tokens] - return indices + Returns: + The index corresponding to the associated token. + """ + return self.vocab[token] - def extend(self, v, sort=False): - words = sorted(v.itos) if sort else v.itos - for w in words: - if w not in self.stoi: - self.itos.append(w) - self.stoi[w] = len(self.itos) - 1 + @torch.jit.export + def set_default_index(self, index: int) -> None: + r""" + Args: + index: Value of default index. This index will be returned when OOV token is queried. + """ + self.vocab.set_default_index(index) - def load_vectors(self, vectors, **kwargs): + @torch.jit.export + def get_default_index(self) -> Optional[int]: + r""" + Returns: + Value of default index if it is set. """ + return self.vocab.get_default_index() + + @torch.jit.export + def reassign_token(self, token: str, index: int) -> None: + r""" Args: - vectors: one of or a list containing instantiations of the - GloVe, CharNGram, or Vectors classes. Alternatively, one - of or a list of available pretrained vectors: - - charngram.100d - fasttext.en.300d - fasttext.simple.300d - glove.42B.300d - glove.840B.300d - glove.twitter.27B.25d - glove.twitter.27B.50d - glove.twitter.27B.100d - glove.twitter.27B.200d - glove.6B.50d - glove.6B.100d - glove.6B.200d - glove.6B.300d - - Remaining keyword arguments: Passed to the constructor of Vectors classes. + token: the token used to lookup the corresponding index. + index: the index corresponding to the associated token. + Raises: + RuntimeError: If `index` is not in range [0,Vocab.size()) or if `token` is not present in Vocab """ - if not isinstance(vectors, list): - vectors = [vectors] - for idx, vector in enumerate(vectors): - if isinstance(vector, str): - # Convert the string pretrained vector identifier - # to a Vectors object - if vector not in pretrained_aliases: - raise ValueError( - "Got string input vector {}, but allowed pretrained " - "vectors are {}".format( - vector, list(pretrained_aliases.keys()))) - vectors[idx] = pretrained_aliases[vector](**kwargs) - elif not isinstance(vector, Vectors): - raise ValueError( - "Got input vectors of type {}, expected str or " - "Vectors object".format(type(vector))) - - tot_dim = sum(v.dim for v in vectors) - self.vectors = torch.Tensor(len(self), tot_dim) - for i, token in enumerate(self.itos): - start_dim = 0 - for v in vectors: - end_dim = start_dim + v.dim - self.vectors[i][start_dim:end_dim] = v[token.strip()] - start_dim = end_dim - assert(start_dim == tot_dim) - - def set_vectors(self, stoi, vectors, dim, unk_init=torch.Tensor.zero_): + self.vocab.reassign_token(token, index) + + @torch.jit.export + def insert_token(self, token: str, index: int) -> None: + r""" + Args: + token: The token used to lookup the corresponding index. + index: The index corresponding to the associated token. + Raises: + RuntimeError: If `index` is not in range [0, Vocab.size()] or if `token` already exists in the vocab. """ - Set the vectors for the Vocab instance from a collection of Tensors. + self.vocab.insert_token(token, index) + @torch.jit.export + def append_token(self, token: str) -> None: + r""" Args: - stoi: A dictionary of string to the index of the associated vector - in the `vectors` input argument. - vectors: An indexed iterable (or other structure supporting __getitem__) that - given an input index, returns a FloatTensor representing the vector - for the token associated with the index. For example, - vector[stoi["string"]] should return the vector for "string". - dim: The dimensionality of the vectors. - unk_init (callback): by default, initialize out-of-vocabulary word vectors - to zero vectors; can be any function that takes in a Tensor and - returns a Tensor of the same size. Default: 'torch.zeros' + token: The token used to lookup the corresponding index. + + Raises: + RuntimeError: If `token` already exists in the vocab """ - self.vectors = torch.Tensor(len(self), dim) - for i, token in enumerate(self.itos): - wv_index = stoi.get(token, None) - if wv_index is not None: - self.vectors[i] = vectors[wv_index] - else: - self.vectors[i] = unk_init(self.vectors[i]) + self.vocab.append_token(token) + @torch.jit.export + def lookup_token(self, index: int) -> str: + r""" + Args: + index: The index corresponding to the associated token. -class SubwordVocab(Vocab): + Returns: + token: The token used to lookup the corresponding index. - def __init__(self, counter, max_size=None, specials=(''), - vectors=None, unk_init=torch.Tensor.zero_): - """Create a revtok subword vocabulary from a collections.Counter. + Raises: + RuntimeError: If `index` not in range [0, itos.size()). + """ + return self.vocab.lookup_token(index) + @torch.jit.export + def lookup_tokens(self, indices: List[int]) -> List[str]: + r""" Args: - counter: collections.Counter object holding the frequencies of - each word found in the data. - max_size: The maximum size of the subword vocabulary, or None for no - maximum. Default: None. - specials: The list of special tokens (e.g., padding or eos) that - will be prepended to the vocabulary in addition to an - token. - vectors: One of either the available pretrained vectors - or custom pretrained vectors (see Vocab.load_vectors); - or a list of aforementioned vectors - unk_init (callback): by default, initialize out-of-vocabulary word vectors - to zero vectors; can be any function that takes in a Tensor and - returns a Tensor of the same size. Default: 'torch.zeros - """ - try: - import revtok - except ImportError: - print("Please install revtok.") - raise - - # Hardcode unk_index as subword_vocab has no specials_first argument - self.unk_index = (specials.index(SubwordVocab.UNK) - if SubwordVocab.UNK in specials else None) - - if self.unk_index is None: - self.stoi = defaultdict() - else: - self.stoi = defaultdict(self._default_unk_index) + indices: The `indices` used to lookup their corresponding`tokens`. + + Returns: + The `tokens` associated with `indices`. - self.stoi.update({tok: i for i, tok in enumerate(specials)}) - self.itos = specials.copy() + Raises: + RuntimeError: If an index within `indices` is not int range [0, itos.size()). + """ + return self.vocab.lookup_tokens(indices) - self.segment = revtok.SubwordSegmenter(counter, max_size) + @torch.jit.export + def lookup_indices(self, tokens: List[str]) -> List[int]: + r""" + Args: + tokens: the tokens used to lookup their corresponding `indices`. - max_size = None if max_size is None else max_size + len(self.itos) + Returns: + The 'indices` associated with `tokens`. + """ + return self.vocab.lookup_indices(tokens) - # sort by frequency/entropy, then alphabetically - toks = sorted(self.segment.vocab.items(), - key=lambda tup: (len(tup[0]) != 1, -tup[1], tup[0])) + @torch.jit.export + def get_stoi(self) -> Dict[str, int]: + r""" + Returns: + Dictionary mapping tokens to indices. + """ + return self.vocab.get_stoi() - for tok, _ in toks: - if len(self.itos) == max_size: - break - self.itos.append(tok) - self.stoi[tok] = len(self.itos) - 1 + @torch.jit.export + def get_itos(self) -> List[str]: + r""" + Returns: + List mapping indices to tokens. + """ + return self.vocab.get_itos() - if vectors is not None: - self.load_vectors(vectors, unk_init=unk_init) + def __prepare_scriptable__(self): + r"""Return a JITable Vocab. + """ + if not self.is_jitable: + cpp_vocab = torch.classes.torchtext.Vocab(self.vocab.itos_, self.vocab.default_index_) + return Vocab(cpp_vocab) + return self def _infer_shape(f): @@ -543,24 +451,3 @@ def __getitem__(self, token): "glove.6B.300d": partial(GloVe, name="6B", dim="300") } """Mapping from string name to factory function""" - - -def build_vocab_from_iterator(iterator, num_lines=None): - """ - Build a Vocab from an iterator. - - Args: - iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. - num_lines: The expected number of elements returned by the iterator. - (Default: None) - Optionally, if known, the expected number of elements can be passed to - this factory function for improved progress reporting. - """ - - counter = Counter() - with tqdm(unit_scale=0, unit='lines', total=num_lines) as t: - for tokens in iterator: - counter.update(tokens) - t.update(1) - word_vocab = Vocab(counter) - return word_vocab From 3142f4e303add403f30c0c41cdb62be2d4fdf6a5 Mon Sep 17 00:00:00 2001 From: Parmeet Singh Bhatia Date: Thu, 20 May 2021 11:43:05 -0700 Subject: [PATCH 62/68] Import torchtext #1313 36e33e2 Summary: Importing from Github Reviewed By: cpuhrsch Differential Revision: D28572929 fbshipit-source-id: 2e7b00aadeda6ab0596ef23295f41c5b0fa246e7 --- benchmark/benchmark_experimental_vocab.py | 6 +- docs/source/datasets.rst | 6 + docs/source/experimental_datasets_raw.rst | 6 - docs/source/experimental_vocab.rst | 18 +- docs/source/vocab.rst | 10 + examples/data_pipeline/transforms.py | 2 +- examples/vocab/pytext_vocab.py | 2 +- test/asset/raw_datasets.jsonl | 8 +- test/data/test_builtin_datasets.py | 9 +- test/experimental/test_with_asset.py | 42 +- test/test_vocab.py | 82 +-- torchtext/csrc/register_bindings.cpp | 3 +- torchtext/csrc/vocab.cpp | 67 ++- torchtext/csrc/vocab.h | 17 +- torchtext/data/__init__.py | 6 +- torchtext/datasets/__init__.py | 4 +- torchtext/datasets/multi30k.py | 85 +++ .../experimental/datasets/raw/__init__.py | 2 - .../experimental/datasets/raw/multi30k.py | 543 ------------------ .../experimental/datasets/translation.py | 56 +- torchtext/experimental/transforms.py | 4 +- torchtext/experimental/vocab.py | 137 ----- torchtext/experimental/vocab_factory.py | 75 +++ torchtext/vocab.py | 118 +++- 24 files changed, 432 insertions(+), 876 deletions(-) create mode 100644 torchtext/datasets/multi30k.py delete mode 100644 torchtext/experimental/datasets/raw/multi30k.py delete mode 100644 torchtext/experimental/vocab.py create mode 100644 torchtext/experimental/vocab_factory.py diff --git a/benchmark/benchmark_experimental_vocab.py b/benchmark/benchmark_experimental_vocab.py index 92729ddf1a..e79f2715c2 100644 --- a/benchmark/benchmark_experimental_vocab.py +++ b/benchmark/benchmark_experimental_vocab.py @@ -7,11 +7,11 @@ from matplotlib import pyplot as plt import torch from torchtext.experimental.datasets import DATASETS -from torchtext.experimental.vocab import ( - vocab as VocabExperimental, +from torchtext.experimental.vocab_factory import ( load_vocab_from_file, build_vocab_from_text_file ) +from torchtext.vocab import vocab as VocabExperimental from torchtext.legacy.vocab import ( Vocab, build_vocab_from_iterator @@ -75,7 +75,7 @@ def legacy_vocab_from_file_object(file_like_object, **kwargs): Vocab: a `Vocab` object. Examples: - >>> from torchtext.experimental.vocab import vocab_from_file_object + >>> from torchtext.vocab import vocab_from_file_object >>> f = open('vocab.txt', 'r') >>> v = vocab_from_file_object(f, specials=('', '', ''), specials_first=False) """ diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index 4f45d217a1..077aa27055 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -98,6 +98,12 @@ PennTreebank Machine Translation ^^^^^^^^^^^^^^^^^^^ +Multi30k +~~~~~~~~ + +.. autofunction:: Multi30k + + IWSLT2016 ~~~~~~~~~ diff --git a/docs/source/experimental_datasets_raw.rst b/docs/source/experimental_datasets_raw.rst index 2f8665bce6..ccf3a22b98 100644 --- a/docs/source/experimental_datasets_raw.rst +++ b/docs/source/experimental_datasets_raw.rst @@ -31,12 +31,6 @@ The following datasets are available: Machine Translation ^^^^^^^^^^^^^^^^^^^ -Multi30k -~~~~~~~~ - -.. autofunction:: Multi30k - - WMT14 ~~~~~ diff --git a/docs/source/experimental_vocab.rst b/docs/source/experimental_vocab.rst index 2803b0e1c2..13ed4a480b 100644 --- a/docs/source/experimental_vocab.rst +++ b/docs/source/experimental_vocab.rst @@ -1,16 +1,11 @@ .. role:: hidden :class: hidden-section -torchtext.experimental.vocab -============================ +torchtext.experimental.vocab_factory +==================================== -.. automodule:: torchtext.experimental.vocab -.. currentmodule:: torchtext.experimental.vocab - -:hidden:`vocab` -~~~~~~~~~~~~~~~ - -.. autofunction:: vocab +.. automodule:: torchtext.experimental.vocab_factory +.. currentmodule:: torchtext.experimental.vocab_factory :hidden:`load_vocab_from_file` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -21,8 +16,3 @@ torchtext.experimental.vocab ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autofunction:: build_vocab_from_text_file - -:hidden:`build_vocab_from_iterator` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: build_vocab_from_iterator diff --git a/docs/source/vocab.rst b/docs/source/vocab.rst index 3dd9882831..a4fcaad0c9 100644 --- a/docs/source/vocab.rst +++ b/docs/source/vocab.rst @@ -13,6 +13,16 @@ torchtext.vocab .. autoclass:: Vocab :members: :special-members: + +:hidden:`vocab` +~~~~~~~~~~~~~~~ + +.. autofunction:: vocab + +:hidden:`build_vocab_from_iterator` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: build_vocab_from_iterator :hidden:`Vectors` diff --git a/examples/data_pipeline/transforms.py b/examples/data_pipeline/transforms.py index 2bcb8ff34c..3bd88ff7a5 100644 --- a/examples/data_pipeline/transforms.py +++ b/examples/data_pipeline/transforms.py @@ -1,5 +1,5 @@ import torch.nn as nn -from torchtext.experimental.vocab import vocab +from torchtext.vocab import vocab from typing import List from collections import OrderedDict import torch diff --git a/examples/vocab/pytext_vocab.py b/examples/vocab/pytext_vocab.py index 09af582133..a12d8ac07b 100644 --- a/examples/vocab/pytext_vocab.py +++ b/examples/vocab/pytext_vocab.py @@ -2,7 +2,7 @@ from fairseq.data.dictionary import Dictionary import torch -from torchtext.experimental.vocab import vocab +from torchtext.vocab import vocab from torchtext.vocab import Vocab from typing import Dict, List, Optional diff --git a/test/asset/raw_datasets.jsonl b/test/asset/raw_datasets.jsonl index e014d1aad7..c27ec73f44 100644 --- a/test/asset/raw_datasets.jsonl +++ b/test/asset/raw_datasets.jsonl @@ -21,9 +21,9 @@ {"dataset_name": "UDPOS", "split": "test", "NUM_LINES": 2077, "MD5": "bdcac7c52d934656bae1699541424545", "URL": "https://bitbucket.org/sivareddyg/public/downloads/en-ud-v2.zip", "first_line": "c81f4ab7afe76c346680b81ab4cb0b36"} {"dataset_name": "CoNLL2000Chunking", "split": "train", "NUM_LINES": 8936, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": "3d411e5490dfb95a9d0449fea4ece7c2"} {"dataset_name": "CoNLL2000Chunking", "split": "test", "NUM_LINES": 2012, "MD5": {"train": "6969c2903a1f19a83569db643e43dcc8", "test": "a916e1c2d83eb3004b38fc6fcd628939"}, "URL": {"train": "https://www.clips.uantwerpen.be/conll2000/chunking/train.txt.gz", "test": "https://www.clips.uantwerpen.be/conll2000/chunking/test.txt.gz"}, "first_line": "b3f46baa5f096206547e5212de493214"} -{"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": ["d9a5fc268917725a2b0efce3a0cc8607", "81ff90b99829c0cd4b1b587d394afd39", "0065d13af80720a55ca8153d126e6627", "6cb767741dcad3931f966fefbc05203f", "62f36422bfab90fb42a560546b704009", "540da4566bb6dd35fdbc720218b742b7", "613eb4a3f0c2b13f0871ced946851b0e", "d848fe0ae8b9447209fb49c5c31cb3d2", "abc13b4042f4fef1cdff6de3b6c53b71", "cbf5bfc2147706f228d288e1b18bf4af", "bdfe4222f4692ccaa1e3389460f0890e", "0e1ee2b4145795bd180b193424db204b", "1cff688d1aadef7fdb22e9ad27d6fd2c", "3e10289959d0059952511c31df3c7550"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/train.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/train.5.en.gz"], "first_line": "51cf1f8f5fd11c9299e1502e3ee3743a"} -{"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": ["83cdc082f646b769095615384cf5c0ca", "6e0e229eb049e3fc99a1ef02fb2d5f91", "2b69aa9253948ac9f67e94917272dd40", "93fc564584b7e5ba410c761ea5a1c682", "b26486ede1d4436d5acf6e38c65bb44d", "16165248083beacebfe18866d5f4f0ae", "7180780822d4b600eb81c1ccf171c230", "8edb43c90cae66ec762748a968089b99", "873a377a348713d3ab84db1fb57cdede", "df57faf5f00d434d2559c021ef55f1aa", "9077a5127480cc799116384de501bd70", "c1f697c3b6dfb7305349db34e26b45fc", "acb5ea26a577ceccfae6337181c31716", "680816e0938fea5cf5331444bc09a4cf"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/val.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/val.5.en.gz"], "first_line": "496d7eab1215ebf8d40fa530dbf6debb"} -{"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": ["3104872229daa1bef3b401d44dd2220b", "efd67d314d98489b716b145475101932", "6a8d5c87f6ae19e3d35681aa6fd16571", "e8cd6ec2bc8a11fc846fa48a46e3d0bb", "ff2c0fcb4893a13bd73414306bc250ae", "005396bac545d880abe6f00bbb7dbbb4", "a7b684e0edbef1d4a23660c8e8e743fd", "a152878809942757a55ce087073486b8", "08dc7cd4a662f31718412de95ca9bfe3", "cb09af7d2b501f9112f2d6a59fa1360d", "4995d10954a804d3cdfd907b9fd093e8", "ac0c72653c140dd96707212a1baa4278", "6dfb42cae4e4fd9a3c40e62ff5398a55", "ece8cec6b87bf00dd12607f3062dae4c", "9a7e7b2dcc33135a32cd621c3b37d2d8", "7d5ef0f069ee2d74dc2fdc6b46cd47fa", "eec05227daba4bb8f3f8f25b1cb335f4", "9318fa08c0c0b96114eadb10eb2fc633", "088ec0765fa213a0eb937a62adfd4996", "5f7c8d0be0ac739856b47d32a9434998", "713ed720636622a54546d5f14f88b00f"], "URL": ["https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.cs.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2018_flickr.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2016_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_flickr.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task1/raw/test_2017_mscoco.fr.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.de.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.1.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.2.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.3.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.4.en.gz", "https://raw.githubusercontent.com/multi30k/dataset/master/data/task2/raw/test_2016.5.en.gz"], "first_line": "5c5a9e6b599a340baf3aaec68dd43b0e"} +{"dataset_name": "Multi30k", "split": "train", "NUM_LINES": 29000, "MD5": {"train": "20140d013d05dd9a72dfde46478663ba05737ce983f478f960c1123c6671be5e", "valid": "a7aa20e9ebd5ba5adce7909498b94410996040857154dab029851af3a866da8c", "test": "0681be16a532912288a91ddd573594fbdd57c0fbb81486eff7c55247e35326c2"}, "URL": {"train": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/training.tar.gz", "valid": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/validation.tar.gz", "test": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/mmt16_task1_test.tar.gz"}, "first_line": "51cf1f8f5fd11c9299e1502e3ee3743a"} +{"dataset_name": "Multi30k", "split": "valid", "NUM_LINES": 1014, "MD5": {"train": "20140d013d05dd9a72dfde46478663ba05737ce983f478f960c1123c6671be5e", "valid": "a7aa20e9ebd5ba5adce7909498b94410996040857154dab029851af3a866da8c", "test": "0681be16a532912288a91ddd573594fbdd57c0fbb81486eff7c55247e35326c2"}, "URL": {"train": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/training.tar.gz", "valid": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/validation.tar.gz", "test": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/mmt16_task1_test.tar.gz"}, "first_line": "496d7eab1215ebf8d40fa530dbf6debb"} +{"dataset_name": "Multi30k", "split": "test", "NUM_LINES": 1000, "MD5": {"train": "20140d013d05dd9a72dfde46478663ba05737ce983f478f960c1123c6671be5e", "valid": "a7aa20e9ebd5ba5adce7909498b94410996040857154dab029851af3a866da8c", "test": "0681be16a532912288a91ddd573594fbdd57c0fbb81486eff7c55247e35326c2"}, "URL": {"train": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/training.tar.gz", "valid": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/validation.tar.gz", "test": "http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/mmt16_task1_test.tar.gz"}, "first_line": "5c5a9e6b599a340baf3aaec68dd43b0e"} {"dataset_name": "IWSLT2016", "split": "train", "NUM_LINES": 196884, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": "0a57052d6042cc1e505779347c187174"} {"dataset_name": "IWSLT2016", "split": "valid", "NUM_LINES": 993, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": "8a875fe03dee1988f21d2b9424e25957"} {"dataset_name": "IWSLT2016", "split": "test", "NUM_LINES": 1305, "MD5": "c393ed3fc2a1b0f004b3331043f615ae", "URL": "https://drive.google.com/uc?id=1l5y6Giag9aRPwGtuZHswh3w5v3qEz8D8", "first_line": "ec2842026c4ddf2ea7321e9566676554"} @@ -46,4 +46,4 @@ {"dataset_name": "SQuAD1", "split": "dev", "NUM_LINES": 10570, "MD5": {"train": "981b29407e0affa3b1b156f72073b945", "dev": "3e85deb501d4e538b6bc56f786231552"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json"}, "first_line": "fd5bd80f392f3a03ec908508da3a4ea3"} {"dataset_name": "SQuAD2", "split": "train", "NUM_LINES": 130319, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": "9b719a13e9ea95ab9700c5c631885fc8"} {"dataset_name": "SQuAD2", "split": "dev", "NUM_LINES": 11873, "MD5": {"train": "62108c273c268d70893182d5cf8df740", "dev": "246adae8b7002f8679c027697b0b7cf8"}, "URL": {"train": "https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json", "dev": "https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json"}, "first_line": "1e011c981d41cca284070532135eb9bd"} -{"dataset_name": "EnWik9", "split": "train", "NUM_LINES": 13147026, "MD5": "3e773f8a1577fda2e27f871ca17f31fd", "URL": "http://mattmahoney.net/dc/enwik9.zip", "first_line": "9ac868b1ea4f13083b6c923bc3134a70"} +{"dataset_name": "EnWik9", "split": "train", "NUM_LINES": 13147026, "MD5": "3e773f8a1577fda2e27f871ca17f31fd", "URL": "http://mattmahoney.net/dc/enwik9.zip", "first_line": "9ac868b1ea4f13083b6c923bc3134a70"} \ No newline at end of file diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index 0a2a1f94e1..ce922c0a8f 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -133,7 +133,7 @@ def test_raw_text_name_property(self, info): dataset_name = info['dataset_name'] split = info['split'] - if dataset_name == "Multi30k" or dataset_name == 'WMT14': + if dataset_name == 'WMT14': data_iter = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) else: data_iter = torchtext.datasets.DATASETS[dataset_name](split=split) @@ -147,7 +147,7 @@ def test_raw_text_classification(self, info): dataset_name = info['dataset_name'] split = info['split'] - if dataset_name == "Multi30k" or dataset_name == 'WMT14': + if dataset_name == 'WMT14': data_iter = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) else: data_iter = torchtext.datasets.DATASETS[dataset_name](split=split) @@ -156,9 +156,6 @@ def test_raw_text_classification(self, info): if dataset_name == "AG_NEWS": self.assertEqual(torchtext.datasets.URLS[dataset_name][split], info['URL']) self.assertEqual(torchtext.datasets.MD5[dataset_name][split], info['MD5']) - elif dataset_name == "Multi30k": - self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name][split], info['URL']) - self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name][split], info['MD5']) elif dataset_name == "WMT14": self.assertEqual(torchtext.experimental.datasets.raw.URLS[dataset_name], info['URL']) self.assertEqual(torchtext.experimental.datasets.raw.MD5[dataset_name], info['MD5']) @@ -328,7 +325,7 @@ def test_multi30k(self): [18, 24, 1168, 807, 16, 56, 83, 335, 1338]) # Add test for the subset of the standard datasets - train_iter, valid_iter = torchtext.experimental.datasets.raw.Multi30k(split=('train', 'valid')) + train_iter, valid_iter = torchtext.datasets.Multi30k(split=('train', 'valid')) self._helper_test_func(len(train_iter), 29000, ' '.join(next(train_iter)), ' '.join(['Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n', 'Two young, White males are outside near many bushes.\n'])) diff --git a/test/experimental/test_with_asset.py b/test/experimental/test_with_asset.py index 2055e0ab57..94c54400da 100644 --- a/test/experimental/test_with_asset.py +++ b/test/experimental/test_with_asset.py @@ -11,7 +11,7 @@ TextSequentialTransforms, ) from torch.utils.data import DataLoader -from torchtext.experimental.vocab import ( +from torchtext.experimental.vocab_factory import ( load_vocab_from_file, build_vocab_from_text_file, ) @@ -26,6 +26,7 @@ FastText, load_vectors_from_file_path, ) +from torchtext.data.functional import custom_replace from torchtext.utils import download_from_url @@ -178,8 +179,8 @@ def test_glove_different_dims(self): def test_vocab_from_file(self): asset_name = 'vocab_test.txt' asset_path = get_asset_path(asset_name) - v = load_vocab_from_file(asset_path, unk_token='') - expected_itos = ['', 'b', 'a', 'c'] + v = load_vocab_from_file(asset_path) + expected_itos = ['b', 'a', 'c'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) @@ -187,16 +188,39 @@ def test_vocab_from_file(self): def test_vocab_from_raw_text_file(self): asset_name = 'vocab_raw_text_test.txt' asset_path = get_asset_path(asset_name) - tokenizer = basic_english_normalize() - jit_tokenizer = torch.jit.script(tokenizer) - v = build_vocab_from_text_file(asset_path, jit_tokenizer, unk_token='') - expected_itos = ['', "'", 'after', 'talks', '.', 'are', 'at', 'disappointed', + + def python_basic_english_normalize(input): + patterns_list = [ + (r'\'', ' \' '), + (r'\"', ''), + (r'\.', ' . '), + (r'
      ', ' '), + (r',', ' , '), + (r'\(', ' ( '), + (r'\)', ' ) '), + (r'\!', ' ! '), + (r'\?', ' ? '), + (r'\;', ' '), + (r'\:', ' '), + (r'\s+', ' ')] + norm_transform = custom_replace(patterns_list) + return list(norm_transform([input.lower()]))[0].split() + + # using python based basic_english_normalize tokenizer + # we can also use basic_english_normalize() here + v1 = build_vocab_from_text_file(asset_path, tokenizer=python_basic_english_normalize) + expected_itos = ["'", 'after', 'talks', '.', 'are', 'at', 'disappointed', 'fears', 'federal', 'firm', 'for', 'mogul', 'n', 'newall', 'parent', 'pension', 'representing', 'say', 'stricken', 't', 'they', 'turner', 'unions', 'with', 'workers'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} - self.assertEqual(v.get_itos(), expected_itos) - self.assertEqual(dict(v.get_stoi()), expected_stoi) + self.assertEqual(v1.get_itos(), expected_itos) + self.assertEqual(dict(v1.get_stoi()), expected_stoi) + + # using JIT'D basic_english_normalize tokenizer + v2 = build_vocab_from_text_file(asset_path, tokenizer=torch.jit.script(basic_english_normalize())) + self.assertEqual(v2.get_itos(), expected_itos) + self.assertEqual(dict(v2.get_stoi()), expected_stoi) def test_builtin_pretrained_sentencepiece_processor(self): sp_model_path = download_from_url(PRETRAINED_SP_MODEL['text_unigram_25000']) diff --git a/test/test_vocab.py b/test/test_vocab.py index afb140c71e..c78cd5c708 100644 --- a/test/test_vocab.py +++ b/test/test_vocab.py @@ -3,7 +3,7 @@ import os import torch from test.common.torchtext_test_case import TorchtextTestCase -from torchtext.experimental.vocab import ( +from torchtext.vocab import ( vocab, build_vocab_from_iterator, ) @@ -15,16 +15,6 @@ def tearDown(self): torch._C._jit_clear_class_registry() torch.jit._recursive.concrete_type_store = torch.jit._recursive.ConcreteTypeStore() - def test_has_unk(self): - c = OrderedDict() - v = vocab(c) - self.assertEqual(v[''], 0) - - def test_new_unk(self): - c = OrderedDict() - v = vocab(c, unk_token="") - self.assertEqual(v[''], 0) - def test_vocab_membership(self): token_to_freq = {'': 2, 'a': 2, 'b': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) @@ -46,28 +36,6 @@ def test_vocab_get_item(self): self.assertEqual(v['a'], 1) self.assertEqual(v['b'], 2) - def test_reassign_token(self): - token_to_freq = {'': 1, 'a': 2, 'b': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - v = vocab(c, min_freq=1) - - self.assertEqual(v[''], 2) - self.assertEqual(v['a'], 0) - self.assertEqual(v['b'], 1) - v.reassign_token('', 0) - self.assertEqual(v[''], 0) - self.assertEqual(v['a'], 1) - self.assertEqual(v['b'], 2) - - self.assertEqual(v.get_itos(), ['', 'a', 'b']) - - with self.assertRaises(RuntimeError): - v.reassign_token('not in vocab', 0) - - with self.assertRaises(RuntimeError): - v.reassign_token('', 3) - def test_default_index(self): token_to_freq = {'': 2, 'a': 2, 'b': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) @@ -81,6 +49,10 @@ def test_default_index(self): v.set_default_index(0) self.assertEqual(v['not in vocab'], 0) + v.set_default_index(None) + with self.assertRaises(RuntimeError): + v['not in vocab'] + def test_default_index_jit(self): token_to_freq = {'': 2, 'a': 2, 'b': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) @@ -90,6 +62,10 @@ def test_default_index_jit(self): v_jit = torch.jit.script(v) self.assertEqual(v_jit['not in vocab'], 0) + v_jit.set_default_index(None) + with self.assertRaises(RuntimeError): + v_jit['not in vocab'] + def test_vocab_insert_token(self): c = OrderedDict({'': 2, 'a': 2}) @@ -118,7 +94,7 @@ def test_vocab_append_token(self): v = vocab(c) v.append_token('b') - expected_itos = ['', 'a', 'b'] + expected_itos = ['a', 'b'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) @@ -134,7 +110,7 @@ def test_vocab_len(self): c = OrderedDict(sorted_by_freq_tuples) v = vocab(c) - self.assertEqual(len(v), 4) + self.assertEqual(len(v), 3) def test_vocab_basic(self): token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} @@ -143,7 +119,7 @@ def test_vocab_basic(self): c = OrderedDict(sorted_by_freq_tuples) v = vocab(c, min_freq=3) - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) @@ -157,7 +133,7 @@ def test_vocab_jit(self): v = vocab(c, min_freq=3) jit_v = torch.jit.script(v) - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} assert not v.is_jitable @@ -177,7 +153,7 @@ def test_vocab_forward(self): jit_v = torch.jit.script(v) tokens = ['b', 'a', 'c'] - expected_indices = [2, 1, 3] + expected_indices = [1, 0, 2] self.assertEqual(v(tokens), expected_indices) self.assertEqual(jit_v(tokens), expected_indices) @@ -188,7 +164,7 @@ def test_vocab_lookup_token(self): c = OrderedDict(sorted_by_freq_tuples) v = vocab(c) - self.assertEqual(v.lookup_token(1), 'a') + self.assertEqual(v.lookup_token(1), 'b') with self.assertRaises(RuntimeError): v.lookup_token(100) @@ -198,7 +174,7 @@ def test_vocab_lookup_tokens(self): c = OrderedDict(sorted_by_freq_tuples) v = vocab(c) - indices = [2, 1, 3] + indices = [1, 0, 2] expected_tokens = ['b', 'a', 'c'] self.assertEqual(v.lookup_tokens(indices), expected_tokens) @@ -210,19 +186,10 @@ def test_vocab_lookup_indices(self): v = vocab(c) tokens = ['b', 'a', 'c'] - expected_indices = [2, 1, 3] + expected_indices = [1, 0, 2] self.assertEqual(v.lookup_indices(tokens), expected_indices) - def test_errors_vocab_python(self): - token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} - sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) - c = OrderedDict(sorted_by_freq_tuples) - - with self.assertRaises(ValueError): - # Test proper error raised when setting unk token to None - vocab(c, unk_token=None) - def test_vocab_load_and_save(self): token_to_freq = {'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2} sorted_by_freq_tuples = sorted(token_to_freq.items(), key=lambda x: x[1], reverse=True) @@ -231,7 +198,7 @@ def test_vocab_load_and_save(self): v = vocab(c, min_freq=3) v.set_default_index(0) - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world'] expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) @@ -258,8 +225,19 @@ def test_vocab_load_and_save(self): def test_build_vocab_iterator(self): iterator = [['hello', 'hello', 'hello', 'freq_low', 'hello', 'world', 'world', 'world', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'freq_low', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T']] + specials = ["", "", "", "pad"] v = build_vocab_from_iterator(iterator) - expected_itos = ['', 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + v = build_vocab_from_iterator(iterator, specials=specials) + expected_itos = specials + ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] + expected_stoi = {x: index for index, x in enumerate(expected_itos)} + self.assertEqual(v.get_itos(), expected_itos) + self.assertEqual(dict(v.get_stoi()), expected_stoi) + v = build_vocab_from_iterator(iterator, specials=specials, special_first=False) + expected_itos = ['ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T', 'hello', 'world', 'freq_low'] + specials expected_stoi = {x: index for index, x in enumerate(expected_itos)} self.assertEqual(v.get_itos(), expected_itos) self.assertEqual(dict(v.get_stoi()), expected_stoi) diff --git a/torchtext/csrc/register_bindings.cpp b/torchtext/csrc/register_bindings.cpp index cf6656d12a..e7e2241a7f 100644 --- a/torchtext/csrc/register_bindings.cpp +++ b/torchtext/csrc/register_bindings.cpp @@ -118,7 +118,6 @@ PYBIND11_MODULE(_torchtext, m) { const char *buffer = PyUnicode_AsUTF8AndSize(item.ptr(), &length); return self->__getitem__(c10::string_view{buffer, (size_t)length}); }) - .def("reassign_token", &Vocab::reassign_token) .def("insert_token", &Vocab::insert_token) .def("set_default_index", &Vocab::set_default_index) .def("get_default_index", &Vocab::get_default_index) @@ -156,6 +155,7 @@ PYBIND11_MODULE(_torchtext, m) { &_load_token_and_vectors_from_file); m.def("_load_vocab_from_file", &_load_vocab_from_file); m.def("_build_vocab_from_text_file", &build_vocab_from_text_file); + m.def("_build_vocab_from_text_file_using_python_tokenizer", &_build_vocab_from_text_file_using_python_tokenizer); } TORCH_LIBRARY_FRAGMENT(torchtext, m) { @@ -243,7 +243,6 @@ TORCH_LIBRARY_FRAGMENT(torchtext, m) { .def("__getitem__", [](const c10::intrusive_ptr &self, const std::string &item) -> int64_t { return self->__getitem__(c10::string_view{item}); }) - .def("reassign_token", &Vocab::reassign_token) .def("insert_token", &Vocab::insert_token) .def("__len__", &Vocab::__len__) .def("set_default_index", &Vocab::set_default_index) diff --git a/torchtext/csrc/vocab.cpp b/torchtext/csrc/vocab.cpp index e659fbdb70..1ce67ed8b5 100644 --- a/torchtext/csrc/vocab.cpp +++ b/torchtext/csrc/vocab.cpp @@ -46,7 +46,9 @@ int64_t Vocab::__getitem__(const c10::string_view &token) const { return default_index_.value(); } -void Vocab::set_default_index(int64_t index) { default_index_ = index; } +void Vocab::set_default_index(c10::optional index) { + default_index_ = index; +} c10::optional Vocab::get_default_index() const { return default_index_; @@ -62,20 +64,6 @@ void Vocab::append_token(const std::string &token) { _add(token); } -void Vocab::reassign_token(const std::string &token, const int64_t &index) { - // throw error if index is not valid - TORCH_CHECK(index >= 0 && index < __len__(), - "Specified index " + std::to_string(index) + - " is out of bounds for vocab of size " + - std::to_string(__len__())); - - // throw error if token not found - TORCH_CHECK(__contains__(token), "Token " + token + " not found in Vocab"); - - _remove(token); - insert_token(token, index); -} - void Vocab::insert_token(const std::string &token, const int64_t &index) { // throw error if index is not valid TORCH_CHECK(index >= 0 && index <= __len__(), @@ -146,6 +134,7 @@ int64_t _infer_lines(const std::string &file_path) { int64_t num_lines = 0; std::ifstream fin; fin.open(file_path, std::ios::in); + TORCH_CHECK(fin.is_open(), "Cannot open input file " + file_path); while (fin.ignore(std::numeric_limits::max(), '\n')) { num_lines++; @@ -356,6 +345,54 @@ Vocab _build_vocab_from_text_file(const std::string &file_path, return Vocab(std::move(tokens)); } +Vocab _build_vocab_from_text_file_using_python_tokenizer( + const std::string &file_path, const int64_t min_freq, + py::object tokenizer) { + // find number of lines + int64_t num_lines = _infer_lines(file_path); + // Read text from file and add tokens + std::ifstream fin(file_path, std::ios::in); + TORCH_CHECK(fin.is_open(), "Cannot open input file " + file_path); + + IndexDict counter; + std::string line; + for (int64_t i = 0; i < num_lines; i++) { + std::getline(fin, line); + std::vector token_list = + tokenizer(line).cast>(); + + for (size_t i = 0; i < token_list.size(); i++) { + std::string token = token_list[i]; + + if (counter.find(token) == counter.end()) { + counter[token] = 1; + } else { + counter[token] += 1; + } + } + } + + // create tokens-frequency pairs + std::vector> token_freq_pairs; + for (const auto &item : counter) { + if (item.second >= min_freq) { + token_freq_pairs.push_back(item); + } + } + + // sort tokens by frequency + CompareTokens compare_tokens; + std::sort(token_freq_pairs.begin(), token_freq_pairs.end(), compare_tokens); + + // Create final list of tokens + StringList tokens; + for (const auto &token_freq_pair : token_freq_pairs) { + tokens.push_back(token_freq_pair.first); + } + + return Vocab(std::move(tokens)); +} + VocabStates _serialize_vocab(const c10::intrusive_ptr &self) { std::vector integers; StringList strings = self->itos_; diff --git a/torchtext/csrc/vocab.h b/torchtext/csrc/vocab.h index 06f98865d3..e7df276391 100644 --- a/torchtext/csrc/vocab.h +++ b/torchtext/csrc/vocab.h @@ -1,6 +1,10 @@ #include #include +#include #include + +namespace py = pybind11; + namespace torchtext { typedef std::vector StringList; @@ -27,9 +31,8 @@ struct Vocab : torch::CustomClassHolder { int64_t __len__() const; int64_t __getitem__(const c10::string_view &token) const; bool __contains__(const c10::string_view &token) const; - void set_default_index(int64_t index); + void set_default_index(c10::optional index); c10::optional get_default_index() const; - void reassign_token(const std::string &token, const int64_t &index); void insert_token(const std::string &token, const int64_t &index); void append_token(const std::string &token); std::string lookup_token(const int64_t &index); @@ -65,14 +68,6 @@ struct Vocab : torch::CustomClassHolder { stoi_[h] = itos_.size() - 1; } } - - void _remove(const std::string &w) { - uint32_t h = _find(c10::string_view{w.data(), w.size()}); - if (stoi_[h] != -1) { - stoi_[h] = -1; - itos_.erase(std::find(itos_.begin(), itos_.end(), w)); - } - } }; VocabStates _serialize_vocab(const c10::intrusive_ptr &self); @@ -84,5 +79,7 @@ Vocab _build_vocab_from_text_file(const std::string &file_path, const int64_t min_freq, const int64_t num_cpus, torch::jit::script::Module tokenizer); +Vocab _build_vocab_from_text_file_using_python_tokenizer( + const std::string &file_path, const int64_t min_freq, py::object tokenizer); } // namespace torchtext diff --git a/torchtext/data/__init__.py b/torchtext/data/__init__.py index d2aa64ccaf..b001027283 100644 --- a/torchtext/data/__init__.py +++ b/torchtext/data/__init__.py @@ -12,8 +12,6 @@ to_map_style_dataset, ) -from ..legacy.data import Batch - __all__ = ["bleu_score", "get_tokenizer", "interleave_keys", "generate_sp_model", "load_sp_model", @@ -21,6 +19,4 @@ "custom_replace", "simple_space_split", "numericalize_tokens_from_iterator", "filter_wikipedia_xml", - "to_map_style_dataset", - "Batch" # tmp compatibility hack for old lightning - ] + "to_map_style_dataset"] diff --git a/torchtext/datasets/__init__.py b/torchtext/datasets/__init__.py index 77838b441d..995fc96a89 100644 --- a/torchtext/datasets/__init__.py +++ b/torchtext/datasets/__init__.py @@ -18,6 +18,7 @@ from .yahooanswers import YahooAnswers from .yelpreviewfull import YelpReviewFull from .yelpreviewpolarity import YelpReviewPolarity +from .multi30k import Multi30k DATASETS = { 'AG_NEWS': AG_NEWS, @@ -38,7 +39,8 @@ 'WikiText2': WikiText2, 'YahooAnswers': YahooAnswers, 'YelpReviewFull': YelpReviewFull, - 'YelpReviewPolarity': YelpReviewPolarity + 'YelpReviewPolarity': YelpReviewPolarity, + 'Multi30k': Multi30k } URLS = {} diff --git a/torchtext/datasets/multi30k.py b/torchtext/datasets/multi30k.py new file mode 100644 index 0000000000..2eda8e0172 --- /dev/null +++ b/torchtext/datasets/multi30k.py @@ -0,0 +1,85 @@ +import os +from torchtext.data.datasets_utils import ( + _download_extract_validate, + _RawTextIterableDataset, + _wrap_split_argument, + _create_dataset_directory, + _read_text_iterator, +) + +URL = { + 'train': r'http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/training.tar.gz', + 'valid': r'http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/validation.tar.gz', + 'test': r'http://www.quest.dcs.shef.ac.uk/wmt16_files_mmt/mmt16_task1_test.tar.gz', +} + +MD5 = { + 'train': '20140d013d05dd9a72dfde46478663ba05737ce983f478f960c1123c6671be5e', + 'valid': 'a7aa20e9ebd5ba5adce7909498b94410996040857154dab029851af3a866da8c', + 'test': '0681be16a532912288a91ddd573594fbdd57c0fbb81486eff7c55247e35326c2', +} + +_EXTRACTED_FILES_INFO = { + 'train': { + 'file_prefix': 'train', + 'md5': { + 'de': '695df46f6fd14567e69970408a2c129a50e778a910ecb1585a92eb25b2c7accc', + 'en': '4b4d37e774976ef44fecca1738cdeb3b3ba384851a59a755b9c5e6aa7d87b13c', + }, + }, + 'valid': { + 'file_prefix': 'val', + 'md5': { + 'de': 'fd0fc009db2446cfc12d96a382aff0d3122cb47577b352d0f7e0bb3a38e2e552', + 'en': '40cd20974079d9afb0e3d27c659a8e059cc2fcf850b4bc23ede13fc36dd8a865', + }, + }, + 'test': { + 'file_prefix': 'test', + 'md5': { + 'de': 'c1d2f544471a7387e37d15f1adf075ff7d6fe57a30840bb969281ae102d24cb1', + 'en': '399a4382932c1aadd3ceb9bef1008d388a64c76d4ae4e9d4728c6f4301cac182', + }, + }, +} + +NUM_LINES = { + 'train': 29000, + 'valid': 1014, + 'test': 1000, +} + +DATASET_NAME = "Multi30k" + + +@_create_dataset_directory(dataset_name=DATASET_NAME) +@_wrap_split_argument(('train', 'valid', 'test')) +def Multi30k(root, split, language_pair=('de', 'en')): + """Multi30k dataset + + Reference: http://www.statmt.org/wmt16/multimodal-task.html#task1 + + Args: + root: Directory where the datasets are saved. Default: ".data" + split: split or splits to be returned. Can be a string or tuple of strings. Default: (‘train’, ‘valid’, ‘test’) + language_pair: tuple or list containing src and tgt language. Available options are ('de','en') and ('en', 'de') + """ + + assert (len(language_pair) == 2), 'language_pair must contain only 2 elements: src and tgt language respectively' + assert (tuple(sorted(language_pair)) == ('de', 'en')), "language_pair must be either ('de','en') or ('en', 'de')" + + downloaded_file = os.path.basename(URL[split]) + + src_path = _download_extract_validate(root, URL[split], MD5[split], + os.path.join(root, downloaded_file), + os.path.join(root, _EXTRACTED_FILES_INFO[split]['file_prefix'] + '.' + language_pair[0]), + _EXTRACTED_FILES_INFO[split]['md5'][language_pair[0]]) + trg_path = _download_extract_validate(root, URL[split], MD5[split], + os.path.join(root, downloaded_file), + os.path.join(root, _EXTRACTED_FILES_INFO[split]['file_prefix'] + '.' + language_pair[1]), + _EXTRACTED_FILES_INFO[split]['md5'][language_pair[1]]) + + src_data_iter = _read_text_iterator(src_path) + trg_data_iter = _read_text_iterator(trg_path) + + return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split], zip(src_data_iter, trg_data_iter)) diff --git a/torchtext/experimental/datasets/raw/__init__.py b/torchtext/experimental/datasets/raw/__init__.py index ca16ff630f..0a2b3f09ac 100644 --- a/torchtext/experimental/datasets/raw/__init__.py +++ b/torchtext/experimental/datasets/raw/__init__.py @@ -1,11 +1,9 @@ import importlib from .wmtnewscrawl import WMTNewsCrawl -from .multi30k import Multi30k from .wmt14 import WMT14 DATASETS = { 'WMTNewsCrawl': WMTNewsCrawl, - 'Multi30k': Multi30k, 'WMT14': WMT14, } diff --git a/torchtext/experimental/datasets/raw/multi30k.py b/torchtext/experimental/datasets/raw/multi30k.py deleted file mode 100644 index acd91f757e..0000000000 --- a/torchtext/experimental/datasets/raw/multi30k.py +++ /dev/null @@ -1,543 +0,0 @@ -import os -from torchtext.utils import (download_from_url, extract_archive) -from torchtext.data.datasets_utils import ( - _RawTextIterableDataset, - _wrap_split_argument, - _create_dataset_directory, - _read_text_iterator, -) - -SUPPORTED_DATASETS = { - 'task1': { - 'cs': { - 'test_2016_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2016_flickr.cs.gz', - 'MD5': '3104872229daa1bef3b401d44dd2220b', - 'NUM_LINES': 1000 - }, - 'train': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/train.cs.gz', - 'MD5': 'd9a5fc268917725a2b0efce3a0cc8607', - 'NUM_LINES': 29000 - }, - 'val': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/val.cs.gz', - 'MD5': '83cdc082f646b769095615384cf5c0ca', - 'NUM_LINES': 1014 - } - }, - 'de': { - 'test_2016_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2016_flickr.de.gz', - 'MD5': 'efd67d314d98489b716b145475101932', - 'NUM_LINES': 1000 - }, - 'test_2017_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2017_flickr.de.gz', - 'MD5': '6a8d5c87f6ae19e3d35681aa6fd16571', - 'NUM_LINES': 1000 - }, - 'test_2017_mscoco': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2017_mscoco.de.gz', - 'MD5': 'e8cd6ec2bc8a11fc846fa48a46e3d0bb', - 'NUM_LINES': 461 - }, - 'train': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/train.de.gz', - 'MD5': '81ff90b99829c0cd4b1b587d394afd39', - 'NUM_LINES': 29000 - }, - 'val': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/val.de.gz', - 'MD5': '6e0e229eb049e3fc99a1ef02fb2d5f91', - 'NUM_LINES': 1014 - } - }, - 'en': { - 'test_2016_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2016_flickr.en.gz', - 'MD5': 'ff2c0fcb4893a13bd73414306bc250ae', - 'NUM_LINES': 1000 - }, - 'test_2017_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2017_flickr.en.gz', - 'MD5': '005396bac545d880abe6f00bbb7dbbb4', - 'NUM_LINES': 1000 - }, - 'test_2017_mscoco': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2017_mscoco.en.gz', - 'MD5': 'a7b684e0edbef1d4a23660c8e8e743fd', - 'NUM_LINES': 461 - }, - 'test_2018_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2018_flickr.en.gz', - 'MD5': 'a152878809942757a55ce087073486b8', - 'NUM_LINES': 1071 - }, - 'train': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/train.en.gz', - 'MD5': '0065d13af80720a55ca8153d126e6627', - 'NUM_LINES': 29000 - }, - 'val': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/val.en.gz', - 'MD5': '2b69aa9253948ac9f67e94917272dd40', - 'NUM_LINES': 1014 - } - }, - 'fr': { - 'test_2016_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2016_flickr.fr.gz', - 'MD5': '08dc7cd4a662f31718412de95ca9bfe3', - 'NUM_LINES': 1000 - }, - 'test_2017_flickr': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2017_flickr.fr.gz', - 'MD5': 'cb09af7d2b501f9112f2d6a59fa1360d', - 'NUM_LINES': 1000 - }, - 'test_2017_mscoco': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/test_2017_mscoco.fr.gz', - 'MD5': '4995d10954a804d3cdfd907b9fd093e8', - 'NUM_LINES': 461 - }, - 'train': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/train.fr.gz', - 'MD5': '6cb767741dcad3931f966fefbc05203f', - 'NUM_LINES': 29000 - }, - 'val': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task1/raw/val.fr.gz', - 'MD5': '93fc564584b7e5ba410c761ea5a1c682', - 'NUM_LINES': 1014 - } - } - }, - 'task2': { - 'de': { - 'test_2016.1': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.1.de.gz', - 'MD5': 'ac0c72653c140dd96707212a1baa4278', - 'NUM_LINES': 1000 - }, - 'test_2016.2': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.2.de.gz', - 'MD5': '6dfb42cae4e4fd9a3c40e62ff5398a55', - 'NUM_LINES': 1000 - }, - 'test_2016.3': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.3.de.gz', - 'MD5': 'ece8cec6b87bf00dd12607f3062dae4c', - 'NUM_LINES': 1000 - }, - 'test_2016.4': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.4.de.gz', - 'MD5': '9a7e7b2dcc33135a32cd621c3b37d2d8', - 'NUM_LINES': 1000 - }, - 'test_2016.5': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.5.de.gz', - 'MD5': '7d5ef0f069ee2d74dc2fdc6b46cd47fa', - 'NUM_LINES': 1000 - }, - 'train.1': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.1.de.gz', - 'MD5': '62f36422bfab90fb42a560546b704009', - 'NUM_LINES': 29000 - }, - 'train.2': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.2.de.gz', - 'MD5': '540da4566bb6dd35fdbc720218b742b7', - 'NUM_LINES': 29000 - }, - 'train.3': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.3.de.gz', - 'MD5': '613eb4a3f0c2b13f0871ced946851b0e', - 'NUM_LINES': 29000 - }, - 'train.4': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.4.de.gz', - 'MD5': 'd848fe0ae8b9447209fb49c5c31cb3d2', - 'NUM_LINES': 29000 - }, - 'train.5': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.5.de.gz', - 'MD5': 'abc13b4042f4fef1cdff6de3b6c53b71', - 'NUM_LINES': 29000 - }, - 'val.1': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.1.de.gz', - 'MD5': 'b26486ede1d4436d5acf6e38c65bb44d', - 'NUM_LINES': 1014 - }, - 'val.2': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.2.de.gz', - 'MD5': '16165248083beacebfe18866d5f4f0ae', - 'NUM_LINES': 1014 - }, - 'val.3': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.3.de.gz', - 'MD5': '7180780822d4b600eb81c1ccf171c230', - 'NUM_LINES': 1014 - }, - 'val.4': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.4.de.gz', - 'MD5': '8edb43c90cae66ec762748a968089b99', - 'NUM_LINES': 1014 - }, - 'val.5': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.5.de.gz', - 'MD5': '873a377a348713d3ab84db1fb57cdede', - 'NUM_LINES': 1014 - } - }, - 'en': { - 'test_2016.1': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.1.en.gz', - 'MD5': 'eec05227daba4bb8f3f8f25b1cb335f4', - 'NUM_LINES': 1000 - }, - 'test_2016.2': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.2.en.gz', - 'MD5': '9318fa08c0c0b96114eadb10eb2fc633', - 'NUM_LINES': 1000 - }, - 'test_2016.3': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.3.en.gz', - 'MD5': '088ec0765fa213a0eb937a62adfd4996', - 'NUM_LINES': 1000 - }, - 'test_2016.4': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.4.en.gz', - 'MD5': '5f7c8d0be0ac739856b47d32a9434998', - 'NUM_LINES': 1000 - }, - 'test_2016.5': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/test_2016.5.en.gz', - 'MD5': '713ed720636622a54546d5f14f88b00f', - 'NUM_LINES': 1000 - }, - 'train.1': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.1.en.gz', - 'MD5': 'cbf5bfc2147706f228d288e1b18bf4af', - 'NUM_LINES': 29000 - }, - 'train.2': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.2.en.gz', - 'MD5': 'bdfe4222f4692ccaa1e3389460f0890e', - 'NUM_LINES': 29000 - }, - 'train.3': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.3.en.gz', - 'MD5': '0e1ee2b4145795bd180b193424db204b', - 'NUM_LINES': 29000 - }, - 'train.4': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.4.en.gz', - 'MD5': '1cff688d1aadef7fdb22e9ad27d6fd2c', - 'NUM_LINES': 29000 - }, - 'train.5': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/train.5.en.gz', - 'MD5': '3e10289959d0059952511c31df3c7550', - 'NUM_LINES': 29000 - }, - 'val.1': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.1.en.gz', - 'MD5': 'df57faf5f00d434d2559c021ef55f1aa', - 'NUM_LINES': 1014 - }, - 'val.2': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.2.en.gz', - 'MD5': '9077a5127480cc799116384de501bd70', - 'NUM_LINES': 1014 - }, - 'val.3': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.3.en.gz', - 'MD5': 'c1f697c3b6dfb7305349db34e26b45fc', - 'NUM_LINES': 1014 - }, - 'val.4': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.4.en.gz', - 'MD5': 'acb5ea26a577ceccfae6337181c31716', - 'NUM_LINES': 1014 - }, - 'val.5': { - 'URL': - 'https://raw.githubusercontent.com/multi30k/dataset/master/' - 'data/task2/raw/val.5.en.gz', - 'MD5': '680816e0938fea5cf5331444bc09a4cf', - 'NUM_LINES': 1014 - } - } - } -} - - -URL = {'train': [], 'valid': [], 'test': []} -MD5 = {'train': [], 'valid': [], 'test': []} -NUM_LINES = {'train': [], 'valid': [], 'test': []} - -for task in SUPPORTED_DATASETS: - for language in SUPPORTED_DATASETS[task]: - for data in SUPPORTED_DATASETS[task][language]: - if 'train' in data: - k = 'train' - elif 'val' in data: - k = 'valid' - else: - k = 'test' - URL[k].append(SUPPORTED_DATASETS[task][language][data]['URL']) - MD5[k].append(SUPPORTED_DATASETS[task][language][data]['MD5']) - NUM_LINES[k].append(SUPPORTED_DATASETS[task][language][data]['NUM_LINES']) - - -def _construct_filepaths(paths, src_filename, tgt_filename): - src_path = None - tgt_path = None - for p in paths: - src_path = p if src_filename in p else src_path - tgt_path = p if tgt_filename in p else tgt_path - return (src_path, tgt_path) - - -DATASET_NAME = "Multi30k" - - -@_create_dataset_directory(dataset_name=DATASET_NAME) -@_wrap_split_argument(('train', 'valid', 'test')) -def Multi30k(root, split, - task='task1', - language_pair=('de', 'en'), - train_set="train", - valid_set="val", - test_set="test_2016_flickr"): - """Multi30k Dataset - - The available datasets include following: - - **Language pairs (task1)**: - - +-----+-----+-----+-----+-----+ - | |'en' |'cs' |'de' |'fr' | - +-----+-----+-----+-----+-----+ - |'en' | | x | x | x | - +-----+-----+-----+-----+-----+ - |'cs' | x | | x | x | - +-----+-----+-----+-----+-----+ - |'de' | x | x | | x | - +-----+-----+-----+-----+-----+ - |'fr' | x | x | x | | - +-----+-----+-----+-----+-----+ - - **Language pairs (task2)**: - - +-----+-----+-----+ - | |'en' |'de' | - +-----+-----+-----+ - |'en' | | x | - +-----+-----+-----+ - |'de' | x | | - +-----+-----+-----+ - - For additional details refer to source: https://github.com/multi30k/dataset - - Args: - root: Directory where the datasets are saved. Default: ".data" - split: split or splits to be returned. Can be a string or tuple of strings. Default: (‘train’, ‘valid’, ‘test’) - task: Indicate the task - language_pair: tuple or list containing src and tgt language - train_set: A string to identify train set. - valid_set: A string to identify validation set. - test_set: A string to identify test set. - - Examples: - >>> from torchtext.experimental.datasets.raw import Multi30k - >>> train_iter, valid_iter, test_iter = Multi30k() - >>> src_sentence, tgt_sentence = next(train_iter) - """ - - if task not in SUPPORTED_DATASETS.keys(): - raise ValueError('task {} is not supported. Valid options are {}'. - format(task, SUPPORTED_DATASETS.keys())) - - assert (len(language_pair) == 2), 'language_pair must contain only 2 elements: src and tgt language respectively' - - if language_pair[0] not in SUPPORTED_DATASETS[task].keys(): - raise ValueError("Source language '{}' is not supported. Valid options for task '{}' are {}". - format(language_pair[0], task, list(SUPPORTED_DATASETS[task].keys()))) - - if language_pair[1] not in SUPPORTED_DATASETS[task].keys(): - raise ValueError("Target language '{}' is not supported. Valid options for task '{}' are {}". - format(language_pair[1], task, list(SUPPORTED_DATASETS[task].keys()))) - - if train_set not in SUPPORTED_DATASETS[task][language_pair[0]].keys() or 'train' not in train_set: - raise ValueError("'{}' is not a valid train set identifier. valid options for task '{}' and language pair {} are {}". - format(train_set, task, language_pair, [k for k in SUPPORTED_DATASETS[task][language_pair[0]].keys() if 'train' in k])) - - if valid_set not in SUPPORTED_DATASETS[task][language_pair[0]].keys() or 'val' not in valid_set: - raise ValueError("'{}' is not a valid valid set identifier. valid options for task '{}' and language pair {} are {}". - format(valid_set, task, language_pair, [k for k in SUPPORTED_DATASETS[task][language_pair[0]].keys() if 'val' in k])) - - if test_set not in SUPPORTED_DATASETS[task][language_pair[0]].keys() or 'test' not in test_set: - raise ValueError("'{}' is not a valid test set identifier. valid options for task '{}' and language pair {} are {}". - format(test_set, task, language_pair, [k for k in SUPPORTED_DATASETS[task][language_pair[0]].keys() if 'test' in k])) - - train_filenames = ["{}.{}".format( - train_set, language_pair[0]), "{}.{}".format(train_set, - language_pair[1])] - valid_filenames = ["{}.{}".format( - valid_set, language_pair[0]), "{}.{}".format(valid_set, - language_pair[1])] - test_filenames = ["{}.{}".format( - test_set, language_pair[0]), "{}.{}".format(test_set, - language_pair[1])] - - if split == 'train': - src_file, tgt_file = train_filenames - elif split == 'valid': - src_file, tgt_file = valid_filenames - else: - src_file, tgt_file = test_filenames - - extracted_files = [] # list of paths to the extracted files - - current_url = [] - current_md5 = [] - - current_filenames = [src_file, tgt_file] - for url, md5 in zip(URL[split], MD5[split]): - if any(f in url for f in current_filenames): - current_url.append(url) - current_md5.append(md5) - - for url, md5 in zip(current_url, current_md5): - dataset_tar = download_from_url( - url, path=os.path.join(root, os.path.basename(url)), root=root, hash_value=md5, hash_type='md5') - extracted_files.extend(extract_archive(dataset_tar)) - - file_archives = extracted_files - - data_filenames = { - split: _construct_filepaths(file_archives, src_file, tgt_file), - } - - for key in data_filenames: - if len(data_filenames[key]) == 0 or data_filenames[key] is None: - raise FileNotFoundError( - "Files are not found for data type {}".format(key)) - - assert data_filenames[split][0] is not None, "Internal Error: File not found for reading" - assert data_filenames[split][1] is not None, "Internal Error: File not found for reading" - src_data_iter = _read_text_iterator(data_filenames[split][0]) - tgt_data_iter = _read_text_iterator(data_filenames[split][1]) - - def _iter(src_data_iter, tgt_data_iter): - for item in zip(src_data_iter, tgt_data_iter): - yield item - - set_identifier = { - 'train': train_set, - 'valid': valid_set, - 'test': test_set, - } - - return _RawTextIterableDataset(DATASET_NAME, - SUPPORTED_DATASETS[task][language_pair[0]][set_identifier[split]]['NUM_LINES'], - _iter(src_data_iter, tgt_data_iter)) diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index fc2bc48024..d6b6d5c16e 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -36,7 +36,7 @@ def _setup_datasets(dataset_name, "tokenizer must be an instance of tuple with length two" "or None") - if dataset_name == 'Multi30k' or dataset_name == 'WMT14': + if dataset_name == 'WMT14': raw_datasets = experimental_raw.DATASETS[dataset_name](split=split, root=root, **kwargs) else: raw_datasets = raw.DATASETS[dataset_name](split=split, root=root, **kwargs) @@ -135,53 +135,17 @@ def get_vocab(self): return self.vocab -def Multi30k(task='task1', - language_pair=('de', 'en'), - train_set="train", - valid_set="val", - test_set="test_2016_flickr", - split=('train', 'valid', 'test'), - root='.data', - vocab=(None, None), - tokenizer=None): +def Multi30k( + language_pair=('de', 'en'), + split=('train', 'valid', 'test'), + root='.data', + vocab=(None, None), + tokenizer=None): """ Define translation datasets: Multi30k Separately returns train/valid/test datasets as a tuple - The available datasets include following: - - **Language pairs (task1)**: - - +-----+-----+-----+-----+-----+ - | |'en' |'cs' |'de' |'fr' | - +-----+-----+-----+-----+-----+ - |'en' | | x | x | x | - +-----+-----+-----+-----+-----+ - |'cs' | x | | x | x | - +-----+-----+-----+-----+-----+ - |'de' | x | x | | x | - +-----+-----+-----+-----+-----+ - |'fr' | x | x | x | | - +-----+-----+-----+-----+-----+ - - **Language pairs (task2)**: - - +-----+-----+-----+ - | |'en' |'de' | - +-----+-----+-----+ - |'en' | | x | - +-----+-----+-----+ - |'de' | x | | - +-----+-----+-----+ - - For additional details refer to source: https://github.com/multi30k/dataset - - Args: - task: Indicate the task language_pair: tuple or list containing src and tgt language - train_set: A string to identify train set. - valid_set: A string to identify validation set. - test_set: A string to identify test set. split: a string or tuple for the returned datasets, Default: ('train', 'valid', 'test') By default, all the three datasets (train, valid, test) are generated. Users could also choose any one or two of them, for example ('train', 'test') or @@ -208,11 +172,7 @@ def Multi30k(task='task1', >>> src_data, tgt_data = train_dataset[10] """ return _setup_datasets("Multi30k", split, root, vocab, tokenizer, - task=task, - language_pair=language_pair, - train_set=train_set, - valid_set=valid_set, - test_set=test_set) + language_pair=language_pair) def IWSLT2017(language_pair=('de', 'en'), diff --git a/torchtext/experimental/transforms.py b/torchtext/experimental/transforms.py index 3b542aeb45..aa37044d22 100644 --- a/torchtext/experimental/transforms.py +++ b/torchtext/experimental/transforms.py @@ -361,11 +361,11 @@ class VocabTransform(nn.Module): r"""Vocab transform Args: - vocab: an instance of torchtext.experimental.vocab.Vocab class. + vocab: an instance of torchtext.vocab.Vocab class. Example: >>> import torch - >>> from torchtext.experimental.vocab import vocab_from_file_object + >>> from torchtext.vocab import vocab_from_file_object >>> f = open('vocab.txt', 'r') >>> vocab_transform = VocabTransform(vocab_from_file_object(f)) >>> jit_vocab_transform = torch.jit.script(vocab_transform) diff --git a/torchtext/experimental/vocab.py b/torchtext/experimental/vocab.py deleted file mode 100644 index c69d26db97..0000000000 --- a/torchtext/experimental/vocab.py +++ /dev/null @@ -1,137 +0,0 @@ -import logging -from collections import Counter, OrderedDict -from torchtext.vocab import Vocab -from torchtext._torchtext import ( - Vocab as VocabPybind, - _load_vocab_from_file, - _build_vocab_from_text_file -) - -__all__ = [ - 'build_vocab_from_text_file', - 'load_vocab_from_file', - 'vocab', -] -logger = logging.getLogger(__name__) - - -def build_vocab_from_text_file(file_path, jited_tokenizer, min_freq=1, unk_token='', num_cpus=4): - r"""Create a `Vocab` object from a raw text file. - - The `file_path` can contain any raw text. This function applies a generic JITed tokenizer in - parallel to the text. - - Args: - file_object (FileObject): a file object to read data from. - jited_tokenizer (ScriptModule): a tokenizer that has been JITed using `torch.jit.script` - min_freq: The minimum frequency needed to include a token in the vocabulary. - Values less than 1 will be set to 1. Default: 1. - unk_token: The default unknown token to use. Default: ''. If not found in text file, it will be inserted to index 0. - num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. - - Returns: - torchtext.experimental.vocab.Vocab: a `Vocab` object. - - Examples: - >>> from torchtext.experimental.vocab import build_vocab_from_text_file - >>> from torchtext.experimental.transforms import basic_english_normalize - >>> tokenizer = basic_english_normalize() - >>> tokenizer = basic_english_normalize() - >>> jit_tokenizer = torch.jit.script(tokenizer) - >>> v = build_vocab_from_text_file('vocab.txt', jit_tokenizer) - """ - vocab_obj = _build_vocab_from_text_file(file_path, min_freq, num_cpus, jited_tokenizer) - if unk_token not in vocab_obj: - vocab_obj.insert_token(unk_token, 0) - return Vocab(vocab_obj) - - -def load_vocab_from_file(file_path, min_freq=1, unk_token='', num_cpus=4): - r"""Create a `Vocab` object from a text file. - The `file_path` should contain tokens separated by new lines. - Format for txt file: - - token1 - token2 - ... - token_n - - Args: - file_object (FileObject): a file like object to read data from. - min_freq: The minimum frequency needed to include a token in the vocabulary. - Values less than 1 will be set to 1. Default: 1. - unk_token: The default unknown token to use. Default: ''. If not found in vocab file, it will be inserted to index 0. - num_cpus (int): the number of cpus to use when loading the vectors from file. Default: 4. - - Returns: - torchtext.experimental.vocab.Vocab: a `Vocab` object. - - Examples: - >>> from torchtext.experimental.vocab import load_vocab_from_file - >>> v = load_vocab_from_file('vocab.txt') - """ - - vocab_obj = _load_vocab_from_file(file_path, min_freq, num_cpus) - if unk_token not in vocab_obj: - vocab_obj.insert_token(unk_token, 0) - return Vocab(vocab_obj) - - -def build_vocab_from_iterator(iterator, min_freq=1, unk_token=''): - """ - Build a Vocab from an iterator. - - Args: - iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. - min_freq: The minimum frequency needed to include a token in the vocabulary. - Values less than 1 will be set to 1. Default: 1. - unk_token: The default unknown token to use. Default: ''. - """ - - counter = Counter() - for tokens in iterator: - counter.update(tokens) - sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) - ordered_dict = OrderedDict(sorted_by_freq_tuples) - word_vocab = vocab(ordered_dict, min_freq=min_freq, unk_token=unk_token) - return word_vocab - - -def vocab(ordered_dict, min_freq=1, unk_token=''): - r"""Factory method for creating a vocab object which maps tokens to indices. - - Note that the ordering in which key value pairs were inserted in the `ordered_dict` will be respected when building the vocab. - Therefore if sorting by token frequency is important to the user, the `ordered_dict` should be created in a way to reflect this. - Additionally, the if the `unk_token` isn't found inside of the `ordered_dict`, it will be added to the end of the vocab. - - Args: - ordered_dict (collections.OrderedDict): object holding the frequencies of each token found in the data. - min_freq: The minimum frequency needed to include a token in the vocabulary. - Values less than 1 will be set to 1. Default: 1. - unk_token: The default unknown token to use. Default: ''. If not found in ordered_dict, it will be inserted at index 0. - - Raises: - ValueError: if a default `unk_token` isn't provided. - - Examples: - >>> from torchtext.experimental.vocab import vocab - >>> from collections import Counter, OrderedDict - >>> counter = Counter(["a", "a", "b", "b", "b"]) - >>> sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) - >>> ordered_dict = OrderedDict(sorted_by_freq_tuples) - >>> v1 = vocab(ordered_dict) - >>> tokens = ['e', 'd', 'c', 'b', 'a'] - >>> v2 = vocab(OrderedDict([(token, 1) for token in tokens])) - """ - - if not unk_token: - raise ValueError("A default unk token wasn't provided.") - - tokens = [] - for token, freq in ordered_dict.items(): - if freq >= min_freq: - tokens.append(token) - - if unk_token not in tokens: - tokens.insert(0, unk_token) - return Vocab(VocabPybind(tokens, None)) diff --git a/torchtext/experimental/vocab_factory.py b/torchtext/experimental/vocab_factory.py new file mode 100644 index 0000000000..bf39b87419 --- /dev/null +++ b/torchtext/experimental/vocab_factory.py @@ -0,0 +1,75 @@ +import torch +from torchtext.vocab import Vocab +from typing import Optional, Callable +from torchtext._torchtext import ( + _build_vocab_from_text_file, + _load_vocab_from_file, + _build_vocab_from_text_file_using_python_tokenizer, +) + +__all__ = [ + 'build_vocab_from_text_file', + 'load_vocab_from_file', +] + + +def build_vocab_from_text_file(file_path: str, tokenizer: Optional[Callable] = None, min_freq: int = 1, num_cpus: Optional[int] = 4) -> Vocab: + r"""Create a `Vocab` object from a raw text file. + The `file_path` can contain any raw text. This function applies a generic JITed tokenizer in + parallel to the text. + + Args: + file_object: A file object to read data from. + tokenizer: A python callable to split input sentence into tokens. It can also be a Jited Module. + By default, the function will do tokenization based on python split() function. + min_freq: The minimum frequency needed to include a token in the vocabulary. + num_cpus: the number of cpus to use when loading the vectors from file. It will be ignored when tokenizer is not torch scripted (JIT'd) + Returns: + torchtext.vocab.Vocab: a `Vocab` object. + Examples: + >>> from torchtext.vocab import build_vocab_from_text_file + >>> v = build_vocab_from_text_file('vocab.txt') # using python split function as tokenizer + >>> #using JIT'd tokenizer + >>> from torchtext.experimental.transforms import basic_english_normalize + >>> tokenizer = basic_english_normalize() + >>> tokenizer = basic_english_normalize() + >>> jit_tokenizer = torch.jit.script(tokenizer) + >>> v = build_vocab_from_text_file('vocab.txt', jit_tokenizer, num_cpus = 4) + """ + + if not tokenizer: + def tokenizer(x): + return x.split() + + if isinstance(tokenizer, torch.jit.ScriptModule) or isinstance(tokenizer, torch.jit.ScriptFunction): + vocab_obj = _build_vocab_from_text_file(file_path, min_freq, num_cpus, tokenizer) + else: + vocab_obj = _build_vocab_from_text_file_using_python_tokenizer(file_path, min_freq, tokenizer) + return Vocab(vocab_obj) + + +def load_vocab_from_file(file_path: str, min_freq: int = 1, num_cpus: int = 4) -> Vocab: + r"""Create a `Vocab` object from a text file. + The `file_path` should contain tokens separated by new lines. + Format for txt file: + + token1 + token2 + ... + token_n + + Args: + file_object: A file like object to read data from. + min_freq: The minimum frequency needed to include a token in the vocabulary. + num_cpus: the number of cpus to use when loading the vectors from file. + + Returns: + torchtext.vocab.Vocab: a `Vocab` object. + + Examples: + >>> from torchtext.vocab import load_vocab_from_file + >>> v = load_vocab_from_file('vocab.txt') + """ + + vocab_obj = _load_vocab_from_file(file_path, min_freq, num_cpus) + return Vocab(vocab_obj) diff --git a/torchtext/vocab.py b/torchtext/vocab.py index 07378c46a4..4ef634d3d4 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -8,13 +8,22 @@ from urllib.request import urlretrieve from tqdm import tqdm import tarfile -from typing import Optional, List, Dict -from torchtext._torchtext import Vocab as VocabPybind - +from typing import Dict, List, Optional, Iterable +from collections import Counter, OrderedDict +from torchtext._torchtext import ( + Vocab as VocabPybind, +) from .utils import reporthook logger = logging.getLogger(__name__) +__all__ = [ + 'build_vocab_from_iterator', + 'vocab', +] + +logger = logging.getLogger(__name__) + class Vocab(nn.Module): __jit_unused_properties__ = ["is_jitable"] @@ -75,7 +84,7 @@ def __getitem__(self, token: str) -> int: return self.vocab[token] @torch.jit.export - def set_default_index(self, index: int) -> None: + def set_default_index(self, index: Optional[int]) -> None: r""" Args: index: Value of default index. This index will be returned when OOV token is queried. @@ -90,17 +99,6 @@ def get_default_index(self) -> Optional[int]: """ return self.vocab.get_default_index() - @torch.jit.export - def reassign_token(self, token: str, index: int) -> None: - r""" - Args: - token: the token used to lookup the corresponding index. - index: the index corresponding to the associated token. - Raises: - RuntimeError: If `index` is not in range [0,Vocab.size()) or if `token` is not present in Vocab - """ - self.vocab.reassign_token(token, index) - @torch.jit.export def insert_token(self, token: str, index: int) -> None: r""" @@ -187,6 +185,96 @@ def __prepare_scriptable__(self): return self +def vocab(ordered_dict: Dict, min_freq: int = 1) -> Vocab: + r"""Factory method for creating a vocab object which maps tokens to indices. + + Note that the ordering in which key value pairs were inserted in the `ordered_dict` will be respected when building the vocab. + Therefore if sorting by token frequency is important to the user, the `ordered_dict` should be created in a way to reflect this. + + Args: + ordered_dict: Ordered Dictionary mapping tokens to their corresponding occurance frequencies. + min_freq: The minimum frequency needed to include a token in the vocabulary. + + Returns: + torchtext.vocab.Vocab: A `Vocab` object + + Examples: + >>> from torchtext.vocab import vocab + >>> from collections import Counter, OrderedDict + >>> counter = Counter(["a", "a", "b", "b", "b"]) + >>> sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) + >>> ordered_dict = OrderedDict(sorted_by_freq_tuples) + >>> v1 = vocab(ordered_dict) + >>> print(v1['a']) #prints 1 + >>> print(v1['out of vocab']) #raise RuntimeError since default index is not set + >>> tokens = ['e', 'd', 'c', 'b', 'a'] + >>> v2 = vocab(OrderedDict([(token, 1) for token in tokens])) + >>> #adding token and default index + >>> unk_token = '' + >>> default_index = -1 + >>> if unk_token not in v2: v2.insert_token(unk_token, 0) + >>> v2.set_default_index(default_index) + >>> print(v2['']) #prints 0 + >>> print(v2['out of vocab']) #prints -1 + >>> #make default index same as index of unk_token + >>> v2.set_default_index(v2[unk_token]) + >>> v2['out of vocab'] is v2[unk_token] #prints True + """ + + tokens = [] + for token, freq in ordered_dict.items(): + if freq >= min_freq: + tokens.append(token) + + return Vocab(VocabPybind(tokens, None)) + + +def build_vocab_from_iterator(iterator: Iterable, min_freq: int = 1, specials: Optional[List[str]] = None, special_first: bool = True) -> Vocab: + """ + Build a Vocab from an iterator. + + Args: + iterator: Iterator used to build Vocab. Must yield list or iterator of tokens. + min_freq: The minimum frequency needed to include a token in the vocabulary. + specials: Special symbols to add. The order of supplied tokens will be preserved. + special_first: Indicates whether to insert symbols at the beginning or at the end. + + + Returns: + torchtext.vocab.Vocab: A `Vocab` object + + Examples: + >>> #generating vocab from text file + >>> import io + >>> from torchtext.vocab import build_vocab_from_iterator + >>> def yield_tokens(file_path): + >>> with io.open(file_path, encoding = 'utf-8') as f: + >>> for line in f: + >>> yield line.strip().split() + >>> vocab = build_vocab_from_iterator(yield_tokens_batch(file_path), specials=[""]) + """ + + counter = Counter() + for tokens in iterator: + counter.update(tokens) + sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) + ordered_dict = OrderedDict(sorted_by_freq_tuples) + + if specials is not None: + for symbol in specials: + if symbol in ordered_dict: + del ordered_dict[symbol] + + if special_first: + specials = specials[::-1] + for symbol in specials: + ordered_dict.update({symbol: min_freq}) + ordered_dict.move_to_end(symbol, last=not special_first) + + word_vocab = vocab(ordered_dict, min_freq=min_freq) + return word_vocab + + def _infer_shape(f): num_lines, vector_dim = 0, None for line in f: From 0c55dd9ef931d50c3ff7700ba150f8776521c3f2 Mon Sep 17 00:00:00 2001 From: Parmeet Singh Bhatia Date: Mon, 24 May 2021 18:30:34 -0700 Subject: [PATCH 63/68] Adding API usage logging Summary: Adding API usage logging for Vocab module Reviewed By: colin2328 Differential Revision: D28585537 fbshipit-source-id: 38975b523fb597412fbcb18ef831bfb4834cb420 --- torchtext/vocab.py | 1 + 1 file changed, 1 insertion(+) diff --git a/torchtext/vocab.py b/torchtext/vocab.py index 4ef634d3d4..3535dd3c23 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -36,6 +36,7 @@ class Vocab(nn.Module): def __init__(self, vocab): super(Vocab, self).__init__() self.vocab = vocab + torch._C._log_api_usage_once(f"torchtext.{self.__class__.__name__}") @property def is_jitable(self): From e9d7593de60c04e1126969e3cd50f42ef3f5cc9c Mon Sep 17 00:00:00 2001 From: Vasilis Vryniotis Date: Tue, 25 May 2021 14:00:49 -0700 Subject: [PATCH 64/68] Import torchtext #1314 99557efd98dd0e74346975d75183dd8aa32eb37e Reviewed By: parmeet Differential Revision: D28683381 fbshipit-source-id: 7bfbf445dd512f0ce21c34096cf3f08332d90138 --- .circleci/config.yml | 4 +++- .circleci/config.yml.in | 4 +++- test/common/cache_utils.py | 7 +++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 32f99b26ff..b2c61d69f6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,7 +44,9 @@ commands: steps: - run: name: Generate CCI cache key - command: echo "$(date "+%D")" > .cachekey + command: + echo "$(date "+%D")" > .cachekey + cat cached_datasets_list.txt >> .cachekey - persist_to_workspace: root: . paths: diff --git a/.circleci/config.yml.in b/.circleci/config.yml.in index 3830d7f881..3c997d777c 100644 --- a/.circleci/config.yml.in +++ b/.circleci/config.yml.in @@ -44,7 +44,9 @@ commands: steps: - run: name: Generate CCI cache key - command: echo "$(date "+%D")" > .cachekey + command: + echo "$(date "+%D")" > .cachekey + cat cached_datasets_list.txt >> .cachekey - persist_to_workspace: root: . paths: diff --git a/test/common/cache_utils.py b/test/common/cache_utils.py index 404dbd0d24..16c62e7e35 100644 --- a/test/common/cache_utils.py +++ b/test/common/cache_utils.py @@ -9,11 +9,14 @@ def check_cache_status(): assert os.path.exists(CACHE_STATUS_FILE), "Cache status file does not exists" with open(CACHE_STATUS_FILE, 'r') as f: + missing_datasets = [] cache_status = json.load(f) for dataset_name in cache_status: for split in cache_status[dataset_name]: if cache_status[dataset_name][split]['status'] == "fail": - raise FileNotFoundError("Failing all raw dataset unit tests as cache is missing atleast one raw dataset") + missing_datasets.append(dataset_name + '_' + split) + if missing_datasets: + raise FileNotFoundError("Failing all raw dataset unit tests as cache is missing {} datasets".format(missing_datasets)) def generate_data_cache(): @@ -30,7 +33,7 @@ def generate_data_cache(): if dataset_name not in cache_status: cache_status[dataset_name] = {} try: - if dataset_name == "Multi30k" or dataset_name == 'WMT14': + if dataset_name == 'WMT14': _ = torchtext.experimental.datasets.raw.DATASETS[dataset_name](split=split) else: _ = torchtext.datasets.DATASETS[dataset_name](split=split) From c56bfbd5b74cf7f9b20f689510837b48ec125ba5 Mon Sep 17 00:00:00 2001 From: Moto Hira Date: Wed, 9 Jun 2021 10:21:32 -0700 Subject: [PATCH 65/68] Import torchtext #1325 57a1df3 Reviewed By: NicolasHug Differential Revision: D28994054 fbshipit-source-id: 4c679f56ef37b18f6d2acaaaed8518facbeaa41c --- README.rst | 23 ++++++++---- test/data/test_builtin_datasets.py | 35 +++---------------- .../datasets/language_modeling.py | 6 ++-- .../experimental/datasets/question_answer.py | 5 +-- .../experimental/datasets/sequence_tagging.py | 6 ++-- .../datasets/text_classification.py | 6 ++-- .../experimental/datasets/translation.py | 6 ++-- torchtext/vocab.py | 12 ++++--- 8 files changed, 47 insertions(+), 52 deletions(-) diff --git a/README.rst b/README.rst index 9369ba40cf..cd23d169aa 100644 --- a/README.rst +++ b/README.rst @@ -15,20 +15,22 @@ This repository consists of: * `torchtext.datasets `_: The raw text iterators for common NLP datasets * `torchtext.data `_: Some basic NLP building blocks (tokenizers, metrics, functionals etc.) * `torchtext.nn `_: NLP related modules +* `torchtext.vocab `_: Vocab and Vectors related classes and factory functions * `examples `_: Example NLP workflows with PyTorch and torchtext library. -Note: the legacy code discussed in `torchtext v0.7.0 release note `_ has been retired to `torchtext.legacy `_ folder. Those legacy code will not be maintained by the development team, and we plan to fully remove them in the future release. See `torchtext.legacy `_ folder for more details. +Note: The legacy code discussed in `torchtext v0.7.0 release note `_ has been retired to `torchtext.legacy `_ folder. Those legacy code will not be maintained by the development team, and we plan to fully remove them in the future release. See `torchtext.legacy `_ folder for more details. Installation ============ -We recommend Anaconda as Python package management system. Please refer to `pytorch.org `_ for the detail of PyTorch installation. The following is the corresponding ``torchtext`` versions and supported Python versions. +We recommend Anaconda as a Python package management system. Please refer to `pytorch.org `_ for the details of PyTorch installation. The following are the corresponding ``torchtext`` versions and supported Python versions. .. csv-table:: Version Compatibility :header: "PyTorch version", "torchtext version", "Supported Python version" :widths: 10, 10, 10 nightly build, master, 3.6+ + 1.9, 0.10, 3.6+ 1.8, 0.9, 3.6+ 1.7, 0.8, 3.6+ 1.6, 0.7, 3.6+ @@ -93,7 +95,7 @@ Datasets The datasets module currently contains: * Language modeling: WikiText2, WikiText103, PennTreebank, EnWik9 -* Machine translation: IWSLT2016, IWSLT2017 +* Machine translation: IWSLT2016, IWSLT2017, Multi30k * Sequence tagging (e.g. POS/NER): UDPOS, CoNLL2000Chunking * Question answering: SQuAD1, SQuAD2 * Text classification: AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, YelpReviewFull, YahooAnswers, AmazonReviewPolarity, AmazonReviewFull, IMDB @@ -113,7 +115,15 @@ For example, to access the raw text from the AG_NEWS dataset: >>> train_iter = AG_NEWS(split='train') >>> dataloader = DataLoader(train_iter, batch_size=8, shuffle=False) -A tutorial for the end-to-end text classification workflow can be found in `PyTorch tutorial `_ +Tutorials +========= + +To get started with torchtext, users may refer to the following tutorials available on PyTorch website. + +* `Text classification with AG_NEWS dataset `_ +* `Translation trained with Multi30k dataset using transformers and torchtext `_ +* `Language modeling using transforms and torchtext `_ + [Prototype] Experimental Code ============================= @@ -121,7 +131,6 @@ A tutorial for the end-to-end text classification workflow can be found in `PyTo We have re-written several building blocks under ``torchtext.experimental``: * `Transforms `_: some basic data processing building blocks -* `Vocabulary `_: a vocabulary to numericalize tokens * `Vectors `_: the vectors to convert tokens into tensors. These prototype building blocks in the experimental folder are available in the nightly release only. The nightly packages are accessible via Pip and Conda for Windows, Mac, and Linux. For example, Linux users can install the nightly wheels with the following command:: @@ -133,7 +142,7 @@ For more detailed instructions, please refer to `Install PyTorch `_. This is part of the work to revamp the torchtext library and the motivation has been discussed in `Issue #664 `_: +In the v0.9.0 release, we moved the following legacy code to `torchtext.legacy `_. This is part of the work to revamp the torchtext library and the motivation has been discussed in `Issue #664 `_: * ``torchtext.legacy.data.field`` * ``torchtext.legacy.data.batch`` @@ -144,6 +153,8 @@ In v0.9.0 release, we move the following legacy code to `torchtext.legacy `_ to help users switch to the torchtext datasets in ``v0.9.0`` release. For the users who still want the legacy components, they can add ``legacy`` to the import path. +In the v0.10.0 release, we retire the Vocab class to `torchtext.legacy `_. Users can still access the legacy Vocab via ``torchtext.legacy.vocab``. This class has been replaced by a Vocab module that is backed by efficient C++ implementation and provides common functional APIs for NLP workflows. + Disclaimer on Datasets ====================== diff --git a/test/data/test_builtin_datasets.py b/test/data/test_builtin_datasets.py index ce922c0a8f..7b16efa340 100644 --- a/test/data/test_builtin_datasets.py +++ b/test/data/test_builtin_datasets.py @@ -207,7 +207,6 @@ def test_next_method_dataset(self): def test_imdb(self): from torchtext.experimental.datasets import IMDB - from torchtext.legacy.vocab import Vocab # smoke test to ensure imdb works properly train_dataset, test_dataset = IMDB() self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], @@ -215,15 +214,7 @@ def test_imdb(self): self._helper_test_func(len(test_dataset), 25000, test_dataset[0][1][:10], [13, 125, 1051, 5, 246, 1652, 8, 277, 66, 20]) - # Test API with a vocab input object - old_vocab = train_dataset.get_vocab() - new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) - new_train_data, new_test_data = IMDB(vocab=new_vocab) - # Add test for the subset of the standard datasets - train_dataset = IMDB(split='train') - self._helper_test_func(len(train_dataset), 25000, train_dataset[0][1][:10], - [13, 1568, 13, 246, 35468, 43, 64, 398, 1135, 92]) train_iter, test_iter = torchtext.datasets.IMDB() self._helper_test_func(len(train_iter), 25000, next(train_iter)[1][:25], 'I rented I AM CURIOUS-YEL') self._helper_test_func(len(test_iter), 25000, next(test_iter)[1][:25], 'I love sci-fi and am will') @@ -241,8 +232,8 @@ def test_iwslt2017(self): de_vocab, en_vocab = train_dataset.get_vocab() def assert_nth_pair_is_equal(n, expected_sentence_pair): - de_sentence = [de_vocab.itos[index] for index in train_dataset[n][0]] - en_sentence = [en_vocab.itos[index] for index in train_dataset[n][1]] + de_sentence = [de_vocab.lookup_token(index) for index in train_dataset[n][0]] + en_sentence = [en_vocab.lookup_token(index) for index in train_dataset[n][1]] expected_de_sentence, expected_en_sentence = expected_sentence_pair @@ -267,8 +258,8 @@ def test_iwslt2016(self): de_vocab, en_vocab = train_dataset.get_vocab() def assert_nth_pair_is_equal(n, expected_sentence_pair): - de_sentence = [de_vocab.itos[index] for index in train_dataset[n][0]] - en_sentence = [en_vocab.itos[index] for index in train_dataset[n][1]] + de_sentence = [de_vocab.lookup_token(index) for index in train_dataset[n][0]] + en_sentence = [en_vocab.lookup_token(index) for index in train_dataset[n][1]] expected_de_sentence, expected_en_sentence = expected_sentence_pair self.assertEqual(de_sentence, expected_de_sentence) @@ -462,7 +453,6 @@ def test_conll_sequence_tagging(self): def test_squad1(self): from torchtext.experimental.datasets import SQuAD1 - from torchtext.legacy.vocab import Vocab # smoke test to ensure imdb works properly train_dataset, dev_dataset = SQuAD1() context, question, answers, ans_pos = train_dataset[100] @@ -472,16 +462,8 @@ def test_squad1(self): self._helper_test_func(len(dev_dataset), 10570, (question, ans_pos[0]), ([42, 27, 669, 7438, 17, 2, 1950, 3273, 17252, 389, 16], [45, 48])) - # Test API with a vocab input object - old_vocab = train_dataset.get_vocab() - new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) - new_train_data, new_test_data = SQuAD1(vocab=new_vocab) - # Add test for the subset of the standard datasets train_dataset = SQuAD1(split='train') - context, question, answers, ans_pos = train_dataset[100] - self._helper_test_func(len(train_dataset), 87599, (question[:5], ans_pos[0]), - ([7, 24, 86, 52, 2], [72, 72])) train_iter, dev_iter = torchtext.datasets.SQuAD1() self._helper_test_func(len(train_iter), 87599, next(train_iter)[0][:50], 'Architecturally, the school has a Catholic charact') @@ -491,7 +473,6 @@ def test_squad1(self): def test_squad2(self): from torchtext.experimental.datasets import SQuAD2 - from torchtext.legacy.vocab import Vocab # smoke test to ensure imdb works properly train_dataset, dev_dataset = SQuAD2() context, question, answers, ans_pos = train_dataset[200] @@ -501,16 +482,8 @@ def test_squad2(self): self._helper_test_func(len(dev_dataset), 11873, (question, ans_pos[0]), ([41, 29, 2, 66, 17016, 30, 0, 1955, 16], [40, 46])) - # Test API with a vocab input object - old_vocab = train_dataset.get_vocab() - new_vocab = Vocab(counter=old_vocab.freqs, max_size=2500) - new_train_data, new_test_data = SQuAD2(vocab=new_vocab) - # Add test for the subset of the standard datasets train_dataset = SQuAD2(split='train') - context, question, answers, ans_pos = train_dataset[200] - self._helper_test_func(len(train_dataset), 130319, (question[:5], ans_pos[0]), - ([84, 50, 1421, 12, 5439], [9, 9])) train_iter, dev_iter = torchtext.datasets.SQuAD2() self._helper_test_func(len(train_iter), 130319, next(train_iter)[0][:50], 'Beyoncé Giselle Knowles-Carter (/biːˈjɒnseɪ/ bee-Y') diff --git a/torchtext/experimental/datasets/language_modeling.py b/torchtext/experimental/datasets/language_modeling.py index f94af3b03a..4cdebab679 100644 --- a/torchtext/experimental/datasets/language_modeling.py +++ b/torchtext/experimental/datasets/language_modeling.py @@ -1,7 +1,7 @@ import torch import logging from torchtext.data.utils import get_tokenizer -from torchtext.legacy.vocab import build_vocab_from_iterator +from torchtext.vocab import build_vocab_from_iterator from torchtext import datasets as raw from torchtext.experimental.datasets import raw as experimental_raw from torchtext.data.datasets_utils import _check_default_set @@ -15,7 +15,9 @@ def apply_transforms(data): for line in data: tokens = transforms(line) yield tokens - return build_vocab_from_iterator(apply_transforms(data), len(data)) + vocab = build_vocab_from_iterator(apply_transforms(data), specials=['', '']) + vocab.set_default_index(vocab['']) + return vocab class LanguageModelingDataset(torch.utils.data.Dataset): diff --git a/torchtext/experimental/datasets/question_answer.py b/torchtext/experimental/datasets/question_answer.py index 6c6d7bb194..88cece2fe8 100644 --- a/torchtext/experimental/datasets/question_answer.py +++ b/torchtext/experimental/datasets/question_answer.py @@ -1,7 +1,7 @@ import torch import logging from torchtext.data.utils import get_tokenizer -from torchtext.legacy.vocab import build_vocab_from_iterator +from torchtext.vocab import build_vocab_from_iterator from torchtext import datasets as raw from torchtext.data.datasets_utils import _check_default_set from torchtext.data.datasets_utils import _wrap_datasets @@ -81,7 +81,8 @@ def apply_transform(data): tok_ans += text_transform(item) yield text_transform(_context) + text_transform(_question) + tok_ans logger_.info('Building Vocab based on train data') - vocab = build_vocab_from_iterator(apply_transform(raw_data['train']), len(raw_data['train'])) + vocab = build_vocab_from_iterator(apply_transform(raw_data['train']), specials=['', '']) + vocab.set_default_index(vocab['']) logger_.info('Vocab has %d entries', len(vocab)) text_transform = sequential_transforms(text_transform, vocab_func(vocab), totensor(dtype=torch.long)) transforms = {'context': text_transform, 'question': text_transform, diff --git a/torchtext/experimental/datasets/sequence_tagging.py b/torchtext/experimental/datasets/sequence_tagging.py index f33e8e265f..d8540224be 100644 --- a/torchtext/experimental/datasets/sequence_tagging.py +++ b/torchtext/experimental/datasets/sequence_tagging.py @@ -3,7 +3,7 @@ from torchtext.data.datasets_utils import _check_default_set from torchtext.data.datasets_utils import _wrap_datasets from torchtext import datasets as raw -from torchtext.legacy.vocab import build_vocab_from_iterator +from torchtext.vocab import build_vocab_from_iterator from torchtext.experimental.functional import ( vocab_func, totensor, @@ -22,7 +22,9 @@ def build_vocab(data): for idx, col in enumerate(line): data_list[idx].append(col) for it in data_list: - vocabs.append(build_vocab_from_iterator(it, len(it))) + vocab = build_vocab_from_iterator(it, specials=['', '']) + vocab.set_default_index(vocab['']) + vocabs.append(vocab) return vocabs diff --git a/torchtext/experimental/datasets/text_classification.py b/torchtext/experimental/datasets/text_classification.py index 4a5b4d670c..18a8314364 100644 --- a/torchtext/experimental/datasets/text_classification.py +++ b/torchtext/experimental/datasets/text_classification.py @@ -1,7 +1,7 @@ import torch import logging from torchtext.data.utils import get_tokenizer -from torchtext.legacy.vocab import build_vocab_from_iterator +from torchtext.vocab import build_vocab_from_iterator from torchtext import datasets as raw from torchtext.data.datasets_utils import _check_default_set from torchtext.data.datasets_utils import _wrap_datasets @@ -19,7 +19,9 @@ def build_vocab(data, transforms): def apply_transforms(data): for _, line in data: yield transforms(line) - return build_vocab_from_iterator(apply_transforms(data), len(data)) + vocab = build_vocab_from_iterator(apply_transforms(data), specials=['', '']) + vocab.set_default_index(vocab['']) + return vocab class TextClassificationDataset(torch.utils.data.Dataset): diff --git a/torchtext/experimental/datasets/translation.py b/torchtext/experimental/datasets/translation.py index d6b6d5c16e..aee7c0baa5 100644 --- a/torchtext/experimental/datasets/translation.py +++ b/torchtext/experimental/datasets/translation.py @@ -4,7 +4,7 @@ from torchtext.data.datasets_utils import _wrap_datasets from torchtext import datasets as raw from torchtext.experimental.datasets import raw as experimental_raw -from torchtext.legacy.vocab import Vocab, build_vocab_from_iterator +from torchtext.vocab import Vocab, build_vocab_from_iterator from torchtext.data.utils import get_tokenizer from ..functional import vocab_func, totensor, sequential_transforms @@ -15,7 +15,9 @@ def build_vocab(data, transforms, index): def apply_transforms(data): for line in data: yield transforms(line[index]) - return build_vocab_from_iterator(apply_transforms(data), len(data)) + vocab = build_vocab_from_iterator(apply_transforms(data), specials=['', '']) + vocab.set_default_index(vocab['']) + return vocab def _setup_datasets(dataset_name, diff --git a/torchtext/vocab.py b/torchtext/vocab.py index 3535dd3c23..995e301869 100755 --- a/torchtext/vocab.py +++ b/torchtext/vocab.py @@ -258,14 +258,16 @@ def build_vocab_from_iterator(iterator: Iterable, min_freq: int = 1, specials: O counter = Counter() for tokens in iterator: counter.update(tokens) - sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[1], reverse=True) - ordered_dict = OrderedDict(sorted_by_freq_tuples) if specials is not None: - for symbol in specials: - if symbol in ordered_dict: - del ordered_dict[symbol] + for tok in specials: + del counter[tok] + sorted_by_freq_tuples = sorted(counter.items(), key=lambda x: x[0]) + sorted_by_freq_tuples.sort(key=lambda x: x[1], reverse=True) + ordered_dict = OrderedDict(sorted_by_freq_tuples) + + if specials is not None: if special_first: specials = specials[::-1] for symbol in specials: From 625c11d10a4a8da9e7e0e312c92ddab66548899b Mon Sep 17 00:00:00 2001 From: Moto Hira Date: Tue, 15 Jun 2021 04:50:20 -0700 Subject: [PATCH 66/68] Import torchtext #1328 ca514f6 Summary: Import torchtext #1328 ca514f6 Reviewed By: NicolasHug Differential Revision: D29120370 fbshipit-source-id: 229586f3470bd61bfb2f6a390d79e45d4eae3b4d --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 37f1777fc3..d22e31d207 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.10.0a0 +0.11.0a0 From 881641121f281f86235b3d6e1b7537b7731288c5 Mon Sep 17 00:00:00 2001 From: Heitor Schueroff Date: Mon, 21 Jun 2021 21:40:24 -0400 Subject: [PATCH 67/68] up the priority of numpy array comparisons in self.assertEqual (#59067) (#1340) --- test/legacy/test_vocab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/legacy/test_vocab.py b/test/legacy/test_vocab.py index 00c2027d37..083a738483 100644 --- a/test/legacy/test_vocab.py +++ b/test/legacy/test_vocab.py @@ -88,7 +88,7 @@ def test_vocab_set_vectors(self): expected_vectors = np.array([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.1, 0.2], [0.5, 0.6], [0.3, 0.4]]) - self.assertEqual(v.vectors, expected_vectors) + self.assertEqual(v.vectors, expected_vectors, exact_dtype=False) def test_errors(self): c = Counter({'hello': 4, 'world': 3, 'ᑌᑎIᑕOᗪᕮ_Tᕮ᙭T': 5, 'freq_too_low': 2}) From 23b5122c880c2adaa03aa2344a8ba7cc3200ceb0 Mon Sep 17 00:00:00 2001 From: Guanheng Zhang Date: Wed, 25 Mar 2020 08:01:07 -0700 Subject: [PATCH 68/68] include pytorch 1.5.0-rc1 for CI test --- .circleci/cached_datasets_list.txt | 21 +++++++++++++++++++++ .travis.yml | 23 ----------------------- test/asset/glove.6B.zip | Bin 0 -> 3074 bytes test/asset/glove.840B.300d.zip | Bin 0 -> 98661 bytes test/asset/vocab_raw_text_test.txt | 3 +++ test/asset/vocab_test.txt | 7 +++++++ test/asset/vocab_test2.txt | 29 +++++++++++++++++++++++++++++ third_party/CMakeLists.txt | 12 ++++++++++++ third_party/double-conversion | 1 + third_party/re2 | 1 + third_party/sentencepiece | 1 + 11 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 .circleci/cached_datasets_list.txt delete mode 100644 .travis.yml create mode 100644 test/asset/glove.6B.zip create mode 100644 test/asset/glove.840B.300d.zip create mode 100644 test/asset/vocab_raw_text_test.txt create mode 100644 test/asset/vocab_test.txt create mode 100644 test/asset/vocab_test2.txt create mode 100644 third_party/CMakeLists.txt create mode 160000 third_party/double-conversion create mode 160000 third_party/re2 create mode 160000 third_party/sentencepiece diff --git a/.circleci/cached_datasets_list.txt b/.circleci/cached_datasets_list.txt new file mode 100644 index 0000000000..c345588868 --- /dev/null +++ b/.circleci/cached_datasets_list.txt @@ -0,0 +1,21 @@ +IMDB +AG_NEWS +SogouNews +DBpedia +YelpReviewPolarity +YelpReviewFull +YahooAnswers +AmazonReviewPolarity +AmazonReviewFull +UDPOS +CoNLL2000Chunking +Multi30k +IWSLT2016 +IWSLT2017 +WMT14 +WikiText2 +WikiText103 +PennTreebank +SQuAD1 +SQuAD2 +EnWik9 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 83f69ea383..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -dist: trusty - -language: python - -cache: - directories: - - /home/travis/download - - /home/travis/.cache/pip - -# This matrix tests that the code works on Python 3.5, -# 3.6 (same versions as PyTorch CI), and passes lint. -matrix: - fast_finish: true - include: - - env: PYTHON_VERSION="3.6" RUN_FLAKE8="true" SKIP_TESTS="true" - sudo: required - -notifications: - email: false - -install: source build_tools/travis/install.sh -script: bash build_tools/travis/test_script.sh -after_success: source build_tools/travis/after_success.sh diff --git a/test/asset/glove.6B.zip b/test/asset/glove.6B.zip new file mode 100644 index 0000000000000000000000000000000000000000..bcea2b907d369a2e07541db189d87c63ea11aa2b GIT binary patch literal 3074 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

      ^c2&;wluS)dyZrDRE$&D24amX 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 AWdHyG literal 0 HcmV?d00001 diff --git a/test/asset/vocab_raw_text_test.txt b/test/asset/vocab_raw_text_test.txt new file mode 100644 index 0000000000..8b2f1bb0e7 --- /dev/null +++ b/test/asset/vocab_raw_text_test.txt @@ -0,0 +1,3 @@ +Fears for T N pension after talks Unions +representing workers at Turner Newall say they are 'disappointed' +after talks with stricken parent firm Federal Mogul. diff --git a/test/asset/vocab_test.txt b/test/asset/vocab_test.txt new file mode 100644 index 0000000000..389d543a10 --- /dev/null +++ b/test/asset/vocab_test.txt @@ -0,0 +1,7 @@ +b +a +c +a +b +a +c \ No newline at end of file diff --git a/test/asset/vocab_test2.txt b/test/asset/vocab_test2.txt new file mode 100644 index 0000000000..e9b74f2d86 --- /dev/null +++ b/test/asset/vocab_test2.txt @@ -0,0 +1,29 @@ + + +. +the +, +to +a +of +in +and +s +on +for +#39 +( +) +- +' +that +with +as +at +is +its +new +by +it +said +reuters diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt new file mode 100644 index 0000000000..16dd0e192f --- /dev/null +++ b/third_party/CMakeLists.txt @@ -0,0 +1,12 @@ +# Old enough to support Ubuntu Xenial. +cmake_minimum_required(VERSION 3.5.1) + +if(POLICY CMP0091) + cmake_policy(SET CMP0091 NEW) +endif() + +project(thirdparty CXX) +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + +add_subdirectory(re2) +add_subdirectory(double-conversion) diff --git a/third_party/double-conversion b/third_party/double-conversion new file mode 160000 index 0000000000..b1d531bfb1 --- /dev/null +++ b/third_party/double-conversion @@ -0,0 +1 @@ +Subproject commit b1d531bfb130e7149ffe24bb0f1c5c01f20c3a5f diff --git a/third_party/re2 b/third_party/re2 new file mode 160000 index 0000000000..2b25567a8e --- /dev/null +++ b/third_party/re2 @@ -0,0 +1 @@ +Subproject commit 2b25567a8ee3b6e97c3cd05d616f296756c52759 diff --git a/third_party/sentencepiece b/third_party/sentencepiece new file mode 160000 index 0000000000..e8a84a16d1 --- /dev/null +++ b/third_party/sentencepiece @@ -0,0 +1 @@ +Subproject commit e8a84a16d13e8bf92892a1cd92e4de3b0d0321fd

      ogE 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 z�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 z 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 z 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 z

      C{Id0wy`dzY*sT4G3gpQT?qXN)Q4V%V+&g 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 z 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 sVX^~ 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