Skip to content

Commit 56e63b1

Browse files
committed
Use activations stored by the senter pipe
Before this change, we'd use the senter pipe directly. However, this did not work with the transformer model without modifications (because it clears tensors after backprop). By using the functionality proposed in explosion/spaCy#11002 we can use the activations that are stored by the senter pipe in `Doc`.
1 parent bb64977 commit 56e63b1

2 files changed

Lines changed: 10 additions & 6 deletions

File tree

projects/biaffine_parser/configs/base-config.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pooling = {"@layers":"reduce_mean.v1"}
3434

3535
[components.arc_predicter]
3636
factory = "experimental_arc_predicter"
37+
senter = "senter"
3738

3839
[components.arc_predicter.model]
3940
@architectures = "spacy-experimental.PairwiseBilinear.v1"
@@ -78,6 +79,7 @@ pooling = {"@layers":"reduce_mean.v1"}
7879

7980
[components.senter]
8081
factory = "senter"
82+
store_activations = true
8183

8284
[components.senter.model]
8385
@architectures = "spacy.Tagger.v1"

spacy_experimental/biaffine_parser/arc_predicter.pyx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class ArcPredicter(TrainablePipe):
162162
docs = list(docs)
163163

164164
if self.senter:
165-
lengths = split_greedily(docs, ops=self.model.ops, max_length=self.max_length, senter=self.senter, is_train=False)
165+
lengths = split_lazily(docs, ops=self.model.ops, max_length=self.max_length, senter=self.senter, is_train=False)
166166
else:
167167
lengths = sents2lens(docs, ops=self.model.ops)
168168
scores = self.model.predict((docs, lengths))
@@ -224,7 +224,7 @@ class ArcPredicter(TrainablePipe):
224224
docs = [eg.predicted for eg in examples]
225225

226226
if self.senter:
227-
lens = split_greedily(docs, ops=self.model.ops, max_length=self.max_length, senter=self.senter, is_train=True)
227+
lens = split_lazily(docs, ops=self.model.ops, max_length=self.max_length, senter=self.senter, is_train=True)
228228
else:
229229
lens = sents2lens(docs, ops=self.model.ops)
230230
if lens.sum() == 0:
@@ -316,11 +316,13 @@ def sents2lens(docs: List[Doc], *, ops: Ops) -> Ints1d:
316316

317317
return ops.asarray1i(lens)
318318

319-
def split_greedily(docs: List[Doc], *, ops: Ops, max_length: int, senter: SentenceRecognizer, is_train: bool):
320-
split_predictions, _ = senter.model(docs, is_train)
321-
319+
def split_lazily(docs: List[Doc], *, ops: Ops, max_length: int, senter: SentenceRecognizer, is_train: bool) -> Ints1d:
322320
lens = []
323-
for (doc, scores) in zip(docs, split_predictions):
321+
for doc in docs:
322+
activations = doc.activations.get(senter.name, None)
323+
if activations is None:
324+
raise ValueError("Greedy splitting requires senter with `store_activations` enabled.")
325+
scores = activations['probs']
324326
split_recursive(scores[:,1], ops, max_length, lens)
325327

326328
assert sum(lens) == sum([len(doc) for doc in docs])

0 commit comments

Comments
 (0)