Skip to content

Commit a80d275

Browse files
authored
Merge pull request #764 from shadeMe/chore/merge-master-into-v9
Merge `master` into `v9`
2 parents 64967eb + b0c9be8 commit a80d275

File tree

15 files changed

+124
-2330
lines changed

15 files changed

+124
-2330
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Thinc: A refreshing functional take on deep learning, compatible with your favorite libraries
44

5-
### From the makers of [spaCy](https://spacy.io), [Prodigy](https://prodi.gy) and [FastAPI](https://fastapi.tiangolo.com)
5+
### From the makers of [spaCy](https://spacy.io) and [Prodigy](https://prodi.gy)
66

77
[Thinc](https://thinc.ai) is a **lightweight deep learning library** that offers an elegant,
88
type-checked, functional-programming API for **composing models**, with support

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
imageName: 'windows-2019'
2424
python.version: '3.6'
2525
Python37Mac:
26-
imageName: 'macos-10.15'
26+
imageName: 'macos-latest'
2727
python.version: '3.7'
2828
Python38Linux:
2929
imageName: 'ubuntu-latest'

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ nbformat>=5.0.4,<5.2.0
3434
# Test to_disk/from_disk against pathlib.Path subclasses
3535
pathy>=0.3.5
3636
black>=22.0,<23.0
37+
confection>=0.0.1,<1.0.0

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ install_requires =
4545
wasabi>=0.8.1,<1.1.0
4646
srsly>=2.4.0,<3.0.0
4747
catalogue>=2.0.4,<2.1.0
48+
confection>=0.0.1,<1.0.0
4849
# Third-party dependencies
4950
setuptools
5051
numpy>=1.15.0

thinc/about.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version__ = "8.1.0"
1+
__version__ = "8.1.1"
22
__release__ = True

thinc/config.py

Lines changed: 3 additions & 1035 deletions
Large diffs are not rendered by default.

thinc/layers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
from .list2padded import list2padded
6060
from .ragged2list import ragged2list
6161
from .padded2list import padded2list
62-
from .remap_ids import remap_ids
62+
from .remap_ids import remap_ids, remap_ids_v2
6363
from .strings2arrays import strings2arrays
6464
from .with_array import with_array
6565
from .with_array2d import with_array2d

thinc/layers/remap_ids.py

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
from typing import Tuple, Callable, Sequence, Dict, Any
1+
from typing import Tuple, Callable, Sequence, cast
2+
from typing import Dict, Union, Optional, Hashable, Any
23

34
from ..model import Model
45
from ..config import registry
5-
from ..types import Ints2d, DTypes
6+
from ..types import Ints1d, Ints2d, DTypes
7+
from ..util import is_xp_array, to_numpy
68

79

8-
InT = Sequence[Any]
10+
InT = Union[Sequence[Hashable], Ints1d, Ints2d]
911
OutT = Ints2d
1012

13+
InT_v1 = Sequence[Any]
14+
OutT_v1 = Ints2d
15+
1116

1217
@registry.layers("remap_ids.v1")
1318
def remap_ids(
1419
mapping_table: Dict[Any, int] = {}, default: int = 0, dtype: DTypes = "i"
15-
) -> Model[InT, OutT]:
20+
) -> Model[InT_v1, OutT_v1]:
1621
"""Remap string or integer inputs using a mapping table, usually as a
1722
preprocess before embeddings. The mapping table can be passed in on input,
1823
or updated after the layer has been created. The mapping table is stored in
@@ -26,7 +31,7 @@ def remap_ids(
2631

2732

2833
def forward(
29-
model: Model[InT, OutT], inputs: InT, is_train: bool
34+
model: Model[InT_v1, OutT_v1], inputs: InT_v1, is_train: bool
3035
) -> Tuple[OutT, Callable]:
3136
table = model.attrs["mapping_table"]
3237
default = model.attrs["default"]
@@ -35,7 +40,60 @@ def forward(
3540
arr = model.ops.asarray2i(values, dtype=dtype)
3641
output = model.ops.reshape2i(arr, -1, 1)
3742

38-
def backprop(dY: OutT) -> InT:
43+
def backprop(dY: OutT_v1) -> InT:
3944
return []
4045

4146
return output, backprop
47+
48+
49+
@registry.layers("remap_ids.v2")
50+
def remap_ids_v2(
51+
mapping_table: Optional[Union[Dict[int, int], Dict[str, int]]] = None,
52+
default: int = 0,
53+
*,
54+
column: Optional[int] = None
55+
) -> Model[InT, OutT]:
56+
"""Remap string or integer inputs using a mapping table,
57+
usually as a preprocessing step before embeddings.
58+
The mapping table can be passed in on input,
59+
or updated after the layer has been created.
60+
The mapping table is stored in the "mapping_table" attribute.
61+
Two dimensional arrays can be provided as input in which case
62+
the 'column' chooses which column to process. This is useful
63+
to work together with FeatureExtractor in spaCy.
64+
"""
65+
return Model(
66+
"remap_ids",
67+
forward_v2,
68+
attrs={"mapping_table": mapping_table, "default": default, "column": column},
69+
)
70+
71+
72+
def forward_v2(
73+
model: Model[InT, OutT], inputs: InT, is_train: bool
74+
) -> Tuple[OutT, Callable]:
75+
table = model.attrs["mapping_table"]
76+
if table is None:
77+
raise ValueError("'mapping table' not set")
78+
default = model.attrs["default"]
79+
column = model.attrs["column"]
80+
if is_xp_array(inputs):
81+
xp_input = True
82+
if column is not None:
83+
idx = to_numpy(cast(Ints2d, inputs)[:, column])
84+
else:
85+
idx = to_numpy(inputs)
86+
else:
87+
xp_input = False
88+
idx = inputs
89+
values = [table.get(x, default) for x in idx]
90+
arr = model.ops.asarray2i(values, dtype="i")
91+
output = model.ops.reshape2i(arr, -1, 1)
92+
93+
def backprop(dY: OutT) -> InT:
94+
if xp_input:
95+
return model.ops.xp.empty(dY.shape) # type: ignore
96+
else:
97+
return []
98+
99+
return output, backprop

thinc/shims/pytorch_grad_scaler.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,11 @@ def __init__(
5151
self._backoff_factor = backoff_factor
5252
self._growth_interval = growth_interval
5353

54-
self._found_inf = torch.full((1,), 0.0)
5554
self._growth_tracker = torch.full((1,), 0, dtype=torch.int)
5655
self._scale = torch.full((1,), init_scale)
56+
self._found_inf = False
5757

5858
def to_(self, device):
59-
self._found_inf = self._found_inf.to(device)
6059
self._growth_tracker = self._growth_tracker.to(device)
6160
self._scale = self._scale.to(device)
6261

@@ -132,7 +131,7 @@ def _tensors_per_device(self, tensors):
132131

133132
@property
134133
def found_inf(self):
135-
return bool(self._found_inf) != 0
134+
return self._found_inf
136135

137136
def unscale(self, tensors):
138137
"""Unscale the given tensors. Returns True if any of the gradients were infinite."""
@@ -152,9 +151,10 @@ def unscale(self, tensors):
152151
device_tensors, found_inf_device, inv_scale_device
153152
)
154153

155-
self._found_inf += found_inf_device.to(self._found_inf.device)
154+
if bool(found_inf_device != 0):
155+
self._found_inf = True
156156

157-
return bool(self._found_inf != 0)
157+
return self._found_inf
158158

159159
def update(self):
160160
"""
@@ -165,14 +165,17 @@ def update(self):
165165
if not self._enabled:
166166
return
167167

