Add files using upload-large-folder tool
Browse files- data/fairseq/scripts/__init__.py +0 -0
- data/fairseq/scripts/average_checkpoints.py +176 -0
- data/fairseq/scripts/build_sym_alignment.py +97 -0
- data/fairseq/scripts/check_installation.py +36 -0
- data/fairseq/scripts/compare_namespaces.py +46 -0
- data/fairseq/scripts/compound_split_bleu.sh +20 -0
- data/fairseq/scripts/constraints/extract.py +90 -0
- data/fairseq/scripts/convert_dictionary.lua +34 -0
- data/fairseq/scripts/convert_model.lua +108 -0
- data/fairseq/scripts/count_docs.py +58 -0
- data/fairseq/scripts/read_binarized.py +48 -0
- data/fairseq/scripts/rm_pt.py +141 -0
- data/fairseq/scripts/sacrebleu.sh +27 -0
- data/fairseq/scripts/shard_docs.py +54 -0
- data/fairseq/scripts/split_train_valid_docs.py +86 -0
- data/fairseq/scripts/spm_decode.py +53 -0
- data/fairseq/scripts/spm_encode.py +119 -0
- data/fairseq/scripts/spm_train.py +16 -0
- data/fairseq/scripts/test_fsdp.sh +24 -0
- data/fairseq/setup.py +257 -0
data/fairseq/scripts/__init__.py
ADDED
|
File without changes
|
data/fairseq/scripts/average_checkpoints.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the MIT license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
import argparse
|
| 8 |
+
import collections
|
| 9 |
+
import os
|
| 10 |
+
import re
|
| 11 |
+
|
| 12 |
+
import torch
|
| 13 |
+
|
| 14 |
+
from fairseq.file_io import PathManager
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def average_checkpoints(inputs):
|
| 18 |
+
"""Loads checkpoints from inputs and returns a model with averaged weights.
|
| 19 |
+
|
| 20 |
+
Args:
|
| 21 |
+
inputs: An iterable of string paths of checkpoints to load from.
|
| 22 |
+
|
| 23 |
+
Returns:
|
| 24 |
+
A dict of string keys mapping to various values. The 'model' key
|
| 25 |
+
from the returned dict should correspond to an OrderedDict mapping
|
| 26 |
+
string parameter names to torch Tensors.
|
| 27 |
+
"""
|
| 28 |
+
params_dict = collections.OrderedDict()
|
| 29 |
+
params_keys = None
|
| 30 |
+
new_state = None
|
| 31 |
+
num_models = len(inputs)
|
| 32 |
+
|
| 33 |
+
for fpath in inputs:
|
| 34 |
+
with PathManager.open(fpath, "rb") as f:
|
| 35 |
+
state = torch.load(
|
| 36 |
+
f,
|
| 37 |
+
map_location=(
|
| 38 |
+
lambda s, _: torch.serialization.default_restore_location(s, "cpu")
|
| 39 |
+
),
|
| 40 |
+
)
|
| 41 |
+
# Copies over the settings from the first checkpoint
|
| 42 |
+
if new_state is None:
|
| 43 |
+
new_state = state
|
| 44 |
+
|
| 45 |
+
model_params = state["model"]
|
| 46 |
+
|
| 47 |
+
model_params_keys = list(model_params.keys())
|
| 48 |
+
if params_keys is None:
|
| 49 |
+
params_keys = model_params_keys
|
| 50 |
+
elif params_keys != model_params_keys:
|
| 51 |
+
raise KeyError(
|
| 52 |
+
"For checkpoint {}, expected list of params: {}, "
|
| 53 |
+
"but found: {}".format(f, params_keys, model_params_keys)
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
for k in params_keys:
|
| 57 |
+
p = model_params[k]
|
| 58 |
+
if isinstance(p, torch.HalfTensor):
|
| 59 |
+
p = p.float()
|
| 60 |
+
if k not in params_dict:
|
| 61 |
+
params_dict[k] = p.clone()
|
| 62 |
+
# NOTE: clone() is needed in case of p is a shared parameter
|
| 63 |
+
else:
|
| 64 |
+
params_dict[k] += p
|
| 65 |
+
|
| 66 |
+
averaged_params = collections.OrderedDict()
|
| 67 |
+
for k, v in params_dict.items():
|
| 68 |
+
averaged_params[k] = v
|
| 69 |
+
if averaged_params[k].is_floating_point():
|
| 70 |
+
averaged_params[k].div_(num_models)
|
| 71 |
+
else:
|
| 72 |
+
averaged_params[k] //= num_models
|
| 73 |
+
new_state["model"] = averaged_params
|
| 74 |
+
return new_state
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def last_n_checkpoints(paths, n, update_based, upper_bound=None):
|
| 78 |
+
assert len(paths) == 1
|
| 79 |
+
path = paths[0]
|
| 80 |
+
if update_based:
|
| 81 |
+
pt_regexp = re.compile(r"checkpoint_\d+_(\d+)\.pt")
|
| 82 |
+
else:
|
| 83 |
+
pt_regexp = re.compile(r"checkpoint(\d+)\.pt")
|
| 84 |
+
files = PathManager.ls(path)
|
| 85 |
+
|
| 86 |
+
entries = []
|
| 87 |
+
for f in files:
|
| 88 |
+
m = pt_regexp.fullmatch(f)
|
| 89 |
+
if m is not None:
|
| 90 |
+
sort_key = int(m.group(1))
|
| 91 |
+
if upper_bound is None or sort_key <= upper_bound:
|
| 92 |
+
entries.append((sort_key, m.group(0)))
|
| 93 |
+
if len(entries) < n:
|
| 94 |
+
raise Exception(
|
| 95 |
+
"Found {} checkpoint files but need at least {}", len(entries), n
|
| 96 |
+
)
|
| 97 |
+
return [os.path.join(path, x[1]) for x in sorted(entries, reverse=True)[:n]]
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def main():
|
| 101 |
+
parser = argparse.ArgumentParser(
|
| 102 |
+
description="Tool to average the params of input checkpoints to "
|
| 103 |
+
"produce a new checkpoint",
|
| 104 |
+
)
|
| 105 |
+
# fmt: off
|
| 106 |
+
parser.add_argument('--inputs', required=True, nargs='+',
|
| 107 |
+
help='Input checkpoint file paths.')
|
| 108 |
+
parser.add_argument('--output', required=True, metavar='FILE',
|
| 109 |
+
help='Write the new checkpoint containing the averaged weights to this path.')
|
| 110 |
+
num_group = parser.add_mutually_exclusive_group()
|
| 111 |
+
num_group.add_argument('--num-epoch-checkpoints', type=int,
|
| 112 |
+
help='if set, will try to find checkpoints with names checkpoint_xx.pt in the '
|
| 113 |
+
'path specified by input, and average last this many of them.')
|
| 114 |
+
num_group.add_argument('--num-update-checkpoints', type=int,
|
| 115 |
+
help='if set, will try to find checkpoints with names checkpoint_ee_xx.pt in the path specified by'
|
| 116 |
+
' input, and average last this many of them.')
|
| 117 |
+
num_group.add_argument('--num-best-checkpoints', type=int, default=0,
|
| 118 |
+
help='if set, will try to find checkpoints with names checkpoint_best_ee_xx.pt in the path specified by'
|
| 119 |
+
' input, and average last this many of them.')
|
| 120 |
+
parser.add_argument('--checkpoint-upper-bound', type=int,
|
| 121 |
+
help='when using --num-epoch-checkpoints, this will set an upper bound on which epoch to use, '
|
| 122 |
+
'when using --num-update-checkpoints, this will set an upper bound on which update to use'
|
| 123 |
+
'e.g., with --num-epoch-checkpoints=10 --checkpoint-upper-bound=50, checkpoints 41-50 would be'
|
| 124 |
+
' averaged.'
|
| 125 |
+
'e.g., with --num-update-checkpoints=10 --checkpoint-upper-bound=50000, checkpoints 40500-50000 would'
|
| 126 |
+
' be averaged assuming --save-interval-updates 500'
|
| 127 |
+
)
|
| 128 |
+
# fmt: on
|
| 129 |
+
args = parser.parse_args()
|
| 130 |
+
print(args)
|
| 131 |
+
|
| 132 |
+
num = None
|
| 133 |
+
is_update_based = False
|
| 134 |
+
if args.num_update_checkpoints is not None:
|
| 135 |
+
num = args.num_update_checkpoints
|
| 136 |
+
is_update_based = True
|
| 137 |
+
elif args.num_epoch_checkpoints is not None:
|
| 138 |
+
num = args.num_epoch_checkpoints
|
| 139 |
+
|
| 140 |
+
assert args.checkpoint_upper_bound is None or (
|
| 141 |
+
args.num_epoch_checkpoints is not None
|
| 142 |
+
or args.num_update_checkpoints is not None
|
| 143 |
+
), "--checkpoint-upper-bound requires --num-epoch-checkpoints or --num-update-checkpoints"
|
| 144 |
+
assert (
|
| 145 |
+
args.num_epoch_checkpoints is None or args.num_update_checkpoints is None
|
| 146 |
+
), "Cannot combine --num-epoch-checkpoints and --num-update-checkpoints"
|
| 147 |
+
|
| 148 |
+
if num is not None:
|
| 149 |
+
args.inputs = last_n_checkpoints(
|
| 150 |
+
args.inputs,
|
| 151 |
+
num,
|
| 152 |
+
is_update_based,
|
| 153 |
+
upper_bound=args.checkpoint_upper_bound,
|
| 154 |
+
)
|
| 155 |
+
print("averaging checkpoints: ", args.inputs)
|
| 156 |
+
|
| 157 |
+
if args.num_best_checkpoints > 0:
|
| 158 |
+
args.inputs = list(
|
| 159 |
+
sorted(
|
| 160 |
+
args.inputs,
|
| 161 |
+
key=lambda x: float(
|
| 162 |
+
os.path.basename(x).split("_")[-1].replace(".pt", "")
|
| 163 |
+
),
|
| 164 |
+
)
|
| 165 |
+
)
|
| 166 |
+
args.inputs = args.inputs[: args.num_best_checkpoints]
|
| 167 |
+
for path in args.inputs:
|
| 168 |
+
print(os.path.basename(path))
|
| 169 |
+
new_state = average_checkpoints(args.inputs)
|
| 170 |
+
with PathManager.open(args.output, "wb") as f:
|
| 171 |
+
torch.save(new_state, f)
|
| 172 |
+
print("Finished writing averaged checkpoint to {}".format(args.output))
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
if __name__ == "__main__":
|
| 176 |
+
main()
|
data/fairseq/scripts/build_sym_alignment.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 2 |
+
#
|
| 3 |
+
# This source code is licensed under the MIT license found in the
|
| 4 |
+
# LICENSE file in the root directory of this source tree.
|
| 5 |
+
"""
|
| 6 |
+
Use this script in order to build symmetric alignments for your translation
|
| 7 |
+
dataset.
|
| 8 |
+
This script depends on fast_align and mosesdecoder tools. You will need to
|
| 9 |
+
build those before running the script.
|
| 10 |
+
fast_align:
|
| 11 |
+
github: http://github.com/clab/fast_align
|
| 12 |
+
instructions: follow the instructions in README.md
|
| 13 |
+
mosesdecoder:
|
| 14 |
+
github: http://github.com/moses-smt/mosesdecoder
|
| 15 |
+
instructions: http://www.statmt.org/moses/?n=Development.GetStarted
|
| 16 |
+
The script produces the following files under --output_dir:
|
| 17 |
+
text.joined - concatenation of lines from the source_file and the
|
| 18 |
+
target_file.
|
| 19 |
+
align.forward - forward pass of fast_align.
|
| 20 |
+
align.backward - backward pass of fast_align.
|
| 21 |
+
aligned.sym_heuristic - symmetrized alignment.
|
| 22 |
+
"""
|
| 23 |
+
|
| 24 |
+
import argparse
|
| 25 |
+
import os
|
| 26 |
+
from itertools import zip_longest
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def main():
|
| 30 |
+
parser = argparse.ArgumentParser(description="symmetric alignment builer")
|
| 31 |
+
# fmt: off
|
| 32 |
+
parser.add_argument('--fast_align_dir',
|
| 33 |
+
help='path to fast_align build directory')
|
| 34 |
+
parser.add_argument('--mosesdecoder_dir',
|
| 35 |
+
help='path to mosesdecoder root directory')
|
| 36 |
+
parser.add_argument('--sym_heuristic',
|
| 37 |
+
help='heuristic to use for symmetrization',
|
| 38 |
+
default='grow-diag-final-and')
|
| 39 |
+
parser.add_argument('--source_file',
|
| 40 |
+
help='path to a file with sentences '
|
| 41 |
+
'in the source language')
|
| 42 |
+
parser.add_argument('--target_file',
|
| 43 |
+
help='path to a file with sentences '
|
| 44 |
+
'in the target language')
|
| 45 |
+
parser.add_argument('--output_dir',
|
| 46 |
+
help='output directory')
|
| 47 |
+
# fmt: on
|
| 48 |
+
args = parser.parse_args()
|
| 49 |
+
|
| 50 |
+
fast_align_bin = os.path.join(args.fast_align_dir, "fast_align")
|
| 51 |
+
symal_bin = os.path.join(args.mosesdecoder_dir, "bin", "symal")
|
| 52 |
+
sym_fast_align_bin = os.path.join(
|
| 53 |
+
args.mosesdecoder_dir, "scripts", "ems", "support", "symmetrize-fast-align.perl"
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
# create joined file
|
| 57 |
+
joined_file = os.path.join(args.output_dir, "text.joined")
|
| 58 |
+
with open(args.source_file, "r", encoding="utf-8") as src, open(
|
| 59 |
+
args.target_file, "r", encoding="utf-8"
|
| 60 |
+
) as tgt:
|
| 61 |
+
with open(joined_file, "w", encoding="utf-8") as joined:
|
| 62 |
+
for s, t in zip_longest(src, tgt):
|
| 63 |
+
print("{} ||| {}".format(s.strip(), t.strip()), file=joined)
|
| 64 |
+
|
| 65 |
+
bwd_align_file = os.path.join(args.output_dir, "align.backward")
|
| 66 |
+
|
| 67 |
+
# run forward alignment
|
| 68 |
+
fwd_align_file = os.path.join(args.output_dir, "align.forward")
|
| 69 |
+
fwd_fast_align_cmd = "{FASTALIGN} -i {JOINED} -d -o -v > {FWD}".format(
|
| 70 |
+
FASTALIGN=fast_align_bin, JOINED=joined_file, FWD=fwd_align_file
|
| 71 |
+
)
|
| 72 |
+
assert os.system(fwd_fast_align_cmd) == 0
|
| 73 |
+
|
| 74 |
+
# run backward alignment
|
| 75 |
+
bwd_align_file = os.path.join(args.output_dir, "align.backward")
|
| 76 |
+
bwd_fast_align_cmd = "{FASTALIGN} -i {JOINED} -d -o -v -r > {BWD}".format(
|
| 77 |
+
FASTALIGN=fast_align_bin, JOINED=joined_file, BWD=bwd_align_file
|
| 78 |
+
)
|
| 79 |
+
assert os.system(bwd_fast_align_cmd) == 0
|
| 80 |
+
|
| 81 |
+
# run symmetrization
|
| 82 |
+
sym_out_file = os.path.join(args.output_dir, "aligned")
|
| 83 |
+
sym_cmd = "{SYMFASTALIGN} {FWD} {BWD} {SRC} {TGT} {OUT} {HEURISTIC} {SYMAL}".format(
|
| 84 |
+
SYMFASTALIGN=sym_fast_align_bin,
|
| 85 |
+
FWD=fwd_align_file,
|
| 86 |
+
BWD=bwd_align_file,
|
| 87 |
+
SRC=args.source_file,
|
| 88 |
+
TGT=args.target_file,
|
| 89 |
+
OUT=sym_out_file,
|
| 90 |
+
HEURISTIC=args.sym_heuristic,
|
| 91 |
+
SYMAL=symal_bin,
|
| 92 |
+
)
|
| 93 |
+
assert os.system(sym_cmd) == 0
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
if __name__ == "__main__":
|
| 97 |
+
main()
|
data/fairseq/scripts/check_installation.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
cwd = Path(".").resolve()
|
| 5 |
+
print("running 'check_installation.py' from:", cwd)
|
| 6 |
+
|
| 7 |
+
# Old versions of numpy/torch can prevent loading the .so files
|
| 8 |
+
import torch
|
| 9 |
+
|
| 10 |
+
print("torch:", torch.__version__)
|
| 11 |
+
import numpy
|
| 12 |
+
|
| 13 |
+
print("numpy:", numpy.__version__)
|
| 14 |
+
|
| 15 |
+
import fairseq
|
| 16 |
+
|
| 17 |
+
print("Fairseq installed at:", fairseq.__file__)
|
| 18 |
+
import fairseq.criterions
|
| 19 |
+
import fairseq.dataclass.configs
|
| 20 |
+
|
| 21 |
+
import _imp
|
| 22 |
+
|
| 23 |
+
print("Should load following .so suffixes:", _imp.extension_suffixes())
|
| 24 |
+
|
| 25 |
+
so_files = list(Path(fairseq.__file__).parent.glob("*.so"))
|
| 26 |
+
so_files.extend(Path(fairseq.__file__).parent.glob("data/*.so"))
|
| 27 |
+
print("Found following .so files:")
|
| 28 |
+
for so_file in so_files:
|
| 29 |
+
print(f"- {so_file}")
|
| 30 |
+
|
| 31 |
+
from fairseq import libbleu
|
| 32 |
+
|
| 33 |
+
print("Found libbleu at", libbleu.__file__)
|
| 34 |
+
from fairseq.data import data_utils_fast
|
| 35 |
+
|
| 36 |
+
print("Found data_utils_fast at", data_utils_fast.__file__)
|
data/fairseq/scripts/compare_namespaces.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""Helper script to compare two argparse.Namespace objects."""
|
| 3 |
+
|
| 4 |
+
from argparse import Namespace # noqa
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def main():
|
| 8 |
+
|
| 9 |
+
ns1 = eval(input("Namespace 1: "))
|
| 10 |
+
ns2 = eval(input("Namespace 2: "))
|
| 11 |
+
|
| 12 |
+
def keys(ns):
|
| 13 |
+
ks = set()
|
| 14 |
+
for k in dir(ns):
|
| 15 |
+
if not k.startswith("_"):
|
| 16 |
+
ks.add(k)
|
| 17 |
+
return ks
|
| 18 |
+
|
| 19 |
+
k1 = keys(ns1)
|
| 20 |
+
k2 = keys(ns2)
|
| 21 |
+
|
| 22 |
+
def print_keys(ks, ns1, ns2=None):
|
| 23 |
+
for k in ks:
|
| 24 |
+
if ns2 is None:
|
| 25 |
+
print("{}\t{}".format(k, getattr(ns1, k, None)))
|
| 26 |
+
else:
|
| 27 |
+
print(
|
| 28 |
+
"{}\t{}\t{}".format(k, getattr(ns1, k, None), getattr(ns2, k, None))
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
print("Keys unique to namespace 1:")
|
| 32 |
+
print_keys(k1 - k2, ns1)
|
| 33 |
+
print()
|
| 34 |
+
|
| 35 |
+
print("Keys unique to namespace 2:")
|
| 36 |
+
print_keys(k2 - k1, ns2)
|
| 37 |
+
print()
|
| 38 |
+
|
| 39 |
+
print("Overlapping keys with different values:")
|
| 40 |
+
ks = [k for k in k1 & k2 if getattr(ns1, k, "None") != getattr(ns2, k, "None")]
|
| 41 |
+
print_keys(ks, ns1, ns2)
|
| 42 |
+
print()
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
if __name__ == "__main__":
|
| 46 |
+
main()
|
data/fairseq/scripts/compound_split_bleu.sh
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
if [ $# -ne 1 ]; then
|
| 4 |
+
echo "usage: $0 GENERATE_PY_OUTPUT"
|
| 5 |
+
exit 1
|
| 6 |
+
fi
|
| 7 |
+
|
| 8 |
+
GEN=$1
|
| 9 |
+
|
| 10 |
+
SYS=$GEN.sys
|
| 11 |
+
REF=$GEN.ref
|
| 12 |
+
|
| 13 |
+
if [ $(tail -n 1 $GEN | grep BLEU | wc -l) -ne 1 ]; then
|
| 14 |
+
echo "not done generating"
|
| 15 |
+
exit
|
| 16 |
+
fi
|
| 17 |
+
|
| 18 |
+
grep ^H $GEN | awk -F '\t' '{print $NF}' | perl -ple 's{(\S)-(\S)}{$1 ##AT##-##AT## $2}g' > $SYS
|
| 19 |
+
grep ^T $GEN | cut -f2- | perl -ple 's{(\S)-(\S)}{$1 ##AT##-##AT## $2}g' > $REF
|
| 20 |
+
fairseq-score --sys $SYS --ref $REF
|
data/fairseq/scripts/constraints/extract.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
#
|
| 3 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 4 |
+
#
|
| 5 |
+
# This source code is licensed under the MIT license found in the
|
| 6 |
+
# LICENSE file in the root directory of this source tree.
|
| 7 |
+
|
| 8 |
+
"""Extracts random constraints from reference files."""
|
| 9 |
+
|
| 10 |
+
import argparse
|
| 11 |
+
import random
|
| 12 |
+
import sys
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def get_phrase(words, index, length):
|
| 16 |
+
assert index < len(words) - length + 1
|
| 17 |
+
phr = " ".join(words[index : index + length])
|
| 18 |
+
for i in range(index, index + length):
|
| 19 |
+
words.pop(index)
|
| 20 |
+
return phr
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def main(args):
|
| 24 |
+
|
| 25 |
+
if args.seed:
|
| 26 |
+
random.seed(args.seed)
|
| 27 |
+
|
| 28 |
+
for line in sys.stdin:
|
| 29 |
+
constraints = []
|
| 30 |
+
|
| 31 |
+
def add_constraint(constraint):
|
| 32 |
+
constraints.append(constraint)
|
| 33 |
+
|
| 34 |
+
source = line.rstrip()
|
| 35 |
+
if "\t" in line:
|
| 36 |
+
source, target = line.split("\t")
|
| 37 |
+
if args.add_sos:
|
| 38 |
+
target = f"<s> {target}"
|
| 39 |
+
if args.add_eos:
|
| 40 |
+
target = f"{target} </s>"
|
| 41 |
+
|
| 42 |
+
if len(target.split()) >= args.len:
|
| 43 |
+
words = [target]
|
| 44 |
+
|
| 45 |
+
num = args.number
|
| 46 |
+
|
| 47 |
+
choices = {}
|
| 48 |
+
for i in range(num):
|
| 49 |
+
if len(words) == 0:
|
| 50 |
+
break
|
| 51 |
+
segmentno = random.choice(range(len(words)))
|
| 52 |
+
segment = words.pop(segmentno)
|
| 53 |
+
tokens = segment.split()
|
| 54 |
+
phrase_index = random.choice(range(len(tokens)))
|
| 55 |
+
choice = " ".join(
|
| 56 |
+
tokens[phrase_index : min(len(tokens), phrase_index + args.len)]
|
| 57 |
+
)
|
| 58 |
+
for j in range(
|
| 59 |
+
phrase_index, min(len(tokens), phrase_index + args.len)
|
| 60 |
+
):
|
| 61 |
+
tokens.pop(phrase_index)
|
| 62 |
+
if phrase_index > 0:
|
| 63 |
+
words.append(" ".join(tokens[0:phrase_index]))
|
| 64 |
+
if phrase_index + 1 < len(tokens):
|
| 65 |
+
words.append(" ".join(tokens[phrase_index:]))
|
| 66 |
+
choices[target.find(choice)] = choice
|
| 67 |
+
|
| 68 |
+
# mask out with spaces
|
| 69 |
+
target = target.replace(choice, " " * len(choice), 1)
|
| 70 |
+
|
| 71 |
+
for key in sorted(choices.keys()):
|
| 72 |
+
add_constraint(choices[key])
|
| 73 |
+
|
| 74 |
+
print(source, *constraints, sep="\t")
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
if __name__ == "__main__":
|
| 78 |
+
parser = argparse.ArgumentParser()
|
| 79 |
+
parser.add_argument("--number", "-n", type=int, default=1, help="number of phrases")
|
| 80 |
+
parser.add_argument("--len", "-l", type=int, default=1, help="phrase length")
|
| 81 |
+
parser.add_argument(
|
| 82 |
+
"--add-sos", default=False, action="store_true", help="add <s> token"
|
| 83 |
+
)
|
| 84 |
+
parser.add_argument(
|
| 85 |
+
"--add-eos", default=False, action="store_true", help="add </s> token"
|
| 86 |
+
)
|
| 87 |
+
parser.add_argument("--seed", "-s", default=0, type=int)
|
| 88 |
+
args = parser.parse_args()
|
| 89 |
+
|
| 90 |
+
main(args)
|
data/fairseq/scripts/convert_dictionary.lua
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- Copyright (c) Facebook, Inc. and its affiliates.
|
| 2 |
+
--
|
| 3 |
+
-- This source code is licensed under the MIT license found in the
|
| 4 |
+
-- LICENSE file in the root directory of this source tree.
|
| 5 |
+
--
|
| 6 |
+
-- Usage: convert_dictionary.lua <dict.th7>
|
| 7 |
+
require 'fairseq'
|
| 8 |
+
require 'torch'
|
| 9 |
+
require 'paths'
|
| 10 |
+
|
| 11 |
+
if #arg < 1 then
|
| 12 |
+
print('usage: convert_dictionary.lua <dict.th7>')
|
| 13 |
+
os.exit(1)
|
| 14 |
+
end
|
| 15 |
+
if not paths.filep(arg[1]) then
|
| 16 |
+
print('error: file does not exit: ' .. arg[1])
|
| 17 |
+
os.exit(1)
|
| 18 |
+
end
|
| 19 |
+
|
| 20 |
+
dict = torch.load(arg[1])
|
| 21 |
+
dst = paths.basename(arg[1]):gsub('.th7', '.txt')
|
| 22 |
+
assert(dst:match('.txt$'))
|
| 23 |
+
|
| 24 |
+
f = io.open(dst, 'w')
|
| 25 |
+
for idx, symbol in ipairs(dict.index_to_symbol) do
|
| 26 |
+
if idx > dict.cutoff then
|
| 27 |
+
break
|
| 28 |
+
end
|
| 29 |
+
f:write(symbol)
|
| 30 |
+
f:write(' ')
|
| 31 |
+
f:write(dict.index_to_freq[idx])
|
| 32 |
+
f:write('\n')
|
| 33 |
+
end
|
| 34 |
+
f:close()
|
data/fairseq/scripts/convert_model.lua
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- Copyright (c) Facebook, Inc. and its affiliates.
|
| 2 |
+
--
|
| 3 |
+
-- This source code is licensed under the MIT license found in the
|
| 4 |
+
-- LICENSE file in the root directory of this source tree.
|
| 5 |
+
--
|
| 6 |
+
-- Usage: convert_model.lua <model_epoch1.th7>
|
| 7 |
+
require 'torch'
|
| 8 |
+
local fairseq = require 'fairseq'
|
| 9 |
+
|
| 10 |
+
model = torch.load(arg[1])
|
| 11 |
+
|
| 12 |
+
function find_weight_norm(container, module)
|
| 13 |
+
for _, wn in ipairs(container:listModules()) do
|
| 14 |
+
if torch.type(wn) == 'nn.WeightNorm' and wn.modules[1] == module then
|
| 15 |
+
return wn
|
| 16 |
+
end
|
| 17 |
+
end
|
| 18 |
+
end
|
| 19 |
+
|
| 20 |
+
function push_state(dict, key, module)
|
| 21 |
+
if torch.type(module) == 'nn.Linear' then
|
| 22 |
+
local wn = find_weight_norm(model.module, module)
|
| 23 |
+
assert(wn)
|
| 24 |
+
dict[key .. '.weight_v'] = wn.v:float()
|
| 25 |
+
dict[key .. '.weight_g'] = wn.g:float()
|
| 26 |
+
elseif torch.type(module) == 'nn.TemporalConvolutionTBC' then
|
| 27 |
+
local wn = find_weight_norm(model.module, module)
|
| 28 |
+
assert(wn)
|
| 29 |
+
local v = wn.v:float():view(wn.viewOut):transpose(2, 3)
|
| 30 |
+
dict[key .. '.weight_v'] = v
|
| 31 |
+
dict[key .. '.weight_g'] = wn.g:float():view(module.weight:size(3), 1, 1)
|
| 32 |
+
else
|
| 33 |
+
dict[key .. '.weight'] = module.weight:float()
|
| 34 |
+
end
|
| 35 |
+
if module.bias then
|
| 36 |
+
dict[key .. '.bias'] = module.bias:float()
|
| 37 |
+
end
|
| 38 |
+
end
|
| 39 |
+
|
| 40 |
+
encoder_dict = {}
|
| 41 |
+
decoder_dict = {}
|
| 42 |
+
combined_dict = {}
|
| 43 |
+
|
| 44 |
+
function encoder_state(encoder)
|
| 45 |
+
luts = encoder:findModules('nn.LookupTable')
|
| 46 |
+
push_state(encoder_dict, 'embed_tokens', luts[1])
|
| 47 |
+
push_state(encoder_dict, 'embed_positions', luts[2])
|
| 48 |
+
|
| 49 |
+
fcs = encoder:findModules('nn.Linear')
|
| 50 |
+
assert(#fcs >= 2)
|
| 51 |
+
local nInputPlane = fcs[1].weight:size(1)
|
| 52 |
+
push_state(encoder_dict, 'fc1', table.remove(fcs, 1))
|
| 53 |
+
push_state(encoder_dict, 'fc2', table.remove(fcs, #fcs))
|
| 54 |
+
|
| 55 |
+
for i, module in ipairs(encoder:findModules('nn.TemporalConvolutionTBC')) do
|
| 56 |
+
push_state(encoder_dict, 'convolutions.' .. tostring(i - 1), module)
|
| 57 |
+
if nInputPlane ~= module.weight:size(3) / 2 then
|
| 58 |
+
push_state(encoder_dict, 'projections.' .. tostring(i - 1), table.remove(fcs, 1))
|
| 59 |
+
end
|
| 60 |
+
nInputPlane = module.weight:size(3) / 2
|
| 61 |
+
end
|
| 62 |
+
assert(#fcs == 0)
|
| 63 |
+
end
|
| 64 |
+
|
| 65 |
+
function decoder_state(decoder)
|
| 66 |
+
luts = decoder:findModules('nn.LookupTable')
|
| 67 |
+
push_state(decoder_dict, 'embed_tokens', luts[1])
|
| 68 |
+
push_state(decoder_dict, 'embed_positions', luts[2])
|
| 69 |
+
|
| 70 |
+
fcs = decoder:findModules('nn.Linear')
|
| 71 |
+
local nInputPlane = fcs[1].weight:size(1)
|
| 72 |
+
push_state(decoder_dict, 'fc1', table.remove(fcs, 1))
|
| 73 |
+
push_state(decoder_dict, 'fc2', fcs[#fcs - 1])
|
| 74 |
+
push_state(decoder_dict, 'fc3', fcs[#fcs])
|
| 75 |
+
|
| 76 |
+
table.remove(fcs, #fcs)
|
| 77 |
+
table.remove(fcs, #fcs)
|
| 78 |
+
|
| 79 |
+
for i, module in ipairs(decoder:findModules('nn.TemporalConvolutionTBC')) do
|
| 80 |
+
if nInputPlane ~= module.weight:size(3) / 2 then
|
| 81 |
+
push_state(decoder_dict, 'projections.' .. tostring(i - 1), table.remove(fcs, 1))
|
| 82 |
+
end
|
| 83 |
+
nInputPlane = module.weight:size(3) / 2
|
| 84 |
+
|
| 85 |
+
local prefix = 'attention.' .. tostring(i - 1)
|
| 86 |
+
push_state(decoder_dict, prefix .. '.in_projection', table.remove(fcs, 1))
|
| 87 |
+
push_state(decoder_dict, prefix .. '.out_projection', table.remove(fcs, 1))
|
| 88 |
+
push_state(decoder_dict, 'convolutions.' .. tostring(i - 1), module)
|
| 89 |
+
end
|
| 90 |
+
assert(#fcs == 0)
|
| 91 |
+
end
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
_encoder = model.module.modules[2]
|
| 95 |
+
_decoder = model.module.modules[3]
|
| 96 |
+
|
| 97 |
+
encoder_state(_encoder)
|
| 98 |
+
decoder_state(_decoder)
|
| 99 |
+
|
| 100 |
+
for k, v in pairs(encoder_dict) do
|
| 101 |
+
combined_dict['encoder.' .. k] = v
|
| 102 |
+
end
|
| 103 |
+
for k, v in pairs(decoder_dict) do
|
| 104 |
+
combined_dict['decoder.' .. k] = v
|
| 105 |
+
end
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
torch.save('state_dict.t7', combined_dict)
|
data/fairseq/scripts/count_docs.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the MIT license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
"""
|
| 7 |
+
Count the number of documents and average number of lines and tokens per
|
| 8 |
+
document in a large file. Documents should be separated by a single empty line.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
import argparse
|
| 12 |
+
import gzip
|
| 13 |
+
import sys
|
| 14 |
+
|
| 15 |
+
import numpy as np
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def main():
|
| 19 |
+
parser = argparse.ArgumentParser()
|
| 20 |
+
parser.add_argument("input")
|
| 21 |
+
parser.add_argument("--gzip", action="store_true")
|
| 22 |
+
args = parser.parse_args()
|
| 23 |
+
|
| 24 |
+
def gopen():
|
| 25 |
+
if args.gzip:
|
| 26 |
+
return gzip.open(args.input, "r")
|
| 27 |
+
else:
|
| 28 |
+
return open(args.input, "r", encoding="utf-8")
|
| 29 |
+
|
| 30 |
+
num_lines = []
|
| 31 |
+
num_toks = []
|
| 32 |
+
with gopen() as h:
|
| 33 |
+
num_docs = 1
|
| 34 |
+
num_lines_in_doc = 0
|
| 35 |
+
num_toks_in_doc = 0
|
| 36 |
+
for i, line in enumerate(h):
|
| 37 |
+
if len(line.strip()) == 0: # empty line indicates new document
|
| 38 |
+
num_docs += 1
|
| 39 |
+
num_lines.append(num_lines_in_doc)
|
| 40 |
+
num_toks.append(num_toks_in_doc)
|
| 41 |
+
num_lines_in_doc = 0
|
| 42 |
+
num_toks_in_doc = 0
|
| 43 |
+
else:
|
| 44 |
+
num_lines_in_doc += 1
|
| 45 |
+
num_toks_in_doc += len(line.rstrip().split())
|
| 46 |
+
if i % 1000000 == 0:
|
| 47 |
+
print(i, file=sys.stderr, end="", flush=True)
|
| 48 |
+
elif i % 100000 == 0:
|
| 49 |
+
print(".", file=sys.stderr, end="", flush=True)
|
| 50 |
+
print(file=sys.stderr, flush=True)
|
| 51 |
+
|
| 52 |
+
print("found {} docs".format(num_docs))
|
| 53 |
+
print("average num lines per doc: {}".format(np.mean(num_lines)))
|
| 54 |
+
print("average num toks per doc: {}".format(np.mean(num_toks)))
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
if __name__ == "__main__":
|
| 58 |
+
main()
|
data/fairseq/scripts/read_binarized.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the MIT license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
import argparse
|
| 8 |
+
|
| 9 |
+
from fairseq.data import Dictionary, data_utils, indexed_dataset
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def get_parser():
|
| 13 |
+
parser = argparse.ArgumentParser(
|
| 14 |
+
description="writes text from binarized file to stdout"
|
| 15 |
+
)
|
| 16 |
+
# fmt: off
|
| 17 |
+
parser.add_argument('--dataset-impl', help='dataset implementation',
|
| 18 |
+
choices=indexed_dataset.get_available_dataset_impl())
|
| 19 |
+
parser.add_argument('--dict', metavar='FP', help='dictionary containing known words', default=None)
|
| 20 |
+
parser.add_argument('--input', metavar='FP', required=True, help='binarized file to read')
|
| 21 |
+
# fmt: on
|
| 22 |
+
|
| 23 |
+
return parser
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def main():
|
| 27 |
+
parser = get_parser()
|
| 28 |
+
args = parser.parse_args()
|
| 29 |
+
|
| 30 |
+
dictionary = Dictionary.load(args.dict) if args.dict is not None else None
|
| 31 |
+
dataset = data_utils.load_indexed_dataset(
|
| 32 |
+
args.input,
|
| 33 |
+
dictionary,
|
| 34 |
+
dataset_impl=args.dataset_impl,
|
| 35 |
+
default="lazy",
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
for tensor_line in dataset:
|
| 39 |
+
if dictionary is None:
|
| 40 |
+
line = " ".join([str(int(x)) for x in tensor_line])
|
| 41 |
+
else:
|
| 42 |
+
line = dictionary.string(tensor_line)
|
| 43 |
+
|
| 44 |
+
print(line)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
if __name__ == "__main__":
|
| 48 |
+
main()
|
data/fairseq/scripts/rm_pt.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the MIT license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
import argparse
|
| 8 |
+
import os
|
| 9 |
+
import re
|
| 10 |
+
import shutil
|
| 11 |
+
import sys
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
pt_regexp = re.compile(r"checkpoint(\d+|_\d+_\d+|_[a-z]+)\.pt")
|
| 15 |
+
pt_regexp_epoch_based = re.compile(r"checkpoint(\d+)\.pt")
|
| 16 |
+
pt_regexp_update_based = re.compile(r"checkpoint_\d+_(\d+)\.pt")
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def parse_checkpoints(files):
|
| 20 |
+
entries = []
|
| 21 |
+
for f in files:
|
| 22 |
+
m = pt_regexp_epoch_based.fullmatch(f)
|
| 23 |
+
if m is not None:
|
| 24 |
+
entries.append((int(m.group(1)), m.group(0)))
|
| 25 |
+
else:
|
| 26 |
+
m = pt_regexp_update_based.fullmatch(f)
|
| 27 |
+
if m is not None:
|
| 28 |
+
entries.append((int(m.group(1)), m.group(0)))
|
| 29 |
+
return entries
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def last_n_checkpoints(files, n):
|
| 33 |
+
entries = parse_checkpoints(files)
|
| 34 |
+
return [x[1] for x in sorted(entries, reverse=True)[:n]]
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def every_n_checkpoints(files, n):
|
| 38 |
+
entries = parse_checkpoints(files)
|
| 39 |
+
return [x[1] for x in sorted(sorted(entries)[::-n])]
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def main():
|
| 43 |
+
parser = argparse.ArgumentParser(
|
| 44 |
+
description=(
|
| 45 |
+
"Recursively delete checkpoint files from `root_dir`, "
|
| 46 |
+
"but preserve checkpoint_best.pt and checkpoint_last.pt"
|
| 47 |
+
)
|
| 48 |
+
)
|
| 49 |
+
parser.add_argument("root_dirs", nargs="*")
|
| 50 |
+
parser.add_argument(
|
| 51 |
+
"--save-last", type=int, default=0, help="number of last checkpoints to save"
|
| 52 |
+
)
|
| 53 |
+
parser.add_argument(
|
| 54 |
+
"--save-every", type=int, default=0, help="interval of checkpoints to save"
|
| 55 |
+
)
|
| 56 |
+
parser.add_argument(
|
| 57 |
+
"--preserve-test",
|
| 58 |
+
action="store_true",
|
| 59 |
+
help="preserve checkpoints in dirs that start with test_ prefix (default: delete them)",
|
| 60 |
+
)
|
| 61 |
+
parser.add_argument(
|
| 62 |
+
"--delete-best", action="store_true", help="delete checkpoint_best.pt"
|
| 63 |
+
)
|
| 64 |
+
parser.add_argument(
|
| 65 |
+
"--delete-last", action="store_true", help="delete checkpoint_last.pt"
|
| 66 |
+
)
|
| 67 |
+
parser.add_argument(
|
| 68 |
+
"--no-dereference", action="store_true", help="don't dereference symlinks"
|
| 69 |
+
)
|
| 70 |
+
args = parser.parse_args()
|
| 71 |
+
|
| 72 |
+
files_to_desymlink = []
|
| 73 |
+
files_to_preserve = []
|
| 74 |
+
files_to_delete = []
|
| 75 |
+
for root_dir in args.root_dirs:
|
| 76 |
+
for root, _subdirs, files in os.walk(root_dir):
|
| 77 |
+
if args.save_last > 0:
|
| 78 |
+
to_save = last_n_checkpoints(files, args.save_last)
|
| 79 |
+
else:
|
| 80 |
+
to_save = []
|
| 81 |
+
if args.save_every > 0:
|
| 82 |
+
to_save += every_n_checkpoints(files, args.save_every)
|
| 83 |
+
for file in files:
|
| 84 |
+
if not pt_regexp.fullmatch(file):
|
| 85 |
+
continue
|
| 86 |
+
full_path = os.path.join(root, file)
|
| 87 |
+
if (
|
| 88 |
+
not os.path.basename(root).startswith("test_") or args.preserve_test
|
| 89 |
+
) and (
|
| 90 |
+
(file == "checkpoint_last.pt" and not args.delete_last)
|
| 91 |
+
or (file == "checkpoint_best.pt" and not args.delete_best)
|
| 92 |
+
or file in to_save
|
| 93 |
+
):
|
| 94 |
+
if os.path.islink(full_path) and not args.no_dereference:
|
| 95 |
+
files_to_desymlink.append(full_path)
|
| 96 |
+
else:
|
| 97 |
+
files_to_preserve.append(full_path)
|
| 98 |
+
else:
|
| 99 |
+
files_to_delete.append(full_path)
|
| 100 |
+
|
| 101 |
+
if len(files_to_desymlink) == 0 and len(files_to_delete) == 0:
|
| 102 |
+
print("Nothing to do.")
|
| 103 |
+
sys.exit(0)
|
| 104 |
+
|
| 105 |
+
files_to_desymlink = sorted(files_to_desymlink)
|
| 106 |
+
files_to_preserve = sorted(files_to_preserve)
|
| 107 |
+
files_to_delete = sorted(files_to_delete)
|
| 108 |
+
|
| 109 |
+
print("Operations to perform (in order):")
|
| 110 |
+
if len(files_to_desymlink) > 0:
|
| 111 |
+
for file in files_to_desymlink:
|
| 112 |
+
print(" - preserve (and dereference symlink): " + file)
|
| 113 |
+
if len(files_to_preserve) > 0:
|
| 114 |
+
for file in files_to_preserve:
|
| 115 |
+
print(" - preserve: " + file)
|
| 116 |
+
if len(files_to_delete) > 0:
|
| 117 |
+
for file in files_to_delete:
|
| 118 |
+
print(" - delete: " + file)
|
| 119 |
+
while True:
|
| 120 |
+
resp = input("Continue? (Y/N): ")
|
| 121 |
+
if resp.strip().lower() == "y":
|
| 122 |
+
break
|
| 123 |
+
elif resp.strip().lower() == "n":
|
| 124 |
+
sys.exit(0)
|
| 125 |
+
|
| 126 |
+
print("Executing...")
|
| 127 |
+
if len(files_to_desymlink) > 0:
|
| 128 |
+
for file in files_to_desymlink:
|
| 129 |
+
realpath = os.path.realpath(file)
|
| 130 |
+
print("rm " + file)
|
| 131 |
+
os.remove(file)
|
| 132 |
+
print("cp {} {}".format(realpath, file))
|
| 133 |
+
shutil.copyfile(realpath, file)
|
| 134 |
+
if len(files_to_delete) > 0:
|
| 135 |
+
for file in files_to_delete:
|
| 136 |
+
print("rm " + file)
|
| 137 |
+
os.remove(file)
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
if __name__ == "__main__":
|
| 141 |
+
main()
|
data/fairseq/scripts/sacrebleu.sh
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
if [ $# -ne 4 ]; then
|
| 4 |
+
echo "usage: $0 TESTSET SRCLANG TGTLANG GEN"
|
| 5 |
+
exit 1
|
| 6 |
+
fi
|
| 7 |
+
|
| 8 |
+
TESTSET=$1
|
| 9 |
+
SRCLANG=$2
|
| 10 |
+
TGTLANG=$3
|
| 11 |
+
|
| 12 |
+
GEN=$4
|
| 13 |
+
|
| 14 |
+
if ! command -v sacremoses &> /dev/null
|
| 15 |
+
then
|
| 16 |
+
echo "sacremoses could not be found, please install with: pip install sacremoses"
|
| 17 |
+
exit
|
| 18 |
+
fi
|
| 19 |
+
|
| 20 |
+
grep ^H $GEN \
|
| 21 |
+
| sed 's/^H\-//' \
|
| 22 |
+
| sort -n -k 1 \
|
| 23 |
+
| cut -f 3 \
|
| 24 |
+
| sacremoses detokenize \
|
| 25 |
+
> $GEN.sorted.detok
|
| 26 |
+
|
| 27 |
+
sacrebleu --test-set $TESTSET --language-pair "${SRCLANG}-${TGTLANG}" < $GEN.sorted.detok
|
data/fairseq/scripts/shard_docs.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the MIT license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
"""
|
| 7 |
+
Split a large file into shards while respecting document boundaries. Documents
|
| 8 |
+
should be separated by a single empty line.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
import argparse
|
| 12 |
+
import contextlib
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def main():
|
| 16 |
+
parser = argparse.ArgumentParser()
|
| 17 |
+
parser.add_argument("input")
|
| 18 |
+
parser.add_argument("--num-shards", type=int)
|
| 19 |
+
args = parser.parse_args()
|
| 20 |
+
|
| 21 |
+
assert args.num_shards is not None and args.num_shards > 1
|
| 22 |
+
|
| 23 |
+
with open(args.input, "r", encoding="utf-8") as h:
|
| 24 |
+
with contextlib.ExitStack() as stack:
|
| 25 |
+
outputs = [
|
| 26 |
+
stack.enter_context(
|
| 27 |
+
open(args.input + ".shard" + str(i), "w", encoding="utf-8")
|
| 28 |
+
)
|
| 29 |
+
for i in range(args.num_shards)
|
| 30 |
+
]
|
| 31 |
+
|
| 32 |
+
doc = []
|
| 33 |
+
first_doc = [True] * args.num_shards
|
| 34 |
+
|
| 35 |
+
def output_doc(i):
|
| 36 |
+
if not first_doc[i]:
|
| 37 |
+
outputs[i].write("\n")
|
| 38 |
+
first_doc[i] = False
|
| 39 |
+
for line in doc:
|
| 40 |
+
outputs[i].write(line)
|
| 41 |
+
doc.clear()
|
| 42 |
+
|
| 43 |
+
num_docs = 0
|
| 44 |
+
for line in h:
|
| 45 |
+
if line.strip() == "": # empty line indicates new document
|
| 46 |
+
output_doc(num_docs % args.num_shards)
|
| 47 |
+
num_docs += 1
|
| 48 |
+
else:
|
| 49 |
+
doc.append(line)
|
| 50 |
+
output_doc(num_docs % args.num_shards)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
if __name__ == "__main__":
|
| 54 |
+
main()
|
data/fairseq/scripts/split_train_valid_docs.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the MIT license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
"""
|
| 7 |
+
Split a large file into a train and valid set while respecting document
|
| 8 |
+
boundaries. Documents should be separated by a single empty line.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
import argparse
|
| 12 |
+
import random
|
| 13 |
+
import sys
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
parser = argparse.ArgumentParser()
|
| 18 |
+
parser.add_argument("input")
|
| 19 |
+
parser.add_argument("sample_output", help="train output file")
|
| 20 |
+
parser.add_argument("remainder_output", help="valid output file")
|
| 21 |
+
parser.add_argument("-k", type=int, help="remainder size")
|
| 22 |
+
parser.add_argument(
|
| 23 |
+
"--lines", action="store_true", help="split lines instead of docs"
|
| 24 |
+
)
|
| 25 |
+
args = parser.parse_args()
|
| 26 |
+
|
| 27 |
+
assert args.k is not None
|
| 28 |
+
|
| 29 |
+
sample = []
|
| 30 |
+
remainder = []
|
| 31 |
+
num_docs = [0]
|
| 32 |
+
|
| 33 |
+
def update_sample(doc):
|
| 34 |
+
if len(sample) < args.k:
|
| 35 |
+
sample.append(doc.copy())
|
| 36 |
+
else:
|
| 37 |
+
i = num_docs[0]
|
| 38 |
+
j = random.randrange(i + 1)
|
| 39 |
+
if j < args.k:
|
| 40 |
+
remainder.append(sample[j])
|
| 41 |
+
sample[j] = doc.copy()
|
| 42 |
+
else:
|
| 43 |
+
remainder.append(doc.copy())
|
| 44 |
+
num_docs[0] += 1
|
| 45 |
+
doc.clear()
|
| 46 |
+
|
| 47 |
+
with open(args.input, "r", encoding="utf-8") as h:
|
| 48 |
+
doc = []
|
| 49 |
+
for i, line in enumerate(h):
|
| 50 |
+
if line.strip() == "": # empty line indicates new document
|
| 51 |
+
update_sample(doc)
|
| 52 |
+
else:
|
| 53 |
+
doc.append(line)
|
| 54 |
+
if args.lines:
|
| 55 |
+
update_sample(doc)
|
| 56 |
+
if i % 1000000 == 0:
|
| 57 |
+
print(i, file=sys.stderr, end="", flush=True)
|
| 58 |
+
elif i % 100000 == 0:
|
| 59 |
+
print(".", file=sys.stderr, end="", flush=True)
|
| 60 |
+
if len(doc) > 0:
|
| 61 |
+
update_sample(doc)
|
| 62 |
+
print(file=sys.stderr, flush=True)
|
| 63 |
+
|
| 64 |
+
assert len(sample) == args.k
|
| 65 |
+
|
| 66 |
+
with open(args.sample_output, "w", encoding="utf-8") as out:
|
| 67 |
+
first = True
|
| 68 |
+
for doc in sample:
|
| 69 |
+
if not first and not args.lines:
|
| 70 |
+
out.write("\n")
|
| 71 |
+
first = False
|
| 72 |
+
for line in doc:
|
| 73 |
+
out.write(line)
|
| 74 |
+
|
| 75 |
+
with open(args.remainder_output, "w", encoding="utf-8") as out:
|
| 76 |
+
first = True
|
| 77 |
+
for doc in remainder:
|
| 78 |
+
if not first and not args.lines:
|
| 79 |
+
out.write("\n")
|
| 80 |
+
first = False
|
| 81 |
+
for line in doc:
|
| 82 |
+
out.write(line)
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
if __name__ == "__main__":
|
| 86 |
+
main()
|
data/fairseq/scripts/spm_decode.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
# All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# This source code is licensed under the license found in the
|
| 6 |
+
# LICENSE file in the root directory of this source tree.
|
| 7 |
+
|
| 8 |
+
from __future__ import absolute_import, division, print_function, unicode_literals
|
| 9 |
+
|
| 10 |
+
import argparse
|
| 11 |
+
|
| 12 |
+
import sentencepiece as spm
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def main():
|
| 16 |
+
parser = argparse.ArgumentParser()
|
| 17 |
+
parser.add_argument(
|
| 18 |
+
"--model", required=True, help="sentencepiece model to use for decoding"
|
| 19 |
+
)
|
| 20 |
+
parser.add_argument("--input", required=True, help="input file to decode")
|
| 21 |
+
parser.add_argument("--input_format", choices=["piece", "id"], default="piece")
|
| 22 |
+
args = parser.parse_args()
|
| 23 |
+
|
| 24 |
+
sp = spm.SentencePieceProcessor()
|
| 25 |
+
sp.Load(args.model)
|
| 26 |
+
|
| 27 |
+
if args.input_format == "piece":
|
| 28 |
+
|
| 29 |
+
def decode(input):
|
| 30 |
+
return "".join(sp.DecodePieces(input))
|
| 31 |
+
|
| 32 |
+
elif args.input_format == "id":
|
| 33 |
+
|
| 34 |
+
def decode(input):
|
| 35 |
+
return "".join(sp.DecodeIds(input))
|
| 36 |
+
|
| 37 |
+
else:
|
| 38 |
+
raise NotImplementedError
|
| 39 |
+
|
| 40 |
+
def tok2int(tok):
|
| 41 |
+
# remap reference-side <unk> (represented as <<unk>>) to 0
|
| 42 |
+
return int(tok) if tok != "<<unk>>" else 0
|
| 43 |
+
|
| 44 |
+
with open(args.input, "r", encoding="utf-8") as h:
|
| 45 |
+
for line in h:
|
| 46 |
+
if args.input_format == "id":
|
| 47 |
+
print(decode(list(map(tok2int, line.rstrip().split()))))
|
| 48 |
+
elif args.input_format == "piece":
|
| 49 |
+
print(decode(line.rstrip().split()))
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
if __name__ == "__main__":
|
| 53 |
+
main()
|
data/fairseq/scripts/spm_encode.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
# All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# This source code is licensed under the license found in the
|
| 6 |
+
# LICENSE file in the root directory of this source tree.
|
| 7 |
+
|
| 8 |
+
from __future__ import absolute_import, division, print_function, unicode_literals
|
| 9 |
+
|
| 10 |
+
import argparse
|
| 11 |
+
import contextlib
|
| 12 |
+
import sys
|
| 13 |
+
|
| 14 |
+
import sentencepiece as spm
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def main():
|
| 18 |
+
parser = argparse.ArgumentParser()
|
| 19 |
+
parser.add_argument(
|
| 20 |
+
"--model", required=True, help="sentencepiece model to use for encoding"
|
| 21 |
+
)
|
| 22 |
+
parser.add_argument(
|
| 23 |
+
"--inputs", nargs="+", default=["-"], help="input files to filter/encode"
|
| 24 |
+
)
|
| 25 |
+
parser.add_argument(
|
| 26 |
+
"--outputs", nargs="+", default=["-"], help="path to save encoded outputs"
|
| 27 |
+
)
|
| 28 |
+
parser.add_argument("--output_format", choices=["piece", "id"], default="piece")
|
| 29 |
+
parser.add_argument(
|
| 30 |
+
"--min-len",
|
| 31 |
+
type=int,
|
| 32 |
+
metavar="N",
|
| 33 |
+
help="filter sentence pairs with fewer than N tokens",
|
| 34 |
+
)
|
| 35 |
+
parser.add_argument(
|
| 36 |
+
"--max-len",
|
| 37 |
+
type=int,
|
| 38 |
+
metavar="N",
|
| 39 |
+
help="filter sentence pairs with more than N tokens",
|
| 40 |
+
)
|
| 41 |
+
args = parser.parse_args()
|
| 42 |
+
|
| 43 |
+
assert len(args.inputs) == len(
|
| 44 |
+
args.outputs
|
| 45 |
+
), "number of input and output paths should match"
|
| 46 |
+
|
| 47 |
+
sp = spm.SentencePieceProcessor()
|
| 48 |
+
sp.Load(args.model)
|
| 49 |
+
|
| 50 |
+
if args.output_format == "piece":
|
| 51 |
+
|
| 52 |
+
def encode(input):
|
| 53 |
+
return sp.EncodeAsPieces(input)
|
| 54 |
+
|
| 55 |
+
elif args.output_format == "id":
|
| 56 |
+
|
| 57 |
+
def encode(input):
|
| 58 |
+
return list(map(str, sp.EncodeAsIds(input)))
|
| 59 |
+
|
| 60 |
+
else:
|
| 61 |
+
raise NotImplementedError
|
| 62 |
+
|
| 63 |
+
if args.min_len is not None or args.max_len is not None:
|
| 64 |
+
|
| 65 |
+
def valid(line):
|
| 66 |
+
return (args.min_len is None or len(line) >= args.min_len) and (
|
| 67 |
+
args.max_len is None or len(line) <= args.max_len
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
else:
|
| 71 |
+
|
| 72 |
+
def valid(lines):
|
| 73 |
+
return True
|
| 74 |
+
|
| 75 |
+
with contextlib.ExitStack() as stack:
|
| 76 |
+
inputs = [
|
| 77 |
+
stack.enter_context(open(input, "r", encoding="utf-8"))
|
| 78 |
+
if input != "-"
|
| 79 |
+
else sys.stdin
|
| 80 |
+
for input in args.inputs
|
| 81 |
+
]
|
| 82 |
+
outputs = [
|
| 83 |
+
stack.enter_context(open(output, "w", encoding="utf-8"))
|
| 84 |
+
if output != "-"
|
| 85 |
+
else sys.stdout
|
| 86 |
+
for output in args.outputs
|
| 87 |
+
]
|
| 88 |
+
|
| 89 |
+
stats = {
|
| 90 |
+
"num_empty": 0,
|
| 91 |
+
"num_filtered": 0,
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
def encode_line(line):
|
| 95 |
+
line = line.strip()
|
| 96 |
+
if len(line) > 0:
|
| 97 |
+
line = encode(line)
|
| 98 |
+
if valid(line):
|
| 99 |
+
return line
|
| 100 |
+
else:
|
| 101 |
+
stats["num_filtered"] += 1
|
| 102 |
+
else:
|
| 103 |
+
stats["num_empty"] += 1
|
| 104 |
+
return None
|
| 105 |
+
|
| 106 |
+
for i, lines in enumerate(zip(*inputs), start=1):
|
| 107 |
+
enc_lines = list(map(encode_line, lines))
|
| 108 |
+
if not any(enc_line is None for enc_line in enc_lines):
|
| 109 |
+
for enc_line, output_h in zip(enc_lines, outputs):
|
| 110 |
+
print(" ".join(enc_line), file=output_h)
|
| 111 |
+
if i % 10000 == 0:
|
| 112 |
+
print("processed {} lines".format(i), file=sys.stderr)
|
| 113 |
+
|
| 114 |
+
print("skipped {} empty lines".format(stats["num_empty"]), file=sys.stderr)
|
| 115 |
+
print("filtered {} lines".format(stats["num_filtered"]), file=sys.stderr)
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
if __name__ == "__main__":
|
| 119 |
+
main()
|
data/fairseq/scripts/spm_train.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
# All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# This source code is licensed under the license found in the
|
| 6 |
+
# LICENSE file in the root directory of this source tree.
|
| 7 |
+
|
| 8 |
+
from __future__ import absolute_import, division, print_function, unicode_literals
|
| 9 |
+
|
| 10 |
+
import sys
|
| 11 |
+
|
| 12 |
+
import sentencepiece as spm
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
if __name__ == "__main__":
|
| 16 |
+
spm.SentencePieceTrainer.Train(" ".join(sys.argv[1:]))
|
data/fairseq/scripts/test_fsdp.sh
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
rm -rf fsdp_dummy
|
| 3 |
+
mkdir -p fsdp_dummy
|
| 4 |
+
CUDA_VISIBLE_DEVICES=0,1,2,3 fairseq-train /private/home/sshleifer/data-bin/stories_mmap \
|
| 5 |
+
--ddp-backend fully_sharded --fp16 --fp16-init-scale 4 \
|
| 6 |
+
--cpu-offload --checkpoint-activations \
|
| 7 |
+
--task language_modeling --tokens-per-sample 256 --batch-size 8 \
|
| 8 |
+
--arch transformer_lm_gpt2_tiny \
|
| 9 |
+
--optimizer cpu_adam --adam-betas "(0.9,0.98)" \
|
| 10 |
+
--lr 0.0001 --lr-scheduler polynomial_decay --warmup-updates 5 --total-num-update 10 \
|
| 11 |
+
--max-update 5 --log-format json --log-interval 1 \
|
| 12 |
+
--save-interval-updates 5 --save-dir fsdp_dummy --disable-validation \
|
| 13 |
+
--restore-file x.pt "$@"
|
| 14 |
+
|
| 15 |
+
# Now we try to load the checkpoint
|
| 16 |
+
CUDA_VISIBLE_DEVICES=0,1 fairseq-train /private/home/sshleifer/data-bin/stories_mmap \
|
| 17 |
+
--ddp-backend fully_sharded --fp16 --fp16-init-scale 4 \
|
| 18 |
+
--cpu-offload --checkpoint-activations \
|
| 19 |
+
--task language_modeling --tokens-per-sample 256 --batch-size 8 \
|
| 20 |
+
--arch transformer_lm_gpt2_tiny \
|
| 21 |
+
--optimizer cpu_adam --adam-betas "(0.9,0.98)" \
|
| 22 |
+
--lr 0.0001 --lr-scheduler polynomial_decay --warmup-updates 5 --total-num-update 10 \
|
| 23 |
+
--max-update 2 --log-format json --log-interval 1 \
|
| 24 |
+
--save-interval-updates 2 --save-dir fsdp_dummy
|
data/fairseq/setup.py
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the MIT license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import subprocess
|
| 9 |
+
import sys
|
| 10 |
+
|
| 11 |
+
from setuptools import Extension, find_packages, setup
|
| 12 |
+
from torch.utils import cpp_extension
|
| 13 |
+
|
| 14 |
+
if sys.version_info < (3, 6):
|
| 15 |
+
sys.exit("Sorry, Python >= 3.6 is required for fairseq.")
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def write_version_py():
|
| 19 |
+
with open(os.path.join("fairseq", "version.txt")) as f:
|
| 20 |
+
version = f.read().strip()
|
| 21 |
+
|
| 22 |
+
# write version info to fairseq/version.py
|
| 23 |
+
with open(os.path.join("fairseq", "version.py"), "w") as f:
|
| 24 |
+
f.write('__version__ = "{}"\n'.format(version))
|
| 25 |
+
return version
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
version = write_version_py()
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
with open("README.md") as f:
|
| 32 |
+
readme = f.read()
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
if sys.platform == "darwin":
|
| 36 |
+
extra_compile_args = ["-stdlib=libc++", "-O3"]
|
| 37 |
+
else:
|
| 38 |
+
extra_compile_args = ["-std=c++11", "-O3"]
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class NumpyExtension(Extension):
|
| 42 |
+
"""Source: https://stackoverflow.com/a/54128391"""
|
| 43 |
+
|
| 44 |
+
def __init__(self, *args, **kwargs):
|
| 45 |
+
self.__include_dirs = []
|
| 46 |
+
super().__init__(*args, **kwargs)
|
| 47 |
+
|
| 48 |
+
@property
|
| 49 |
+
def include_dirs(self):
|
| 50 |
+
import numpy
|
| 51 |
+
|
| 52 |
+
return self.__include_dirs + [numpy.get_include()]
|
| 53 |
+
|
| 54 |
+
@include_dirs.setter
|
| 55 |
+
def include_dirs(self, dirs):
|
| 56 |
+
self.__include_dirs = dirs
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
extensions = [
|
| 60 |
+
Extension(
|
| 61 |
+
"fairseq.libbleu",
|
| 62 |
+
sources=[
|
| 63 |
+
"fairseq/clib/libbleu/libbleu.cpp",
|
| 64 |
+
"fairseq/clib/libbleu/module.cpp",
|
| 65 |
+
],
|
| 66 |
+
extra_compile_args=extra_compile_args,
|
| 67 |
+
),
|
| 68 |
+
NumpyExtension(
|
| 69 |
+
"fairseq.data.data_utils_fast",
|
| 70 |
+
sources=["fairseq/data/data_utils_fast.pyx"],
|
| 71 |
+
language="c++",
|
| 72 |
+
extra_compile_args=extra_compile_args,
|
| 73 |
+
),
|
| 74 |
+
NumpyExtension(
|
| 75 |
+
"fairseq.data.token_block_utils_fast",
|
| 76 |
+
sources=["fairseq/data/token_block_utils_fast.pyx"],
|
| 77 |
+
language="c++",
|
| 78 |
+
extra_compile_args=extra_compile_args,
|
| 79 |
+
),
|
| 80 |
+
]
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
extensions.extend(
|
| 84 |
+
[
|
| 85 |
+
cpp_extension.CppExtension(
|
| 86 |
+
"fairseq.libbase",
|
| 87 |
+
sources=[
|
| 88 |
+
"fairseq/clib/libbase/balanced_assignment.cpp",
|
| 89 |
+
],
|
| 90 |
+
),
|
| 91 |
+
cpp_extension.CppExtension(
|
| 92 |
+
"fairseq.libnat",
|
| 93 |
+
sources=[
|
| 94 |
+
"fairseq/clib/libnat/edit_dist.cpp",
|
| 95 |
+
],
|
| 96 |
+
),
|
| 97 |
+
cpp_extension.CppExtension(
|
| 98 |
+
"alignment_train_cpu_binding",
|
| 99 |
+
sources=[
|
| 100 |
+
"examples/operators/alignment_train_cpu.cpp",
|
| 101 |
+
],
|
| 102 |
+
),
|
| 103 |
+
]
|
| 104 |
+
)
|
| 105 |
+
if "CUDA_HOME" in os.environ:
|
| 106 |
+
extensions.extend(
|
| 107 |
+
[
|
| 108 |
+
cpp_extension.CppExtension(
|
| 109 |
+
"fairseq.libnat_cuda",
|
| 110 |
+
sources=[
|
| 111 |
+
"fairseq/clib/libnat_cuda/edit_dist.cu",
|
| 112 |
+
"fairseq/clib/libnat_cuda/binding.cpp",
|
| 113 |
+
],
|
| 114 |
+
),
|
| 115 |
+
cpp_extension.CppExtension(
|
| 116 |
+
"fairseq.ngram_repeat_block_cuda",
|
| 117 |
+
sources=[
|
| 118 |
+
"fairseq/clib/cuda/ngram_repeat_block_cuda.cpp",
|
| 119 |
+
"fairseq/clib/cuda/ngram_repeat_block_cuda_kernel.cu",
|
| 120 |
+
],
|
| 121 |
+
),
|
| 122 |
+
cpp_extension.CppExtension(
|
| 123 |
+
"alignment_train_cuda_binding",
|
| 124 |
+
sources=[
|
| 125 |
+
"examples/operators/alignment_train_kernel.cu",
|
| 126 |
+
"examples/operators/alignment_train_cuda.cpp",
|
| 127 |
+
],
|
| 128 |
+
),
|
| 129 |
+
]
|
| 130 |
+
)
|
| 131 |
+
|
| 132 |
+
cmdclass = {"build_ext": cpp_extension.BuildExtension}
|
| 133 |
+
|
| 134 |
+
if "READTHEDOCS" in os.environ:
|
| 135 |
+
# don't build extensions when generating docs
|
| 136 |
+
extensions = []
|
| 137 |
+
if "build_ext" in cmdclass:
|
| 138 |
+
del cmdclass["build_ext"]
|
| 139 |
+
|
| 140 |
+
# use CPU build of PyTorch
|
| 141 |
+
dependency_links = [
|
| 142 |
+
"https://download.pytorch.org/whl/cpu/torch-1.7.0%2Bcpu-cp36-cp36m-linux_x86_64.whl"
|
| 143 |
+
]
|
| 144 |
+
else:
|
| 145 |
+
dependency_links = []
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
if "clean" in sys.argv[1:]:
|
| 149 |
+
# Source: https://bit.ly/2NLVsgE
|
| 150 |
+
print("deleting Cython files...")
|
| 151 |
+
|
| 152 |
+
subprocess.run(
|
| 153 |
+
["rm -f fairseq/*.so fairseq/**/*.so fairseq/*.pyd fairseq/**/*.pyd"],
|
| 154 |
+
shell=True,
|
| 155 |
+
)
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
extra_packages = []
|
| 159 |
+
if os.path.exists(os.path.join("fairseq", "model_parallel", "megatron", "mpu")):
|
| 160 |
+
extra_packages.append("fairseq.model_parallel.megatron.mpu")
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
def do_setup(package_data):
|
| 164 |
+
setup(
|
| 165 |
+
name="fairseq",
|
| 166 |
+
version=version,
|
| 167 |
+
description="Facebook AI Research Sequence-to-Sequence Toolkit",
|
| 168 |
+
url="https://github.com/pytorch/fairseq",
|
| 169 |
+
classifiers=[
|
| 170 |
+
"Intended Audience :: Science/Research",
|
| 171 |
+
"License :: OSI Approved :: MIT License",
|
| 172 |
+
"Programming Language :: Python :: 3.6",
|
| 173 |
+
"Programming Language :: Python :: 3.7",
|
| 174 |
+
"Programming Language :: Python :: 3.8",
|
| 175 |
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
| 176 |
+
],
|
| 177 |
+
long_description=readme,
|
| 178 |
+
long_description_content_type="text/markdown",
|
| 179 |
+
install_requires=[
|
| 180 |
+
"cffi",
|
| 181 |
+
"cython",
|
| 182 |
+
"hydra-core>=1.0.7,<1.1",
|
| 183 |
+
"omegaconf<2.1",
|
| 184 |
+
"numpy>=1.21.3",
|
| 185 |
+
"regex",
|
| 186 |
+
"sacrebleu>=1.4.12",
|
| 187 |
+
"torch>=1.13",
|
| 188 |
+
"tqdm",
|
| 189 |
+
"bitarray",
|
| 190 |
+
"torchaudio>=0.8.0",
|
| 191 |
+
"scikit-learn",
|
| 192 |
+
"packaging",
|
| 193 |
+
],
|
| 194 |
+
extras_require={
|
| 195 |
+
"dev": ["flake8", "pytest", "black==22.3.0"],
|
| 196 |
+
"docs": ["sphinx", "sphinx-argparse"],
|
| 197 |
+
},
|
| 198 |
+
dependency_links=dependency_links,
|
| 199 |
+
packages=find_packages(
|
| 200 |
+
exclude=[
|
| 201 |
+
"examples",
|
| 202 |
+
"examples.*",
|
| 203 |
+
"scripts",
|
| 204 |
+
"scripts.*",
|
| 205 |
+
"tests",
|
| 206 |
+
"tests.*",
|
| 207 |
+
]
|
| 208 |
+
)
|
| 209 |
+
+ extra_packages,
|
| 210 |
+
package_data=package_data,
|
| 211 |
+
ext_modules=extensions,
|
| 212 |
+
test_suite="tests",
|
| 213 |
+
entry_points={
|
| 214 |
+
"console_scripts": [
|
| 215 |
+
"fairseq-eval-lm = fairseq_cli.eval_lm:cli_main",
|
| 216 |
+
"fairseq-generate = fairseq_cli.generate:cli_main",
|
| 217 |
+
"fairseq-hydra-train = fairseq_cli.hydra_train:cli_main",
|
| 218 |
+
"fairseq-interactive = fairseq_cli.interactive:cli_main",
|
| 219 |
+
"fairseq-preprocess = fairseq_cli.preprocess:cli_main",
|
| 220 |
+
"fairseq-score = fairseq_cli.score:cli_main",
|
| 221 |
+
"fairseq-train = fairseq_cli.train:cli_main",
|
| 222 |
+
"fairseq-validate = fairseq_cli.validate:cli_main",
|
| 223 |
+
],
|
| 224 |
+
},
|
| 225 |
+
cmdclass=cmdclass,
|
| 226 |
+
zip_safe=False,
|
| 227 |
+
)
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
def get_files(path, relative_to="fairseq"):
|
| 231 |
+
all_files = []
|
| 232 |
+
for root, _dirs, files in os.walk(path, followlinks=True):
|
| 233 |
+
root = os.path.relpath(root, relative_to)
|
| 234 |
+
for file in files:
|
| 235 |
+
if file.endswith(".pyc"):
|
| 236 |
+
continue
|
| 237 |
+
all_files.append(os.path.join(root, file))
|
| 238 |
+
return all_files
|
| 239 |
+
|
| 240 |
+
|
| 241 |
+
if __name__ == "__main__":
|
| 242 |
+
try:
|
| 243 |
+
# symlink examples into fairseq package so package_data accepts them
|
| 244 |
+
fairseq_examples = os.path.join("fairseq", "examples")
|
| 245 |
+
if "build_ext" not in sys.argv[1:] and not os.path.exists(fairseq_examples):
|
| 246 |
+
os.symlink(os.path.join("..", "examples"), fairseq_examples)
|
| 247 |
+
|
| 248 |
+
package_data = {
|
| 249 |
+
"fairseq": (
|
| 250 |
+
get_files(fairseq_examples)
|
| 251 |
+
+ get_files(os.path.join("fairseq", "config"))
|
| 252 |
+
)
|
| 253 |
+
}
|
| 254 |
+
do_setup(package_data)
|
| 255 |
+
finally:
|
| 256 |
+
if "build_ext" not in sys.argv[1:] and os.path.islink(fairseq_examples):
|
| 257 |
+
os.unlink(fairseq_examples)
|