Skip to content

Commit 96237c7

Browse files
authored
Merge pull request #416 from explosion/develop
Synch `main` with `develop`
2 parents 0cb81d2 + 377b1d4 commit 96237c7

141 files changed

Lines changed: 6777 additions & 1157 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ jobs:
2424
os: [ubuntu-latest, windows-latest, macos-latest]
2525
python_version: ["3.11"]
2626
include:
27-
- os: ubuntu-20.04
28-
python_version: "3.6"
2927
- os: windows-latest
3028
python_version: "3.7"
3129
- os: macos-latest

.github/workflows/test_gpu.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: GPU tests
22

33
on:
4-
schedule:
5-
- cron: "0 0 * * *"
4+
# schedule:
5+
# - cron: "0 0 * * *"
66
issue_comment:
77
types: [created]
88
workflow_dispatch:

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<a href="https://explosion.ai"><img src="https://explosion.ai/assets/img/logo.svg" width="125" height="125" align="right" /></a>
2+
<a href="https://explosion.ai"><img src="assets/logo.png" width="125" height="125" align="left" style="margin-right:30px" /></a>
23

3-
# spacy-llm: Integrating LLMs into structured NLP pipelines
4+
<h1 align="center">
5+
<span style="font: bold 38pt'Courier New';">spacy-llm</span>
6+
<br>Structured NLP with LLMs
7+
</h1>
8+
<br><br>
49