168+
found_inf_device = torch.full(
169+
(1,), 1.0 if self._found_inf else 0.0, device=self._scale.device
170+
)
168171
torch._amp_update_scale_(
169172
self._scale,
170173
self._growth_tracker,
171-
self._found_inf,
174+
found_inf_device,
172175
self._growth_factor,
173176
self._backoff_factor,
174177
self._growth_interval,
175178
)
176179

177180
# Clear infinity found status
178-
self._found_inf = torch.zeros_like(self._found_inf)
181+
self._found_inf = False

thinc/tests/layers/test_layers_api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ def assert_data_match(Y, out_data):
128128
# ("CauchySimilarity.v1", {}, (array2d, array2d), array1d),
129129
("ParametricAttention.v1", {}, ragged, ragged),
130130
("SparseLinear.v1", {}, (numpy.asarray([1, 2, 3], dtype="uint64"), array1d, numpy.asarray([1, 1], dtype="i")), array2d),
131-
("remap_ids.v1", {"dtype": "f"}, ["a", 1, 5.0], array2dint)
131+
("remap_ids.v1", {"dtype": "f"}, ["a", 1, 5.0], array2dint),
132+
("remap_ids.v2", {"mapping_table": {}, "column": 1}, numpy.array([[1, 2, 3], [4, 5, 6]]).T, array2dint)
132133
# fmt: on
133134
]
134135

0 commit comments

Comments
 (0)