Releases: explosion/spaCy
v3.8.7: Python 3.13 support, Cython 3, centralize registry entries
In order to support Python 3.13, spaCy is now compiled with Cython 3. This brings a change to the way types are handled at runtime (Cython 3 uses the from __future__ import annotations
semantics, which stores types as strings at runtime. This difference caused problems for components registered within Cython files, as we rely on building Pydantic models from factory function signatures to do validation.
To support Python 3.13 we therefore create a new module, spacy.pipeline.factories
, which contains the factory function implementations. __getattr__
import shims have been added to the previous locations of these functions to prevent backwards incompatibilities.
As well as moving the factories, the new implementation avoids import-time side-effects, by moving the actual calls to the decorator inside a function, which is executed once when the Language
class is initialised.
A matching change has been made to the catalogue registry decorators. A new module spacy.registrations
has been created that performs all the catalogue registrations. Moving these registrations away from the functions prevents these decorators from running at import time. This change was not necessary for the Python 3.13 support, but it means we no longer rely on any import-time side-effects, which will allow us to improve spaCy's import time and therefore CLI execution time. The change also makes maintenance easier as it's easier to find the implementations of different registry functions (this may help library users as well).
v3.8.6: Restore wheels, remove Python 3.13 compatibility
Restores support for wheels for ARM platforms, while correctly noting compatibility range.
v3.8.3: Improve memory zone stability
Fix bug in memory zones when non-transient strings were added to the StringStore inside a memory zone. This caused a bug in the morphological analyser that caused string not found errors when applied during a memory zone.
v3.8: Memory management for persistent services, numpy 2.0 support
Optional memory management for persistent services
Support a new context manager method Language.memory_zone()
, to allow long-running services to avoid growing memory usage from cached entries in the Vocab
or StringStore
. Once the memory zone block ends, spaCy will evict Vocab
and StringStore
entries that were added during the block, freeing up memory. Doc
objects created inside a memory zone block should not be accessed outside the block.
The current implementation disables population of the tokenizer cache inside the memory zone, resulting in some performance impact. The performance difference will likely be negligible if you're running a full pipeline, but if you're only running the tokenizer, it'll be much slower. If this is a problem, you can mitigate it by warming the cache first, by processing the first few batches of text without creating a memory zone. Support for memory zones in the tokenizer will be added in a future update.
The Language.memory_zone()
context manager also checks for a memory_zone()
method on pipeline components, so that components can perform similar memory management if necessary. None of the built-in components currently require this.
If you component needs to add non-transient entries to the StringStore
or Vocab
, you can pass the allow_transient=False
flag to the Vocab.add()
or StringStore.add()
components.
Example usage:
import spacy
import json
from pathlib import Path
from typing import Iterator
from collections import Counter
import typer
from spacy.util import minibatch
def texts(path: Path) -> Iterator[str]:
with path.open("r", encoding="utf8") as file_:
for line in file_:
yield json.loads(line)["text"]
def main(jsonl_path: Path) -> None:
nlp = spacy.load("en_core_web_sm")
counts = Counter()
batches = minibatch(texts(jsonl_path), 1000)
for i, batch in enumerate(batches):
print("Batch", i)
with nlp.memory_zone():
for doc in nlp.pipe(batch):
for token in doc:
counts[token.text] += 1
for word, count in counts.most_common(100):
print(count, word)
if __name__ == "__main__":
typer.run(main)
Numpy v2 compatibility
Numpy 2.0 isn't binary-compatible with numpy v1, so we need to build against one or the other. This release isolates the dependency change and has no other changes, to make things easier if the dependency change causes problems.
This dependency change was previously attempted in version 3.7.6, but dependencies within the v3.7 family of models resulted in some conflicts, and some packages depending on numpy v1 were incompatible with v3.7.6. I've therefore removed the 3.7.6 release and replaced it with this one, which increments the minor version.
Model packages no longer list spacy as a requirement
I've also made a change to the way models are packaged to make it easier to release more quickly. Previously spaCy models specified a versioned requirement on spacy itself. This meant that there was no way to increment the spaCy version and have it work with the existing models, because the models would specify they were only compatible with spacy>=3.7.0,<3.8.0
. We have a compatibility table that allows spacy to see which models are compatible, but the models themselves can't know which future versions of spaCy they work with.
I've therefore added a flag --require-parent/--no-require-parent
to the spacy package
CLI, which controls where the parent package (e.g. spaCy) should be listed as a requirement of the model. --require-parent
is the default for v3.8, but this will change to --no-require-parent
by default in v4. I've set --no-require-parent
for the v3.8 models, so that further changes can be published that don't impact the models, without retraining the models or forcing users to redownload them.
Optional memory management for persistent services
Support a new context manager method Language.memory_zone()
, to allow long-running services to avoid growing memory usage from cached entries in the Vocab
or StringStore
. Once the memory zone block ends, spaCy will evict Vocab
and StringStore
entries that were added during the block, freeing up memory. Doc
objects created inside a memory zone block should not be accessed outside the block.
The current implementation disables population of the tokenizer cache inside the memory zone, resulting in some performance impact. The performance difference will likely be negligible if you're running a full pipeline, but if you're only running the tokenizer, it'll be much slower. If this is a problem, you can mitigate it by warming the cache first, by processing the first few batches of text without creating a memory zone. Support for memory zones in the tokenizer will be added in a future update.
The Language.memory_zone()
context manager also checks for a memory_zone()
method on pipeline components, so that components can perform similar memory management if necessary. None of the built-in components currently require this.
If you component needs to add non-transient entries to the StringStore
or Vocab
, you can pass the allow_transient=False
flag to the Vocab.add()
or StringStore.add()
components.
Example usage:
import spacy
import json
from pathlib import Path
from typing import Iterator
from collections import Counter
import typer
from spacy.util import minibatch
def texts(path: Path) -> Iterator[str]:
with path.open("r", encoding="utf8") as file_:
for line in file_:
yield json.loads(line)["text"]
def main(jsonl_path: Path) -> None:
nlp = spacy.load("en_core_web_sm")
counts = Counter()
batches = minibatch(texts(jsonl_path), 1000)
for i, batch in enumerate(batches):
print("Batch", i)
with nlp.vocab.memory_zone():
for doc in nlp.pipe(batch):
for token in doc:
counts[token.text] += 1
for word, count in counts.most_common(100):
print(count, word)
if __name__ == "__main__":
typer.run(main)```
v3.7.6a: Test pypi release process
prerelease-v3.7.6a Try to import cibuildwheel settings from previous setup
v3.7.5: Download sanitization, Typer compatibility, and a bugfix for linking gold entities
✨ New features and improvements
- Sanitize direct download for
spacy download
(#13313). - Convert Cython properties to decorator syntax (#13390).
- Bump Weasel pin to allow v0.4.x (#13409).
- Improvements to the test suite (#13469, #13470).
- Bump Typer pin to allow v0.10.0 and above (#13471).
- Allow
typing-extensions<5.0.0
for Python < 3.8 (#13516).
🔴 Bug fixes
- #13400: Fix
use_gold_ents
behaviour for EntityLinker.
📖 Documentation and examples
- Make the file name for code listings stick to the top (#13379).
- Update the documentation of
MorphAnalysis
(#13433). - Typo fixes in the documentation (#13466).
👥 Contributors
@danieldk, @honnibal, @ines, @JoeSchiff, @nokados, @Paillat-dev, @rmitsch, @schorfma, @strickvl, @svlandeg, @ynx0
v3.7.4: New textcat layers and fo/nn language extensions
✨ New features and improvements
- Improve NumPy 2.0 compatibility (#13103).
- Added language extensions for Faroese and Norwegian Nynorsk (#13116).
- Add new
TextCatReduce.v1
layer for text classification (#13181). - Add new
TextCatParametricAttention.v1
layer for text classification (#13201). - Use
build
module for creating model packages by default (#13109). - Add support for code loading to the
benchmark speed
command (#13247). - Extend lexical attributes for English with more numericals (#13106).
- Warn about reloading dependencies after downloading models (#13081).
🔴 Bug fixes
- #13259, #13304, #13321: Correctness fixes for multiprocessing support in
Language.pipe
. - #13187: Typing and documentation fixes for
Doc
. - #13086: Update
Tokenizer.explain
for special cases with whitespace. - #13068: Fix displaCy span stacking.
- #13149: Add spacy.TextCatBOW.v3 to use the fixed
SparseLinear
layer.
📖 Documentation and examples
- Many improvements and updates to the LLM documentation.
- Update
trf_data
examples and the transformer pipeline design section.
👥 Contributors
@adrianeboyd, @danieldk, @evornov, @honnibal, @ines, @lise-brinck, @ridge-kimani, @rmitsch, @shadeMe, @svlandeg
v3.7.2: Fixes for APIs and requirements
✨ New features and improvements
- Update
__all__
fields (#13063).
🔴 Bug fixes
- #13035: Remove Pathy requirement.
- #13053: Restore
spacy.cli.project
API. - #13057: Support
Any
comparisons forToken
andSpan
.
📖 Documentation and examples
- Many updates for
spacy-llm
including Azure OpenAI, PaLM, and Mistral support. - Various documentation corrections.
👥 Contributors
v3.7.1: Bug fix for spacy.cli module loading
🔴 Bug fixes
- Revert lazy loading of CLI module for
spacy.info
to fix availability ofspacy.cli
followingimport spacy
(#13040).