510
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/explosion/spacy-llm/test.yml?branch=main)](https://github.com/explosion/spacy-llm/actions/workflows/test.yml)
611
[![pypi Version](https://img.shields.io/pypi/v/spacy-llm.svg?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/spacy-llm/)
@@ -16,7 +21,8 @@ This package integrates Large Language Models (LLMs) into [spaCy](https://spacy.
1621
- **[OpenAI](https://platform.openai.com/docs/api-reference/)**
1722
- **[Cohere](https://docs.cohere.com/reference/generate)**
1823
- **[Anthropic](https://docs.anthropic.com/claude/reference/)**
19-
- **[PaLM](https://ai.google/discover/palm2/)**
24+
- **[Google PaLM](https://ai.google/discover/palm2/)**
25+
- **[Microsoft Azure AI](https://azure.microsoft.com/en-us/solutions/ai)**
2026
- Supports open-source LLMs hosted on Hugging Face 🤗:
2127
- **[Falcon](https://huggingface.co/tiiuae)**
2228
- **[Dolly](https://huggingface.co/databricks)**
@@ -33,10 +39,13 @@ This package integrates Large Language Models (LLMs) into [spaCy](https://spacy.
3339
- Sentiment analysis
3440
- Span categorization
3541
- Summarization
42+
- Entity linking
43+
- Translation
44+
- Raw prompt execution for maximum flexibility
3645
- Soon:
37-
- Entity linking
3846
- Semantic role labeling
3947
- Easy implementation of **your own functions** via [spaCy's registry](https://spacy.io/api/top-level#registry) for custom prompting, parsing and model integrations
48+
- Map-reduce approach for splitting prompts too long for LLM's context window and fusing the results back together
4049

4150
## 🧠 Motivation
4251

assets/logo.png

866 KB
Loading

setup.cfg

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ classifiers =
1616
Operating System :: MacOS :: MacOS X
1717
Operating System :: Microsoft :: Windows
1818
Programming Language :: Python :: 3
19-
Programming Language :: Python :: 3.6
2019
Programming Language :: Python :: 3.7
2120
Programming Language :: Python :: 3.8
2221
Programming Language :: Python :: 3.9
@@ -30,7 +29,7 @@ project_urls =
3029
[options]
3130
zip_safe = false
3231
include_package_data = true
33-
python_requires = >=3.6
32+
python_requires = >=3.7
3433
install_requires =
3534
spacy>=3.5,<4.0
3635
jinja2

spacy_llm/cache.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from spacy.vocab import Vocab
99

1010
from .registry import registry
11-
from .ty import LLMTask, PromptTemplateProvider
11+
from .ty import PromptTemplateProvider, ShardingLLMTask
1212

1313

1414
@registry.llm_misc("spacy.BatchCache.v1")
@@ -68,11 +68,11 @@ def __init__(
6868

6969
self._init_cache_dir()
7070

71-
def initialize(self, vocab: Vocab, task: LLMTask) -> None:
71+
def initialize(self, vocab: Vocab, task: ShardingLLMTask) -> None:
7272
"""
7373
Initialize cache with data not available at construction time.
7474
vocab (Vocab): Vocab object.
75-
task (LLMTask): Task.
75+
task (ShardingLLMTask): Task.
7676
"""
7777
self._vocab = vocab
7878
if isinstance(task, PromptTemplateProvider):

spacy_llm/compat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,7 @@
5757
if PYDANTIC_V2:
5858
from pydantic.v1 import BaseModel, ExtraError, ValidationError # noqa: F401
5959
from pydantic.v1 import validator
60+
from pydantic.v1.generics import GenericModel # noqa: F401
6061
else:
6162
from pydantic import BaseModel, ExtraError, ValidationError, validator # noqa: F401
63+
from pydantic.generics import GenericModel # noqa: F401

spacy_llm/models/hf/base.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,18 @@ def __init__(
1717
name: str,
1818
config_init: Optional[Dict[str, Any]],
1919
config_run: Optional[Dict[str, Any]],
20+
context_length: Optional[int],
2021
):
2122
"""Initializes HF model instance.
2223
query (Callable[[Any, Iterable[Any]], Iterable[Any]): Callable executing LLM prompts when
2324
supplied with the `integration` object.
2425
name (str): Name of HF model to load (without account name).
2526
config_init (Optional[Dict[str, Any]]): HF config for initializing the model.
2627
config_run (Optional[Dict[str, Any]]): HF config for running the model.
27-
inference_config (Dict[Any, Any]): HF config for model run.
28+
context_length (Optional[int]): Context length for this model. Necessary for sharding.
2829
"""
2930
self._name = name if self.hf_account in name else f"{self.hf_account}/{name}"
31+
self._context_length = context_length
3032
default_cfg_init, default_cfg_run = self.compile_default_configs()
3133
self._config_init, self._config_run = default_cfg_init, default_cfg_run
3234

@@ -73,10 +75,10 @@ def __init__(
7375
self._model = self.init_model()
7476

7577
@abc.abstractmethod
76-
def __call__(self, prompts: Iterable[Any]) -> Iterable[Any]:
78+
def __call__(self, prompts: Iterable[Iterable[Any]]) -> Iterable[Iterable[Any]]:
7779
"""Executes prompts on specified API.
78-
prompts (Iterable[Any]): Prompts to execute.
79-
RETURNS (Iterable[Any]): API responses.
80+
prompts (Iterable[Iterable[Any]]): Prompts to execute per doc.
81+
RETURNS (Iterable[Iterable[Any]]): API responses per doc.
8082
"""
8183

8284
def _check_model(self) -> None:
@@ -93,6 +95,13 @@ def get_model_names(cls) -> Tuple[str, ...]:
9395
"""
9496
return tuple(str(arg) for arg in cls.MODEL_NAMES.__args__) # type: ignore[attr-defined]
9597

98+
@property
99+
def context_length(self) -> Optional[int]:
100+
"""Returns context length in number of tokens for this model.
101+
RETURNS (Optional[int]): Max. number of tokens allowed in prompt for the current model.
102+
"""
103+
return self._context_length
104+
96105
@property
97106
@abc.abstractmethod
98107
def hf_account(self) -> str:

spacy_llm/models/hf/dolly.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@ def init_model(self) -> Any:
1818
model=self._name, return_full_text=False, **self._config_init
1919
)
2020

21-
def __call__(self, prompts: Iterable[str]) -> Iterable[str]: # type: ignore[override]
21+
def __call__(self, prompts: Iterable[Iterable[str]]) -> Iterable[Iterable[str]]: # type: ignore[override]
2222
"""Queries Dolly HF model.
2323
pipeline (transformers.pipeline): Transformers pipeline to query.
24-
prompts (Iterable[str]): Prompts to query Dolly model with.
25-
RETURNS (Iterable[str]): Prompt responses.
24+
prompts (Iterable[Iterable[str]]): Prompts per doc to query Dolly model with.
25+
RETURNS (Iterable[Iterable[str]]): Prompt responses per doc.
2626
"""
2727
return [
28-
self._model(pr, **self._config_run)[0]["generated_text"] for pr in prompts
28+
[
29+
self._model(pr, **self._config_run)[0]["generated_text"]
30+
for pr in prompts_for_doc
31+
]
32+
for prompts_for_doc in prompts
2933
]
3034

3135
@property
@@ -52,12 +56,14 @@ def dolly_hf(
5256
name: Dolly.MODEL_NAMES,
5357
config_init: Optional[Dict[str, Any]] = SimpleFrozenDict(),
5458
config_run: Optional[Dict[str, Any]] = SimpleFrozenDict(),
55-
) -> Callable[[Iterable[str]], Iterable[str]]:
59+
) -> Callable[[Iterable[Iterable[str]]], Iterable[Iterable[str]]]:
5660
"""Generates Dolly instance that can execute a set of prompts and return the raw responses.
5761
name (Literal): Name of the Dolly model. Has to be one of Dolly.get_model_names().
5862
config_init (Optional[Dict[str, Any]]): HF config for initializing the model.
5963
config_run (Optional[Dict[str, Any]]): HF config for running the model.
6064
RETURNS (Callable[[Iterable[str]], Iterable[str]]): Dolly instance that can execute a set of prompts and return
6165
the raw responses.
6266
"""
63-
return Dolly(name=name, config_init=config_init, config_run=config_run)
67+
return Dolly(
68+
name=name, config_init=config_init, config_run=config_run, context_length=2048
69+
)

spacy_llm/models/hf/falcon.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ def __init__(
1717
name: MODEL_NAMES,
1818
config_init: Optional[Dict[str, Any]],
1919
config_run: Optional[Dict[str, Any]],
20+
context_length: Optional[int],
2021
):
2122
self._tokenizer: Optional["transformers.AutoTokenizer"] = None
22-
super().__init__(name=name, config_init=config_init, config_run=config_run)
23+
super().__init__(
24+
name=name,
25+
config_init=config_init,
26+
config_run=config_run,
27+
context_length=context_length,
28+
)
2329

2430
assert isinstance(self._tokenizer, transformers.PreTrainedTokenizerBase)
2531
self._config_run["pad_token_id"] = self._tokenizer.pad_token_id
@@ -45,10 +51,15 @@ def init_model(self) -> Any:
4551
def hf_account(self) -> str:
4652
return "tiiuae"
4753

48-
def __call__(self, prompts: Iterable[str]) -> Iterable[str]: # type: ignore[override]
54+
def __call__(self, prompts: Iterable[Iterable[str]]) -> Iterable[Iterable[str]]: # type: ignore[override]
4955
return [
50-
self._model(pr, generation_config=self._hf_config_run)[0]["generated_text"]
51-
for pr in prompts
56+
[
57+
self._model(pr, generation_config=self._hf_config_run)[0][
58+
"generated_text"
59+
]
60+
for pr in prompts_for_doc
61+
]
62+
for prompts_for_doc in prompts
5263
]
5364

5465
@staticmethod
@@ -68,12 +79,14 @@ def falcon_hf(
6879
name: Falcon.MODEL_NAMES,
6980
config_init: Optional[Dict[str, Any]] = SimpleFrozenDict(),
7081
config_run: Optional[Dict[str, Any]] = SimpleFrozenDict(),
71-
) -> Callable[[Iterable[str]], Iterable[str]]:
82+
) -> Callable[[Iterable[Iterable[str]]], Iterable[Iterable[str]]]:
7283
"""Generates Falcon instance that can execute a set of prompts and return the raw responses.
7384
name (Literal): Name of the Falcon model. Has to be one of Falcon.get_model_names().
7485
config_init (Optional[Dict[str, Any]]): HF config for initializing the model.
7586
config_run (Optional[Dict[str, Any]]): HF config for running the model.
7687
RETURNS (Callable[[Iterable[str]], Iterable[str]]): Falcon instance that can execute a set of prompts and return
7788
the raw responses.
7889
"""
79-
return Falcon(name=name, config_init=config_init, config_run=config_run)
90+
return Falcon(
91+
name=name, config_init=config_init, config_run=config_run, context_length=2048
92+
)

0 commit comments

Comments
 (0)