aidial-rag-eval 0.6.0.dev16__tar.gz → 0.6.0.dev20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/PKG-INFO +41 -12
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/README.md +37 -8
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/pyproject.toml +5 -4
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/metrics.py +33 -19
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/evaluate.py +0 -2
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/inference.py +45 -44
- aidial_rag_eval-0.6.0.dev20/src/aidial_rag_eval/generation/metric_binds.py +125 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/refusal.py +1 -7
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/types.py +19 -6
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/segmented_text.py +38 -9
- aidial_rag_eval-0.6.0.dev20/src/aidial_rag_eval/metric_binds.py +19 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/types.py +3 -5
- aidial_rag_eval-0.6.0.dev16/src/aidial_rag_eval/generation/metric_binds.py +0 -174
- aidial_rag_eval-0.6.0.dev16/src/aidial_rag_eval/metric_binds.py +0 -15
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/LICENSE +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/match_facts.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/merge.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataset.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/citation.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/exact.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/match_str_facts.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/converters/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/converters/base_converter.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/converters/decontextualization_template.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/converters/llm_decontextualization_converter.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/inference_scorers/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/inference_scorers/base_inference_scorer.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/inference_scorers/inference_template.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/inference_scorers/llm_inference_scorer.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/lambdas.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/refusal_detectors/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/refusal_detectors/base_refusal_detector.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/refusal_detectors/llm_refusal_detector.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/refusal_detectors/refusal_template.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/statement_extractor/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/statement_extractor/base_statement_extractor.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/statement_extractor/llm_statement_extractor.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/statement_extractor/statement_extractor_template.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/exceptions.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/progress_bar.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/metrics.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/metrics.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/types.py +0 -0
- {aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/utils.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aidial-rag-eval
|
|
3
|
-
Version: 0.6.0.
|
|
3
|
+
Version: 0.6.0.dev20
|
|
4
4
|
Summary: Library for RAG evaluation
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: ai
|
|
8
8
|
Author: EPAM RAIL
|
|
9
9
|
Author-email: SpecialEPM-DIALDevTeam@epam.com
|
|
10
|
-
Requires-Python: >=3.11,<
|
|
10
|
+
Requires-Python: >=3.11,<3.15
|
|
11
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -19,12 +19,12 @@ Provides-Extra: s3fs
|
|
|
19
19
|
Requires-Dist: fsspec (>=2024.3.1,<2025.0.0)
|
|
20
20
|
Requires-Dist: langchain-core (>=0.3.80,<2)
|
|
21
21
|
Requires-Dist: more-itertools (>=10.5.0,<11.0.0)
|
|
22
|
-
Requires-Dist: nltk (>=3.8.1,<4.0.0)
|
|
23
22
|
Requires-Dist: numpy (>=1.26.4,<3)
|
|
24
23
|
Requires-Dist: pandas (>=2.2.2,<3.0.0)
|
|
25
24
|
Requires-Dist: pyarrow (>=20.0.0)
|
|
26
|
-
Requires-Dist: pydantic (>=2.7.1
|
|
25
|
+
Requires-Dist: pydantic (>=2.7.1)
|
|
27
26
|
Requires-Dist: s3fs (>=2024.3.1,<2025.0.0) ; extra == "s3fs"
|
|
27
|
+
Requires-Dist: spacy (>=3.8.9,<4)
|
|
28
28
|
Requires-Dist: tqdm (>=4.66.4,<5.0.0)
|
|
29
29
|
Project-URL: Documentation, https://github.com/epam/ai-dial-rag-eval
|
|
30
30
|
Project-URL: Homepage, https://github.com/epam/ai-dial-rag-eval
|
|
@@ -47,6 +47,27 @@ Install the library using [pip](https://pip.pypa.org/en/stable/getting-started):
|
|
|
47
47
|
pip install aidial-rag-eval
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
### spaCy language model
|
|
51
|
+
|
|
52
|
+
The generation metrics require the English language model for [spaCy](https://spacy.io/).
|
|
53
|
+
Download it after installation:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
python -m spacy download en_core_web_sm
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Alternatively, you can install the model directly via URL:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
pip install https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or as a [Poetry](https://python-poetry.org/) dependency:
|
|
66
|
+
|
|
67
|
+
```toml
|
|
68
|
+
en-core-web-sm = {url = "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl"}
|
|
69
|
+
```
|
|
70
|
+
|
|
50
71
|
### Example
|
|
51
72
|
|
|
52
73
|
The example of how to get retrieval metrics along with answer inference based on the context.
|
|
@@ -56,7 +77,8 @@ import pandas as pd
|
|
|
56
77
|
from langchain_openai import AzureChatOpenAI
|
|
57
78
|
from aidial_rag_eval import create_rag_eval_metrics_report
|
|
58
79
|
from aidial_rag_eval.metric_binds import CONTEXT_TO_ANSWER_INFERENCE,\
|
|
59
|
-
ANSWER_TO_GROUND_TRUTH_INFERENCE, GROUND_TRUTH_TO_ANSWER_INFERENCE
|
|
80
|
+
ANSWER_TO_GROUND_TRUTH_INFERENCE, GROUND_TRUTH_TO_ANSWER_INFERENCE,\
|
|
81
|
+
ANSWER_TO_FACTS_INFERENCE, FACTS_TO_ANSWER_INFERENCE
|
|
60
82
|
|
|
61
83
|
llm = AzureChatOpenAI(model="gemini-2.5-flash-lite")
|
|
62
84
|
|
|
@@ -87,16 +109,18 @@ df_metrics = create_rag_eval_metrics_report(
|
|
|
87
109
|
CONTEXT_TO_ANSWER_INFERENCE,
|
|
88
110
|
ANSWER_TO_GROUND_TRUTH_INFERENCE,
|
|
89
111
|
GROUND_TRUTH_TO_ANSWER_INFERENCE,
|
|
112
|
+
ANSWER_TO_FACTS_INFERENCE,
|
|
113
|
+
FACTS_TO_ANSWER_INFERENCE,
|
|
90
114
|
],
|
|
91
115
|
)
|
|
92
|
-
print(df_metrics[["facts_ranks", "recall", 'precision', 'mrr', 'f1', 'ctx_ans_inference', 'ans_gt_inference', 'gt_ans_inference']])
|
|
116
|
+
print(df_metrics[["facts_ranks", "recall", 'precision', 'mrr', 'f1', 'ctx_ans_inference', 'ans_gt_inference', 'gt_ans_inference', 'ans_fct_inference', 'fct_ans_inference']])
|
|
93
117
|
```
|
|
94
118
|
|
|
95
119
|
It is expected to see the following results:
|
|
96
120
|
|
|
97
|
-
| recall | precision | mrr | f1 | ctx_ans_inference | ans_gt_inference | gt_ans_inference |
|
|
98
|
-
| ------ | --------- | --- | --- | ----------------- | ---------------- | ---------------- |
|
|
99
|
-
| 0.5 | 0.5 | 0.5 | 0.5 | 1.0 | 0.5 | 1.0 |
|
|
121
|
+
| recall | precision | mrr | f1 | ctx_ans_inference | ans_gt_inference | gt_ans_inference | ans_fct_inference | fct_ans_inference |
|
|
122
|
+
| ------ | --------- | --- | --- | ----------------- | ---------------- | ---------------- | ----------------- | ----------------- |
|
|
123
|
+
| 0.5 | 0.5 | 0.5 | 0.5 | 1.0 | 0.5 | 1.0 | 0.5 | 1.0 |
|
|
100
124
|
|
|
101
125
|
In this table:
|
|
102
126
|
|
|
@@ -106,17 +130,22 @@ In this table:
|
|
|
106
130
|
- "ctx" refers to 'context'
|
|
107
131
|
- "ans" refers to 'answer'
|
|
108
132
|
- "gt" refers to 'ground truth answer'
|
|
109
|
-
- "
|
|
110
|
-
- "
|
|
133
|
+
- "fct" refers to 'facts'
|
|
134
|
+
- "ctx_ans_inference" of 1.0 means our answer can be fully derived from the context.
|
|
135
|
+
- "ans_gt_inference" of 0.5 means the ground truth answer is only partially entailed by our answer.
|
|
136
|
+
- "gt_ans_inference" of 1.0 means our answer can be fully derived from the ground truth answer.
|
|
137
|
+
- "ans_fct_inference" of 0.5 means only half of the ground truth facts are entailed by our answer (the Pacific Ocean fact is missing).
|
|
138
|
+
- "fct_ans_inference" of 1.0 means our answer can be fully derived from the ground truth facts.
|
|
111
139
|
|
|
112
140
|
## Recommended models
|
|
113
141
|
|
|
114
142
|
The algorithm is token-intensive. Considering the balance between quality and price, the following models are recommended:
|
|
115
143
|
|
|
144
|
+
- **gemini-3.1-flash-lite**
|
|
116
145
|
- **gemini-2.5-flash-lite**
|
|
117
146
|
- **gpt-5-mini**
|
|
118
|
-
- **gemini-2.0-flash-lite**
|
|
119
147
|
- **gpt-5-nano**
|
|
148
|
+
- **gpt-5.4-mini**
|
|
120
149
|
|
|
121
150
|
## Developer environment
|
|
122
151
|
|
|
@@ -14,6 +14,27 @@ Install the library using [pip](https://pip.pypa.org/en/stable/getting-started):
|
|
|
14
14
|
pip install aidial-rag-eval
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
### spaCy language model
|
|
18
|
+
|
|
19
|
+
The generation metrics require the English language model for [spaCy](https://spacy.io/).
|
|
20
|
+
Download it after installation:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
python -m spacy download en_core_web_sm
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Alternatively, you can install the model directly via URL:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pip install https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or as a [Poetry](https://python-poetry.org/) dependency:
|
|
33
|
+
|
|
34
|
+
```toml
|
|
35
|
+
en-core-web-sm = {url = "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl"}
|
|
36
|
+
```
|
|
37
|
+
|
|
17
38
|
### Example
|
|
18
39
|
|
|
19
40
|
The example of how to get retrieval metrics along with answer inference based on the context.
|
|
@@ -23,7 +44,8 @@ import pandas as pd
|
|
|
23
44
|
from langchain_openai import AzureChatOpenAI
|
|
24
45
|
from aidial_rag_eval import create_rag_eval_metrics_report
|
|
25
46
|
from aidial_rag_eval.metric_binds import CONTEXT_TO_ANSWER_INFERENCE,\
|
|
26
|
-
ANSWER_TO_GROUND_TRUTH_INFERENCE, GROUND_TRUTH_TO_ANSWER_INFERENCE
|
|
47
|
+
ANSWER_TO_GROUND_TRUTH_INFERENCE, GROUND_TRUTH_TO_ANSWER_INFERENCE,\
|
|
48
|
+
ANSWER_TO_FACTS_INFERENCE, FACTS_TO_ANSWER_INFERENCE
|
|
27
49
|
|
|
28
50
|
llm = AzureChatOpenAI(model="gemini-2.5-flash-lite")
|
|
29
51
|
|
|
@@ -54,16 +76,18 @@ df_metrics = create_rag_eval_metrics_report(
|
|
|
54
76
|
CONTEXT_TO_ANSWER_INFERENCE,
|
|
55
77
|
ANSWER_TO_GROUND_TRUTH_INFERENCE,
|
|
56
78
|
GROUND_TRUTH_TO_ANSWER_INFERENCE,
|
|
79
|
+
ANSWER_TO_FACTS_INFERENCE,
|
|
80
|
+
FACTS_TO_ANSWER_INFERENCE,
|
|
57
81
|
],
|
|
58
82
|
)
|
|
59
|
-
print(df_metrics[["facts_ranks", "recall", 'precision', 'mrr', 'f1', 'ctx_ans_inference', 'ans_gt_inference', 'gt_ans_inference']])
|
|
83
|
+
print(df_metrics[["facts_ranks", "recall", 'precision', 'mrr', 'f1', 'ctx_ans_inference', 'ans_gt_inference', 'gt_ans_inference', 'ans_fct_inference', 'fct_ans_inference']])
|
|
60
84
|
```
|
|
61
85
|
|
|
62
86
|
It is expected to see the following results:
|
|
63
87
|
|
|
64
|
-
| recall | precision | mrr | f1 | ctx_ans_inference | ans_gt_inference | gt_ans_inference |
|
|
65
|
-
| ------ | --------- | --- | --- | ----------------- | ---------------- | ---------------- |
|
|
66
|
-
| 0.5 | 0.5 | 0.5 | 0.5 | 1.0 | 0.5 | 1.0 |
|
|
88
|
+
| recall | precision | mrr | f1 | ctx_ans_inference | ans_gt_inference | gt_ans_inference | ans_fct_inference | fct_ans_inference |
|
|
89
|
+
| ------ | --------- | --- | --- | ----------------- | ---------------- | ---------------- | ----------------- | ----------------- |
|
|
90
|
+
| 0.5 | 0.5 | 0.5 | 0.5 | 1.0 | 0.5 | 1.0 | 0.5 | 1.0 |
|
|
67
91
|
|
|
68
92
|
In this table:
|
|
69
93
|
|
|
@@ -73,17 +97,22 @@ In this table:
|
|
|
73
97
|
- "ctx" refers to 'context'
|
|
74
98
|
- "ans" refers to 'answer'
|
|
75
99
|
- "gt" refers to 'ground truth answer'
|
|
76
|
-
- "
|
|
77
|
-
- "
|
|
100
|
+
- "fct" refers to 'facts'
|
|
101
|
+
- "ctx_ans_inference" of 1.0 means our answer can be fully derived from the context.
|
|
102
|
+
- "ans_gt_inference" of 0.5 means the ground truth answer is only partially entailed by our answer.
|
|
103
|
+
- "gt_ans_inference" of 1.0 means our answer can be fully derived from the ground truth answer.
|
|
104
|
+
- "ans_fct_inference" of 0.5 means only half of the ground truth facts are entailed by our answer (the Pacific Ocean fact is missing).
|
|
105
|
+
- "fct_ans_inference" of 1.0 means our answer can be fully derived from the ground truth facts.
|
|
78
106
|
|
|
79
107
|
## Recommended models
|
|
80
108
|
|
|
81
109
|
The algorithm is token-intensive. Considering the balance between quality and price, the following models are recommended:
|
|
82
110
|
|
|
111
|
+
- **gemini-3.1-flash-lite**
|
|
83
112
|
- **gemini-2.5-flash-lite**
|
|
84
113
|
- **gpt-5-mini**
|
|
85
|
-
- **gemini-2.0-flash-lite**
|
|
86
114
|
- **gpt-5-nano**
|
|
115
|
+
- **gpt-5.4-mini**
|
|
87
116
|
|
|
88
117
|
## Developer environment
|
|
89
118
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "aidial-rag-eval"
|
|
3
|
-
version = "0.6.0.
|
|
3
|
+
version = "0.6.0.dev20"
|
|
4
4
|
description = "Library for RAG evaluation"
|
|
5
5
|
authors = ["EPAM RAIL <SpecialEPM-DIALDevTeam@epam.com>"]
|
|
6
6
|
homepage = "https://github.com/epam/ai-dial-rag-eval"
|
|
@@ -13,13 +13,13 @@ repository = "https://github.com/epam/ai-dial-rag-eval"
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
[tool.poetry.dependencies]
|
|
16
|
-
python = "
|
|
16
|
+
python = ">=3.11, <3.15"
|
|
17
17
|
numpy = ">=1.26.4,<3"
|
|
18
18
|
pandas = "^2.2.2"
|
|
19
19
|
fsspec = "^2024.3.1"
|
|
20
20
|
s3fs = {version = "^2024.3.1", optional = true}
|
|
21
|
-
pydantic = "
|
|
22
|
-
|
|
21
|
+
pydantic = ">=2.7.1"
|
|
22
|
+
spacy = ">=3.8.9,<4"
|
|
23
23
|
tqdm = "^4.66.4"
|
|
24
24
|
langchain-core = ">=0.3.80,<2"
|
|
25
25
|
more-itertools = "^10.5.0"
|
|
@@ -35,6 +35,7 @@ pytest-cov = "^4.1.0"
|
|
|
35
35
|
pytest-mock = "^3.14.0"
|
|
36
36
|
langchain-community = "^0.3.14"
|
|
37
37
|
langchain-openai = "^0.2.1"
|
|
38
|
+
en-core-web-sm = {url = "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl"}
|
|
38
39
|
|
|
39
40
|
[tool.poetry.group.lint.dependencies]
|
|
40
41
|
black = "^24.3.0"
|
{aidial_rag_eval-0.6.0.dev16 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/metrics.py
RENAMED
|
@@ -8,13 +8,20 @@ from aidial_rag_eval.dataframe.match_facts import (
|
|
|
8
8
|
apply_matcher_to_merged_dataframe,
|
|
9
9
|
)
|
|
10
10
|
from aidial_rag_eval.dataframe.merge import merge_ground_truth_and_answers
|
|
11
|
-
from aidial_rag_eval.generation.metric_binds import
|
|
12
|
-
|
|
11
|
+
from aidial_rag_eval.generation.metric_binds import (
|
|
12
|
+
_wrapped_dataframe_inference,
|
|
13
|
+
_wrapped_dataframe_refusal,
|
|
14
|
+
)
|
|
15
|
+
from aidial_rag_eval.generation.types import (
|
|
16
|
+
InferenceMetricBind,
|
|
17
|
+
MetricBind,
|
|
18
|
+
RefusalMetricBind,
|
|
19
|
+
inference_column,
|
|
20
|
+
)
|
|
13
21
|
from aidial_rag_eval.retrieval.metrics import (
|
|
14
22
|
calculate_metrics as calculate_metrics_by_row,
|
|
15
23
|
)
|
|
16
24
|
from aidial_rag_eval.retrieval.types import Matcher
|
|
17
|
-
from aidial_rag_eval.types import MergedColumns
|
|
18
25
|
|
|
19
26
|
|
|
20
27
|
def apply_metrics_to_matched_results(match_result_data: pd.DataFrame) -> pd.DataFrame:
|
|
@@ -114,7 +121,6 @@ def calculate_generation_metrics(
|
|
|
114
121
|
metric_binds: List[MetricBind],
|
|
115
122
|
max_concurrency: int = 8,
|
|
116
123
|
show_progress_bar: bool = True,
|
|
117
|
-
auto_download_nltk: bool = True,
|
|
118
124
|
) -> pd.DataFrame:
|
|
119
125
|
"""
|
|
120
126
|
Calculates RAG evaluation generation metrics from df_merged dataframe.
|
|
@@ -130,7 +136,7 @@ def calculate_generation_metrics(
|
|
|
130
136
|
A Langchain chat model used for calculating generation metrics.
|
|
131
137
|
|
|
132
138
|
metric_binds : List[MetricBind], optional, default=None
|
|
133
|
-
A list of
|
|
139
|
+
A list of metric bind instances from `aidial_rag_eval.metric_binds`
|
|
134
140
|
specifying the generation metrics.
|
|
135
141
|
|
|
136
142
|
max_concurrency : int, default=8
|
|
@@ -145,20 +151,32 @@ def calculate_generation_metrics(
|
|
|
145
151
|
Returns generation metrics dataframe.
|
|
146
152
|
"""
|
|
147
153
|
df_merged_copy = df_merged.copy()
|
|
148
|
-
df_merged_copy[MergedColumns.JOINED_CONTEXT] = df_merged_copy[
|
|
149
|
-
MergedColumns.CONTEXT
|
|
150
|
-
].apply(lambda x: "\n".join(x))
|
|
151
154
|
metric_results = dict()
|
|
152
155
|
for metric_bind in metric_binds:
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
if isinstance(metric_bind, InferenceMetricBind):
|
|
157
|
+
result = _wrapped_dataframe_inference(
|
|
158
|
+
df_merged=df_merged_copy,
|
|
159
|
+
premise_column=metric_bind.premise_column,
|
|
160
|
+
hypothesis_column=metric_bind.hypothesis_column,
|
|
161
|
+
llm=llm,
|
|
162
|
+
prefix=metric_bind.prefix,
|
|
163
|
+
premise_prefix_column=metric_bind.premise_prefix_column,
|
|
164
|
+
document_column=metric_bind.document_column,
|
|
165
|
+
max_concurrency=max_concurrency,
|
|
166
|
+
show_progress_bar=show_progress_bar,
|
|
167
|
+
)
|
|
168
|
+
elif isinstance(metric_bind, RefusalMetricBind):
|
|
169
|
+
result = _wrapped_dataframe_refusal(
|
|
155
170
|
df_merged=df_merged_copy,
|
|
171
|
+
answer_column=metric_bind.answer_column,
|
|
156
172
|
llm=llm,
|
|
173
|
+
prefix=metric_bind.prefix,
|
|
157
174
|
max_concurrency=max_concurrency,
|
|
158
175
|
show_progress_bar=show_progress_bar,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
176
|
+
)
|
|
177
|
+
else:
|
|
178
|
+
raise ValueError(f"Unknown metric bind type: {type(metric_bind)}")
|
|
179
|
+
metric_results.update(result.to_dict(orient="series"))
|
|
162
180
|
df_metrics = pd.DataFrame(data=metric_results)
|
|
163
181
|
nli_columns = [
|
|
164
182
|
column for column in metric_results.keys() if column.endswith(inference_column)
|
|
@@ -180,7 +198,6 @@ def create_generation_metrics_report(
|
|
|
180
198
|
metric_binds: List[MetricBind],
|
|
181
199
|
max_concurrency: int = 8,
|
|
182
200
|
show_progress_bar: bool = True,
|
|
183
|
-
auto_download_nltk: bool = True,
|
|
184
201
|
) -> pd.DataFrame:
|
|
185
202
|
"""
|
|
186
203
|
Calculates RAG evaluation generation metrics from input dataframes.
|
|
@@ -201,7 +218,7 @@ def create_generation_metrics_report(
|
|
|
201
218
|
A Langchain chat model used for calculating generation metrics.
|
|
202
219
|
|
|
203
220
|
metric_binds : List[MetricBind], optional, default=None
|
|
204
|
-
A list of
|
|
221
|
+
A list of metric bind instances from `aidial_rag_eval.metric_binds`
|
|
205
222
|
specifying the generation metrics.
|
|
206
223
|
|
|
207
224
|
max_concurrency : int, default=8
|
|
@@ -223,7 +240,6 @@ def create_generation_metrics_report(
|
|
|
223
240
|
metric_binds,
|
|
224
241
|
max_concurrency,
|
|
225
242
|
show_progress_bar,
|
|
226
|
-
auto_download_nltk,
|
|
227
243
|
)
|
|
228
244
|
return pd.merge(df_merged, df_metrics, left_index=True, right_index=True)
|
|
229
245
|
|
|
@@ -236,7 +252,6 @@ def create_rag_eval_metrics_report(
|
|
|
236
252
|
metric_binds: Optional[List[MetricBind]] = None,
|
|
237
253
|
max_concurrency: int = 8,
|
|
238
254
|
show_progress_bar: bool = True,
|
|
239
|
-
auto_download_nltk: bool = True,
|
|
240
255
|
) -> pd.DataFrame:
|
|
241
256
|
"""
|
|
242
257
|
Calculates RAG evaluation metrics from input dataframes.
|
|
@@ -261,7 +276,7 @@ def create_rag_eval_metrics_report(
|
|
|
261
276
|
A Langchain chat model used for calculating generation metrics.
|
|
262
277
|
|
|
263
278
|
metric_binds : List[MetricBind], optional, default=None
|
|
264
|
-
A list of
|
|
279
|
+
A list of metric bind instances from `aidial_rag_eval.metric_binds`
|
|
265
280
|
specifying the generation metrics.
|
|
266
281
|
|
|
267
282
|
max_concurrency : int, default=8
|
|
@@ -287,6 +302,5 @@ def create_rag_eval_metrics_report(
|
|
|
287
302
|
metric_binds,
|
|
288
303
|
max_concurrency,
|
|
289
304
|
show_progress_bar,
|
|
290
|
-
auto_download_nltk,
|
|
291
305
|
)
|
|
292
306
|
return pd.concat([df_merged, retrieval_metrics, generation_metrics], axis=1)
|
|
@@ -21,7 +21,6 @@ def evaluate(
|
|
|
21
21
|
metric_binds: Optional[List[MetricBind]] = None,
|
|
22
22
|
max_concurrency: int = 8,
|
|
23
23
|
show_progress_bar: bool = True,
|
|
24
|
-
auto_download_nltk: bool = False,
|
|
25
24
|
) -> Dataset:
|
|
26
25
|
"""
|
|
27
26
|
Calculates RAG evaluation metrics from input
|
|
@@ -83,7 +82,6 @@ def evaluate(
|
|
|
83
82
|
metric_binds=metric_binds,
|
|
84
83
|
max_concurrency=max_concurrency,
|
|
85
84
|
show_progress_bar=show_progress_bar,
|
|
86
|
-
auto_download_nltk=auto_download_nltk,
|
|
87
85
|
)
|
|
88
86
|
aggregated_metrics = df_final.mean(numeric_only=True)
|
|
89
87
|
assert isinstance(aggregated_metrics, pd.Series)
|
|
@@ -30,13 +30,15 @@ from aidial_rag_eval.types import Documents, Question
|
|
|
30
30
|
|
|
31
31
|
T = TypeVar("T")
|
|
32
32
|
|
|
33
|
+
_LIST_DELIMITER = "\n"
|
|
34
|
+
|
|
33
35
|
|
|
34
36
|
def _join_documents(documents: Documents) -> JoinedDocumentsName:
|
|
35
37
|
return " ; ".join(documents)
|
|
36
38
|
|
|
37
39
|
|
|
38
40
|
def _make_inference_task_inputs(
|
|
39
|
-
|
|
41
|
+
adjusted_premises: List[str],
|
|
40
42
|
statements: List[Union[HypothesisStatements, ErrorInfo]],
|
|
41
43
|
document_names: List[JoinedDocumentsName],
|
|
42
44
|
) -> List[InferenceInputs]:
|
|
@@ -45,7 +47,7 @@ def _make_inference_task_inputs(
|
|
|
45
47
|
|
|
46
48
|
Parameters
|
|
47
49
|
-----------
|
|
48
|
-
|
|
50
|
+
adjusted_premises : List[str]
|
|
49
51
|
A list of premises from which we want to derive hypotheses in pairs.
|
|
50
52
|
|
|
51
53
|
statements : List[Union[HypothesisStatements, ErrorInfo]]
|
|
@@ -73,7 +75,7 @@ def _make_inference_task_inputs(
|
|
|
73
75
|
[
|
|
74
76
|
InferenceInputs(
|
|
75
77
|
hypothesis_id=i,
|
|
76
|
-
premise=
|
|
78
|
+
premise=adjusted_premises[i],
|
|
77
79
|
statements=list_statements,
|
|
78
80
|
document_name=document_names[i],
|
|
79
81
|
)
|
|
@@ -83,7 +85,7 @@ def _make_inference_task_inputs(
|
|
|
83
85
|
else [
|
|
84
86
|
InferenceInputs(
|
|
85
87
|
hypothesis_id=i,
|
|
86
|
-
premise=
|
|
88
|
+
premise=adjusted_premises[i],
|
|
87
89
|
statements=[],
|
|
88
90
|
document_name=document_names[i],
|
|
89
91
|
error=statement_result,
|
|
@@ -203,7 +205,6 @@ def _segment_hypotheses(
|
|
|
203
205
|
llm: BaseChatModel,
|
|
204
206
|
max_concurrency: int = 8,
|
|
205
207
|
show_progress_bar: bool = True,
|
|
206
|
-
auto_download_nltk: bool = True,
|
|
207
208
|
) -> Tuple[List[SegmentedText], List[Union[SegmentedText, ErrorInfo]]]:
|
|
208
209
|
"""
|
|
209
210
|
Function that segments hypotheses into hypothesis segments(roughly into
|
|
@@ -212,8 +213,9 @@ def _segment_hypotheses(
|
|
|
212
213
|
Parameters
|
|
213
214
|
-----------
|
|
214
215
|
|
|
215
|
-
hypotheses : List[str]
|
|
216
|
+
hypotheses : List[Union[str, List[str]]]
|
|
216
217
|
The text of the hypothesis.
|
|
218
|
+
Each hypothesis can be a single text or a list of text fragments.
|
|
217
219
|
|
|
218
220
|
llm : BaseChatModel
|
|
219
221
|
The Langchain chat model used for calculating inference.
|
|
@@ -236,7 +238,11 @@ def _segment_hypotheses(
|
|
|
236
238
|
max_concurrency=max_concurrency,
|
|
237
239
|
)
|
|
238
240
|
segmented_hypotheses = [
|
|
239
|
-
|
|
241
|
+
(
|
|
242
|
+
SegmentedText.from_list(hypothesis, _LIST_DELIMITER)
|
|
243
|
+
if not isinstance(hypothesis, str)
|
|
244
|
+
else SegmentedText.from_text(hypothesis)
|
|
245
|
+
)
|
|
240
246
|
for hypothesis in hypotheses
|
|
241
247
|
]
|
|
242
248
|
if show_progress_bar:
|
|
@@ -291,18 +297,17 @@ def _extract_statements(
|
|
|
291
297
|
return extractor.extract(segmented_hypotheses, show_progress_bar)
|
|
292
298
|
|
|
293
299
|
|
|
294
|
-
def
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
300
|
+
def _prepend_premise_prefixes(
|
|
301
|
+
normalized_premises: List[str],
|
|
302
|
+
premise_prefixes: Optional[List[Question]],
|
|
303
|
+
) -> List[str]:
|
|
304
|
+
adjusted_premises: List[str] = list(normalized_premises)
|
|
305
|
+
if premise_prefixes is not None:
|
|
306
|
+
for i, prefix in enumerate(premise_prefixes):
|
|
307
|
+
prefix_split = SegmentedText.from_text(text=prefix)
|
|
308
|
+
adjusted_premises[i] = _LIST_DELIMITER.join(
|
|
309
|
+
[prefix_split.segments[-1], normalized_premises[i]]
|
|
304
310
|
)
|
|
305
|
-
adjusted_premises[i] = question_split.segments[-1] + "\n" + premises[i]
|
|
306
311
|
return adjusted_premises
|
|
307
312
|
|
|
308
313
|
|
|
@@ -310,11 +315,10 @@ def _infer_statements(
|
|
|
310
315
|
premises: List[Premise],
|
|
311
316
|
statements: List[Union[HypothesisStatements, ErrorInfo]],
|
|
312
317
|
llm: BaseChatModel,
|
|
313
|
-
|
|
318
|
+
premise_prefixes: Optional[List[Question]] = None,
|
|
314
319
|
list_documents: Optional[List[Documents]] = None,
|
|
315
320
|
max_concurrency: int = 8,
|
|
316
321
|
show_progress_bar: bool = True,
|
|
317
|
-
auto_download_nltk: bool = True,
|
|
318
322
|
) -> List[List[Tuple[InferenceInputs, InferenceScore]]]:
|
|
319
323
|
"""
|
|
320
324
|
Function that infers statements.
|
|
@@ -325,8 +329,9 @@ def _infer_statements(
|
|
|
325
329
|
Parameters
|
|
326
330
|
-----------
|
|
327
331
|
|
|
328
|
-
premises : List[str]
|
|
332
|
+
premises : List[Union[str, List[str]]]
|
|
329
333
|
The text of the premise from which the hypothesis will be inferred.
|
|
334
|
+
Each premise can be a single text or a list of text fragments.
|
|
330
335
|
|
|
331
336
|
statements : List[Union[HypothesisStatements, ErrorInfo]]
|
|
332
337
|
A deeply nested list of statements, where the outermost
|
|
@@ -358,9 +363,10 @@ def _infer_statements(
|
|
|
358
363
|
For items that failed in any stage, InferenceScore will have inference=None
|
|
359
364
|
and the error field set.
|
|
360
365
|
"""
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
366
|
+
normalized_premises: List[str] = [
|
|
367
|
+
_LIST_DELIMITER.join(p) if not isinstance(p, str) else p for p in premises
|
|
368
|
+
]
|
|
369
|
+
adjusted_premises = _prepend_premise_prefixes(normalized_premises, premise_prefixes)
|
|
364
370
|
|
|
365
371
|
document_names: List[JoinedDocumentsName] = (
|
|
366
372
|
[""] * len(statements)
|
|
@@ -391,14 +397,12 @@ def segment_hypotheses(
|
|
|
391
397
|
llm: BaseChatModel,
|
|
392
398
|
max_concurrency: int = 8,
|
|
393
399
|
show_progress_bar: bool = True,
|
|
394
|
-
auto_download_nltk: bool = True,
|
|
395
400
|
) -> List[Union[SegmentedText, ErrorInfo]]:
|
|
396
401
|
return _segment_hypotheses(
|
|
397
402
|
hypotheses=hypotheses,
|
|
398
403
|
llm=llm,
|
|
399
404
|
max_concurrency=max_concurrency,
|
|
400
405
|
show_progress_bar=show_progress_bar,
|
|
401
|
-
auto_download_nltk=auto_download_nltk,
|
|
402
406
|
)[1]
|
|
403
407
|
|
|
404
408
|
|
|
@@ -422,21 +426,19 @@ def infer_statements(
|
|
|
422
426
|
premises: List[Premise],
|
|
423
427
|
statements: List[HypothesisStatements],
|
|
424
428
|
llm: BaseChatModel,
|
|
425
|
-
|
|
429
|
+
premise_prefixes: Optional[List[Question]] = None,
|
|
426
430
|
list_documents: Optional[List[Documents]] = None,
|
|
427
431
|
max_concurrency: int = 8,
|
|
428
432
|
show_progress_bar: bool = True,
|
|
429
|
-
auto_download_nltk: bool = True,
|
|
430
433
|
) -> List[List[Tuple[InferenceInputs, InferenceScore]]]:
|
|
431
434
|
return _infer_statements(
|
|
432
435
|
premises=premises,
|
|
433
436
|
statements=cast(List[Union[HypothesisStatements, ErrorInfo]], statements),
|
|
434
437
|
llm=llm,
|
|
435
|
-
|
|
438
|
+
premise_prefixes=premise_prefixes,
|
|
436
439
|
list_documents=list_documents,
|
|
437
440
|
max_concurrency=max_concurrency,
|
|
438
441
|
show_progress_bar=show_progress_bar,
|
|
439
|
-
auto_download_nltk=auto_download_nltk,
|
|
440
442
|
)
|
|
441
443
|
|
|
442
444
|
|
|
@@ -480,11 +482,10 @@ def calculate_batch_inference(
|
|
|
480
482
|
premises: List[Premise],
|
|
481
483
|
hypotheses: List[Hypothesis],
|
|
482
484
|
llm: BaseChatModel,
|
|
483
|
-
|
|
485
|
+
premise_prefixes: Optional[List[Question]] = None,
|
|
484
486
|
list_documents: Optional[List[Documents]] = None,
|
|
485
487
|
max_concurrency: int = 8,
|
|
486
488
|
show_progress_bar: bool = True,
|
|
487
|
-
auto_download_nltk: bool = True,
|
|
488
489
|
) -> List[InferenceReturn]:
|
|
489
490
|
"""
|
|
490
491
|
Calculates pairwise the inference of a hypotheses from a premises.
|
|
@@ -492,11 +493,13 @@ def calculate_batch_inference(
|
|
|
492
493
|
Parameters
|
|
493
494
|
-----------
|
|
494
495
|
|
|
495
|
-
premises : List[str]
|
|
496
|
+
premises : List[Union[str, List[str]]]
|
|
496
497
|
The text of the premise from which the hypothesis will be inferred.
|
|
498
|
+
Each premise can be a single text or a list of text fragments.
|
|
497
499
|
|
|
498
|
-
hypotheses : List[str]
|
|
500
|
+
hypotheses : List[Union[str, List[str]]]
|
|
499
501
|
The text of the hypothesis.
|
|
502
|
+
Each hypothesis can be a single text or a list of text fragments.
|
|
500
503
|
|
|
501
504
|
llm : BaseChatModel
|
|
502
505
|
The Langchain chat model used for calculating inference.
|
|
@@ -530,7 +533,6 @@ def calculate_batch_inference(
|
|
|
530
533
|
llm=llm,
|
|
531
534
|
max_concurrency=max_concurrency,
|
|
532
535
|
show_progress_bar=show_progress_bar,
|
|
533
|
-
auto_download_nltk=auto_download_nltk,
|
|
534
536
|
)
|
|
535
537
|
statements: List[Union[HypothesisStatements, ErrorInfo]] = _extract_statements(
|
|
536
538
|
segmented_hypotheses=decontextualized_segmented_hypotheses,
|
|
@@ -543,11 +545,10 @@ def calculate_batch_inference(
|
|
|
543
545
|
premises=premises,
|
|
544
546
|
statements=statements,
|
|
545
547
|
llm=llm,
|
|
546
|
-
|
|
548
|
+
premise_prefixes=premise_prefixes,
|
|
547
549
|
list_documents=list_documents,
|
|
548
550
|
max_concurrency=max_concurrency,
|
|
549
551
|
show_progress_bar=show_progress_bar,
|
|
550
|
-
auto_download_nltk=auto_download_nltk,
|
|
551
552
|
)
|
|
552
553
|
)
|
|
553
554
|
|
|
@@ -581,11 +582,10 @@ def calculate_inference(
|
|
|
581
582
|
premise: Premise,
|
|
582
583
|
hypothesis: Hypothesis,
|
|
583
584
|
llm: BaseChatModel,
|
|
584
|
-
|
|
585
|
+
premise_prefix: Optional[Question] = None,
|
|
585
586
|
documents: Optional[Documents] = None,
|
|
586
587
|
max_concurrency: int = 8,
|
|
587
588
|
show_progress_bar: bool = True,
|
|
588
|
-
auto_download_nltk: bool = True,
|
|
589
589
|
) -> InferenceReturn:
|
|
590
590
|
"""
|
|
591
591
|
Calculates the inference of a hypothesis from a premise.
|
|
@@ -593,11 +593,13 @@ def calculate_inference(
|
|
|
593
593
|
Parameters
|
|
594
594
|
-----------
|
|
595
595
|
|
|
596
|
-
premise : str
|
|
596
|
+
premise : Union[str, List[str]]
|
|
597
597
|
The text of the premise from which the hypothesis will be inferred.
|
|
598
|
+
Can be a single text or a list of text fragments.
|
|
598
599
|
|
|
599
|
-
hypothesis : str
|
|
600
|
+
hypothesis : Union[str, List[str]]
|
|
600
601
|
The text of the hypothesis.
|
|
602
|
+
Can be a single text or a list of text fragments.
|
|
601
603
|
|
|
602
604
|
llm : BaseChatModel
|
|
603
605
|
The Langchain chat model used for calculating inference.
|
|
@@ -621,16 +623,15 @@ def calculate_inference(
|
|
|
621
623
|
along with a JSON string that explains how the inference was derived and
|
|
622
624
|
highlights string used for highlighting each segment of the hypothesis.
|
|
623
625
|
"""
|
|
624
|
-
|
|
626
|
+
premise_prefixes = None if premise_prefix is None else [premise_prefix]
|
|
625
627
|
list_documents = None if documents is None else [documents]
|
|
626
628
|
inference_returns = calculate_batch_inference(
|
|
627
629
|
premises=[premise],
|
|
628
630
|
hypotheses=[hypothesis],
|
|
629
631
|
llm=llm,
|
|
630
|
-
|
|
632
|
+
premise_prefixes=premise_prefixes,
|
|
631
633
|
list_documents=list_documents,
|
|
632
634
|
max_concurrency=max_concurrency,
|
|
633
635
|
show_progress_bar=show_progress_bar,
|
|
634
|
-
auto_download_nltk=auto_download_nltk,
|
|
635
636
|
)
|
|
636
637
|
return inference_returns[0]
|