aidial-rag-eval 0.6.0.dev19__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.dev19 → aidial_rag_eval-0.6.0.dev20}/PKG-INFO +15 -8
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/README.md +14 -7
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/pyproject.toml +1 -1
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/metrics.py +33 -13
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/inference.py +47 -29
- aidial_rag_eval-0.6.0.dev20/src/aidial_rag_eval/generation/metric_binds.py +125 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/types.py +19 -6
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/segmented_text.py +15 -4
- aidial_rag_eval-0.6.0.dev20/src/aidial_rag_eval/metric_binds.py +19 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/types.py +3 -5
- aidial_rag_eval-0.6.0.dev19/src/aidial_rag_eval/generation/metric_binds.py +0 -165
- aidial_rag_eval-0.6.0.dev19/src/aidial_rag_eval/metric_binds.py +0 -15
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/LICENSE +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/match_facts.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/merge.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataset.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/evaluate.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/citation.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/exact.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/match_str_facts.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/converters/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/models/lambdas.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → 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.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/refusal.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/exceptions.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/utils/progress_bar.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/metrics.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/__init__.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/metrics.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/types.py +0 -0
- {aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
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
|
|
@@ -77,7 +77,8 @@ import pandas as pd
|
|
|
77
77
|
from langchain_openai import AzureChatOpenAI
|
|
78
78
|
from aidial_rag_eval import create_rag_eval_metrics_report
|
|
79
79
|
from aidial_rag_eval.metric_binds import CONTEXT_TO_ANSWER_INFERENCE,\
|
|
80
|
-
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
|
|
81
82
|
|
|
82
83
|
llm = AzureChatOpenAI(model="gemini-2.5-flash-lite")
|
|
83
84
|
|
|
@@ -108,16 +109,18 @@ df_metrics = create_rag_eval_metrics_report(
|
|
|
108
109
|
CONTEXT_TO_ANSWER_INFERENCE,
|
|
109
110
|
ANSWER_TO_GROUND_TRUTH_INFERENCE,
|
|
110
111
|
GROUND_TRUTH_TO_ANSWER_INFERENCE,
|
|
112
|
+
ANSWER_TO_FACTS_INFERENCE,
|
|
113
|
+
FACTS_TO_ANSWER_INFERENCE,
|
|
111
114
|
],
|
|
112
115
|
)
|
|
113
|
-
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']])
|
|
114
117
|
```
|
|
115
118
|
|
|
116
119
|
It is expected to see the following results:
|
|
117
120
|
|
|
118
|
-
| recall | precision | mrr | f1 | ctx_ans_inference | ans_gt_inference | gt_ans_inference |
|
|
119
|
-
| ------ | --------- | --- | --- | ----------------- | ---------------- | ---------------- |
|
|
120
|
-
| 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 |
|
|
121
124
|
|
|
122
125
|
In this table:
|
|
123
126
|
|
|
@@ -127,8 +130,12 @@ In this table:
|
|
|
127
130
|
- "ctx" refers to 'context'
|
|
128
131
|
- "ans" refers to 'answer'
|
|
129
132
|
- "gt" refers to 'ground truth answer'
|
|
130
|
-
- "
|
|
131
|
-
- "
|
|
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.
|
|
132
139
|
|
|
133
140
|
## Recommended models
|
|
134
141
|
|
|
@@ -44,7 +44,8 @@ import pandas as pd
|
|
|
44
44
|
from langchain_openai import AzureChatOpenAI
|
|
45
45
|
from aidial_rag_eval import create_rag_eval_metrics_report
|
|
46
46
|
from aidial_rag_eval.metric_binds import CONTEXT_TO_ANSWER_INFERENCE,\
|
|
47
|
-
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
|
|
48
49
|
|
|
49
50
|
llm = AzureChatOpenAI(model="gemini-2.5-flash-lite")
|
|
50
51
|
|
|
@@ -75,16 +76,18 @@ df_metrics = create_rag_eval_metrics_report(
|
|
|
75
76
|
CONTEXT_TO_ANSWER_INFERENCE,
|
|
76
77
|
ANSWER_TO_GROUND_TRUTH_INFERENCE,
|
|
77
78
|
GROUND_TRUTH_TO_ANSWER_INFERENCE,
|
|
79
|
+
ANSWER_TO_FACTS_INFERENCE,
|
|
80
|
+
FACTS_TO_ANSWER_INFERENCE,
|
|
78
81
|
],
|
|
79
82
|
)
|
|
80
|
-
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']])
|
|
81
84
|
```
|
|
82
85
|
|
|
83
86
|
It is expected to see the following results:
|
|
84
87
|
|
|
85
|
-
| recall | precision | mrr | f1 | ctx_ans_inference | ans_gt_inference | gt_ans_inference |
|
|
86
|
-
| ------ | --------- | --- | --- | ----------------- | ---------------- | ---------------- |
|
|
87
|
-
| 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 |
|
|
88
91
|
|
|
89
92
|
In this table:
|
|
90
93
|
|
|
@@ -94,8 +97,12 @@ In this table:
|
|
|
94
97
|
- "ctx" refers to 'context'
|
|
95
98
|
- "ans" refers to 'answer'
|
|
96
99
|
- "gt" refers to 'ground truth answer'
|
|
97
|
-
- "
|
|
98
|
-
- "
|
|
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.
|
|
99
106
|
|
|
100
107
|
## Recommended models
|
|
101
108
|
|
{aidial_rag_eval-0.6.0.dev19 → 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:
|
|
@@ -129,7 +136,7 @@ def calculate_generation_metrics(
|
|
|
129
136
|
A Langchain chat model used for calculating generation metrics.
|
|
130
137
|
|
|
131
138
|
metric_binds : List[MetricBind], optional, default=None
|
|
132
|
-
A list of
|
|
139
|
+
A list of metric bind instances from `aidial_rag_eval.metric_binds`
|
|
133
140
|
specifying the generation metrics.
|
|
134
141
|
|
|
135
142
|
max_concurrency : int, default=8
|
|
@@ -144,19 +151,32 @@ def calculate_generation_metrics(
|
|
|
144
151
|
Returns generation metrics dataframe.
|
|
145
152
|
"""
|
|
146
153
|
df_merged_copy = df_merged.copy()
|
|
147
|
-
df_merged_copy[MergedColumns.JOINED_CONTEXT] = df_merged_copy[
|
|
148
|
-
MergedColumns.CONTEXT
|
|
149
|
-
].apply(lambda x: "\n".join(x))
|
|
150
154
|
metric_results = dict()
|
|
151
155
|
for metric_bind in metric_binds:
|
|
152
|
-
|
|
153
|
-
|
|
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(
|
|
154
170
|
df_merged=df_merged_copy,
|
|
171
|
+
answer_column=metric_bind.answer_column,
|
|
155
172
|
llm=llm,
|
|
173
|
+
prefix=metric_bind.prefix,
|
|
156
174
|
max_concurrency=max_concurrency,
|
|
157
175
|
show_progress_bar=show_progress_bar,
|
|
158
|
-
)
|
|
159
|
-
|
|
176
|
+
)
|
|
177
|
+
else:
|
|
178
|
+
raise ValueError(f"Unknown metric bind type: {type(metric_bind)}")
|
|
179
|
+
metric_results.update(result.to_dict(orient="series"))
|
|
160
180
|
df_metrics = pd.DataFrame(data=metric_results)
|
|
161
181
|
nli_columns = [
|
|
162
182
|
column for column in metric_results.keys() if column.endswith(inference_column)
|
|
@@ -198,7 +218,7 @@ def create_generation_metrics_report(
|
|
|
198
218
|
A Langchain chat model used for calculating generation metrics.
|
|
199
219
|
|
|
200
220
|
metric_binds : List[MetricBind], optional, default=None
|
|
201
|
-
A list of
|
|
221
|
+
A list of metric bind instances from `aidial_rag_eval.metric_binds`
|
|
202
222
|
specifying the generation metrics.
|
|
203
223
|
|
|
204
224
|
max_concurrency : int, default=8
|
|
@@ -256,7 +276,7 @@ def create_rag_eval_metrics_report(
|
|
|
256
276
|
A Langchain chat model used for calculating generation metrics.
|
|
257
277
|
|
|
258
278
|
metric_binds : List[MetricBind], optional, default=None
|
|
259
|
-
A list of
|
|
279
|
+
A list of metric bind instances from `aidial_rag_eval.metric_binds`
|
|
260
280
|
specifying the generation metrics.
|
|
261
281
|
|
|
262
282
|
max_concurrency : int, default=8
|
|
@@ -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,
|
|
@@ -211,8 +213,9 @@ def _segment_hypotheses(
|
|
|
211
213
|
Parameters
|
|
212
214
|
-----------
|
|
213
215
|
|
|
214
|
-
hypotheses : List[str]
|
|
216
|
+
hypotheses : List[Union[str, List[str]]]
|
|
215
217
|
The text of the hypothesis.
|
|
218
|
+
Each hypothesis can be a single text or a list of text fragments.
|
|
216
219
|
|
|
217
220
|
llm : BaseChatModel
|
|
218
221
|
The Langchain chat model used for calculating inference.
|
|
@@ -235,7 +238,12 @@ def _segment_hypotheses(
|
|
|
235
238
|
max_concurrency=max_concurrency,
|
|
236
239
|
)
|
|
237
240
|
segmented_hypotheses = [
|
|
238
|
-
|
|
241
|
+
(
|
|
242
|
+
SegmentedText.from_list(hypothesis, _LIST_DELIMITER)
|
|
243
|
+
if not isinstance(hypothesis, str)
|
|
244
|
+
else SegmentedText.from_text(hypothesis)
|
|
245
|
+
)
|
|
246
|
+
for hypothesis in hypotheses
|
|
239
247
|
]
|
|
240
248
|
if show_progress_bar:
|
|
241
249
|
print("Converting hypothesis...")
|
|
@@ -289,15 +297,17 @@ def _extract_statements(
|
|
|
289
297
|
return extractor.extract(segmented_hypotheses, show_progress_bar)
|
|
290
298
|
|
|
291
299
|
|
|
292
|
-
def
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
) -> List[
|
|
296
|
-
adjusted_premises: List[
|
|
297
|
-
if
|
|
298
|
-
for i,
|
|
299
|
-
|
|
300
|
-
adjusted_premises[i] =
|
|
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]]
|
|
310
|
+
)
|
|
301
311
|
return adjusted_premises
|
|
302
312
|
|
|
303
313
|
|
|
@@ -305,7 +315,7 @@ def _infer_statements(
|
|
|
305
315
|
premises: List[Premise],
|
|
306
316
|
statements: List[Union[HypothesisStatements, ErrorInfo]],
|
|
307
317
|
llm: BaseChatModel,
|
|
308
|
-
|
|
318
|
+
premise_prefixes: Optional[List[Question]] = None,
|
|
309
319
|
list_documents: Optional[List[Documents]] = None,
|
|
310
320
|
max_concurrency: int = 8,
|
|
311
321
|
show_progress_bar: bool = True,
|
|
@@ -319,8 +329,9 @@ def _infer_statements(
|
|
|
319
329
|
Parameters
|
|
320
330
|
-----------
|
|
321
331
|
|
|
322
|
-
premises : List[str]
|
|
332
|
+
premises : List[Union[str, List[str]]]
|
|
323
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.
|
|
324
335
|
|
|
325
336
|
statements : List[Union[HypothesisStatements, ErrorInfo]]
|
|
326
337
|
A deeply nested list of statements, where the outermost
|
|
@@ -352,7 +363,10 @@ def _infer_statements(
|
|
|
352
363
|
For items that failed in any stage, InferenceScore will have inference=None
|
|
353
364
|
and the error field set.
|
|
354
365
|
"""
|
|
355
|
-
|
|
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)
|
|
356
370
|
|
|
357
371
|
document_names: List[JoinedDocumentsName] = (
|
|
358
372
|
[""] * len(statements)
|
|
@@ -412,7 +426,7 @@ def infer_statements(
|
|
|
412
426
|
premises: List[Premise],
|
|
413
427
|
statements: List[HypothesisStatements],
|
|
414
428
|
llm: BaseChatModel,
|
|
415
|
-
|
|
429
|
+
premise_prefixes: Optional[List[Question]] = None,
|
|
416
430
|
list_documents: Optional[List[Documents]] = None,
|
|
417
431
|
max_concurrency: int = 8,
|
|
418
432
|
show_progress_bar: bool = True,
|
|
@@ -421,7 +435,7 @@ def infer_statements(
|
|
|
421
435
|
premises=premises,
|
|
422
436
|
statements=cast(List[Union[HypothesisStatements, ErrorInfo]], statements),
|
|
423
437
|
llm=llm,
|
|
424
|
-
|
|
438
|
+
premise_prefixes=premise_prefixes,
|
|
425
439
|
list_documents=list_documents,
|
|
426
440
|
max_concurrency=max_concurrency,
|
|
427
441
|
show_progress_bar=show_progress_bar,
|
|
@@ -468,7 +482,7 @@ def calculate_batch_inference(
|
|
|
468
482
|
premises: List[Premise],
|
|
469
483
|
hypotheses: List[Hypothesis],
|
|
470
484
|
llm: BaseChatModel,
|
|
471
|
-
|
|
485
|
+
premise_prefixes: Optional[List[Question]] = None,
|
|
472
486
|
list_documents: Optional[List[Documents]] = None,
|
|
473
487
|
max_concurrency: int = 8,
|
|
474
488
|
show_progress_bar: bool = True,
|
|
@@ -479,11 +493,13 @@ def calculate_batch_inference(
|
|
|
479
493
|
Parameters
|
|
480
494
|
-----------
|
|
481
495
|
|
|
482
|
-
premises : List[str]
|
|
496
|
+
premises : List[Union[str, List[str]]]
|
|
483
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.
|
|
484
499
|
|
|
485
|
-
hypotheses : List[str]
|
|
500
|
+
hypotheses : List[Union[str, List[str]]]
|
|
486
501
|
The text of the hypothesis.
|
|
502
|
+
Each hypothesis can be a single text or a list of text fragments.
|
|
487
503
|
|
|
488
504
|
llm : BaseChatModel
|
|
489
505
|
The Langchain chat model used for calculating inference.
|
|
@@ -529,7 +545,7 @@ def calculate_batch_inference(
|
|
|
529
545
|
premises=premises,
|
|
530
546
|
statements=statements,
|
|
531
547
|
llm=llm,
|
|
532
|
-
|
|
548
|
+
premise_prefixes=premise_prefixes,
|
|
533
549
|
list_documents=list_documents,
|
|
534
550
|
max_concurrency=max_concurrency,
|
|
535
551
|
show_progress_bar=show_progress_bar,
|
|
@@ -566,7 +582,7 @@ def calculate_inference(
|
|
|
566
582
|
premise: Premise,
|
|
567
583
|
hypothesis: Hypothesis,
|
|
568
584
|
llm: BaseChatModel,
|
|
569
|
-
|
|
585
|
+
premise_prefix: Optional[Question] = None,
|
|
570
586
|
documents: Optional[Documents] = None,
|
|
571
587
|
max_concurrency: int = 8,
|
|
572
588
|
show_progress_bar: bool = True,
|
|
@@ -577,11 +593,13 @@ def calculate_inference(
|
|
|
577
593
|
Parameters
|
|
578
594
|
-----------
|
|
579
595
|
|
|
580
|
-
premise : str
|
|
596
|
+
premise : Union[str, List[str]]
|
|
581
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.
|
|
582
599
|
|
|
583
|
-
hypothesis : str
|
|
600
|
+
hypothesis : Union[str, List[str]]
|
|
584
601
|
The text of the hypothesis.
|
|
602
|
+
Can be a single text or a list of text fragments.
|
|
585
603
|
|
|
586
604
|
llm : BaseChatModel
|
|
587
605
|
The Langchain chat model used for calculating inference.
|
|
@@ -605,13 +623,13 @@ def calculate_inference(
|
|
|
605
623
|
along with a JSON string that explains how the inference was derived and
|
|
606
624
|
highlights string used for highlighting each segment of the hypothesis.
|
|
607
625
|
"""
|
|
608
|
-
|
|
626
|
+
premise_prefixes = None if premise_prefix is None else [premise_prefix]
|
|
609
627
|
list_documents = None if documents is None else [documents]
|
|
610
628
|
inference_returns = calculate_batch_inference(
|
|
611
629
|
premises=[premise],
|
|
612
630
|
hypotheses=[hypothesis],
|
|
613
631
|
llm=llm,
|
|
614
|
-
|
|
632
|
+
premise_prefixes=premise_prefixes,
|
|
615
633
|
list_documents=list_documents,
|
|
616
634
|
max_concurrency=max_concurrency,
|
|
617
635
|
show_progress_bar=show_progress_bar,
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from langchain_core.language_models import BaseChatModel
|
|
7
|
+
|
|
8
|
+
from aidial_rag_eval.generation.inference import calculate_batch_inference
|
|
9
|
+
from aidial_rag_eval.generation.refusal import calculate_batch_refusal
|
|
10
|
+
from aidial_rag_eval.generation.types import InferenceMetricBind, RefusalMetricBind
|
|
11
|
+
from aidial_rag_eval.types import MergedColumns
|
|
12
|
+
|
|
13
|
+
C2A_INFERENCE_PREFIX = "ctx_ans_"
|
|
14
|
+
A2GT_INFERENCE_PREFIX = "ans_gt_"
|
|
15
|
+
GT2A_INFERENCE_PREFIX = "gt_ans_"
|
|
16
|
+
A2F_INFERENCE_PREFIX = "ans_fct_"
|
|
17
|
+
F2A_INFERENCE_PREFIX = "fct_ans_"
|
|
18
|
+
|
|
19
|
+
ANSWER_REFUSAL_PREFIX = "answer_"
|
|
20
|
+
GT_ANSWER_REFUSAL_PREFIX = "ground_truth_"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _get_column_as_list(dataframe: pd.DataFrame, column: str) -> List[Any]:
|
|
24
|
+
return [x.tolist() if isinstance(x, np.ndarray) else x for x in dataframe[column]]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _wrapped_dataframe_inference(
|
|
28
|
+
df_merged: pd.DataFrame,
|
|
29
|
+
premise_column: str,
|
|
30
|
+
hypothesis_column: str,
|
|
31
|
+
llm: BaseChatModel,
|
|
32
|
+
prefix: str,
|
|
33
|
+
premise_prefix_column: Optional[str] = None,
|
|
34
|
+
document_column: Optional[str] = None,
|
|
35
|
+
max_concurrency: int = 8,
|
|
36
|
+
show_progress_bar: bool = True,
|
|
37
|
+
) -> pd.DataFrame:
|
|
38
|
+
inference_returns = calculate_batch_inference(
|
|
39
|
+
premises=_get_column_as_list(df_merged, premise_column),
|
|
40
|
+
hypotheses=_get_column_as_list(df_merged, hypothesis_column),
|
|
41
|
+
llm=llm,
|
|
42
|
+
premise_prefixes=(
|
|
43
|
+
_get_column_as_list(df_merged, premise_prefix_column)
|
|
44
|
+
if premise_prefix_column is not None
|
|
45
|
+
else None
|
|
46
|
+
),
|
|
47
|
+
list_documents=(
|
|
48
|
+
_get_column_as_list(df_merged, document_column)
|
|
49
|
+
if document_column is not None
|
|
50
|
+
else None
|
|
51
|
+
),
|
|
52
|
+
max_concurrency=max_concurrency,
|
|
53
|
+
show_progress_bar=show_progress_bar,
|
|
54
|
+
)
|
|
55
|
+
return pd.DataFrame(
|
|
56
|
+
[dataclasses.asdict(inference_return) for inference_return in inference_returns]
|
|
57
|
+
).add_prefix(prefix)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _wrapped_dataframe_refusal(
|
|
61
|
+
df_merged: pd.DataFrame,
|
|
62
|
+
answer_column: str,
|
|
63
|
+
llm: BaseChatModel,
|
|
64
|
+
prefix: str,
|
|
65
|
+
max_concurrency: int = 8,
|
|
66
|
+
show_progress_bar: bool = True,
|
|
67
|
+
) -> pd.DataFrame:
|
|
68
|
+
refusal_returns = calculate_batch_refusal(
|
|
69
|
+
answers=_get_column_as_list(df_merged, answer_column),
|
|
70
|
+
llm=llm,
|
|
71
|
+
max_concurrency=max_concurrency,
|
|
72
|
+
show_progress_bar=show_progress_bar,
|
|
73
|
+
)
|
|
74
|
+
return pd.DataFrame(
|
|
75
|
+
[dataclasses.asdict(refusal) for refusal in refusal_returns]
|
|
76
|
+
).add_prefix(prefix)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
CONTEXT_TO_ANSWER_INFERENCE = InferenceMetricBind(
|
|
80
|
+
premise_column=MergedColumns.CONTEXT,
|
|
81
|
+
hypothesis_column=MergedColumns.ANSWER,
|
|
82
|
+
prefix=C2A_INFERENCE_PREFIX,
|
|
83
|
+
document_column=MergedColumns.DOCUMENTS,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
ANSWER_TO_GROUND_TRUTH_INFERENCE = InferenceMetricBind(
|
|
87
|
+
premise_column=MergedColumns.ANSWER,
|
|
88
|
+
hypothesis_column=MergedColumns.GROUND_TRUTH_ANSWER,
|
|
89
|
+
prefix=A2GT_INFERENCE_PREFIX,
|
|
90
|
+
premise_prefix_column=MergedColumns.QUESTION,
|
|
91
|
+
document_column=MergedColumns.DOCUMENTS,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
GROUND_TRUTH_TO_ANSWER_INFERENCE = InferenceMetricBind(
|
|
95
|
+
premise_column=MergedColumns.GROUND_TRUTH_ANSWER,
|
|
96
|
+
hypothesis_column=MergedColumns.ANSWER,
|
|
97
|
+
prefix=GT2A_INFERENCE_PREFIX,
|
|
98
|
+
premise_prefix_column=MergedColumns.QUESTION,
|
|
99
|
+
document_column=MergedColumns.DOCUMENTS,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
ANSWER_TO_FACTS_INFERENCE = InferenceMetricBind(
|
|
103
|
+
premise_column=MergedColumns.ANSWER,
|
|
104
|
+
hypothesis_column=MergedColumns.FACTS,
|
|
105
|
+
prefix=A2F_INFERENCE_PREFIX,
|
|
106
|
+
premise_prefix_column=MergedColumns.QUESTION,
|
|
107
|
+
document_column=MergedColumns.DOCUMENTS,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
FACTS_TO_ANSWER_INFERENCE = InferenceMetricBind(
|
|
111
|
+
premise_column=MergedColumns.FACTS,
|
|
112
|
+
hypothesis_column=MergedColumns.ANSWER,
|
|
113
|
+
prefix=F2A_INFERENCE_PREFIX,
|
|
114
|
+
document_column=MergedColumns.DOCUMENTS,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
ANSWER_REFUSAL = RefusalMetricBind(
|
|
118
|
+
answer_column=MergedColumns.ANSWER,
|
|
119
|
+
prefix=ANSWER_REFUSAL_PREFIX,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
GROUND_TRUTH_REFUSAL = RefusalMetricBind(
|
|
123
|
+
answer_column=MergedColumns.GROUND_TRUTH_ANSWER,
|
|
124
|
+
prefix=GT_ANSWER_REFUSAL_PREFIX,
|
|
125
|
+
)
|
{aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/generation/types.py
RENAMED
|
@@ -3,19 +3,32 @@ import json
|
|
|
3
3
|
from dataclasses import dataclass, fields
|
|
4
4
|
from typing import List, Optional, Union
|
|
5
5
|
|
|
6
|
-
from aidial_rag_eval.types import Answer, GroundTruthAnswer, Text
|
|
7
|
-
|
|
8
6
|
TextSegment = str
|
|
9
|
-
JoinedContext = Text
|
|
10
7
|
|
|
11
|
-
Premise = Union[
|
|
12
|
-
Hypothesis = Union[
|
|
8
|
+
Premise = Union[str, List[str]]
|
|
9
|
+
Hypothesis = Union[str, List[str]]
|
|
13
10
|
Statement = str
|
|
14
11
|
HypothesisSegmentStatements = List[Statement]
|
|
15
12
|
HypothesisStatements = List[HypothesisSegmentStatements]
|
|
16
13
|
JoinedDocumentsName = str
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class InferenceMetricBind:
|
|
18
|
+
premise_column: str
|
|
19
|
+
hypothesis_column: str
|
|
20
|
+
prefix: str
|
|
21
|
+
premise_prefix_column: Optional[str] = None
|
|
22
|
+
document_column: Optional[str] = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
|
+
class RefusalMetricBind:
|
|
27
|
+
answer_column: str
|
|
28
|
+
prefix: str
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
MetricBind = Union[InferenceMetricBind, RefusalMetricBind]
|
|
19
32
|
|
|
20
33
|
|
|
21
34
|
@dataclass
|
|
@@ -3,7 +3,7 @@ from typing import Callable, List, Optional, Tuple
|
|
|
3
3
|
import spacy
|
|
4
4
|
from more_itertools import chunked, constrained_batches
|
|
5
5
|
|
|
6
|
-
from aidial_rag_eval.generation.types import
|
|
6
|
+
from aidial_rag_eval.generation.types import TextSegment
|
|
7
7
|
|
|
8
8
|
Splitter = Callable[[TextSegment], List[TextSegment]]
|
|
9
9
|
|
|
@@ -30,7 +30,7 @@ def _sent_tokenize(text: str) -> List[str]:
|
|
|
30
30
|
SegmentChecker = Callable[[TextSegment], bool]
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def get_delimiters(text:
|
|
33
|
+
def get_delimiters(text: str, segmented_text: List[TextSegment]) -> List[str]:
|
|
34
34
|
delimiters = []
|
|
35
35
|
start = 0
|
|
36
36
|
for i, part in enumerate(segmented_text[:-1]):
|
|
@@ -48,7 +48,7 @@ def get_delimiters(text: Text, segmented_text: List[TextSegment]) -> List[str]:
|
|
|
48
48
|
|
|
49
49
|
def join_with_delimiters(
|
|
50
50
|
segmented_text: List[TextSegment], delimiters: List[str]
|
|
51
|
-
) ->
|
|
51
|
+
) -> str:
|
|
52
52
|
result = []
|
|
53
53
|
for i in range(len(segmented_text)):
|
|
54
54
|
result.append(segmented_text[i])
|
|
@@ -101,7 +101,18 @@ class SegmentedText:
|
|
|
101
101
|
self.delimiters = delimiters.copy()
|
|
102
102
|
|
|
103
103
|
@classmethod
|
|
104
|
-
def
|
|
104
|
+
def from_list(cls, texts: List[str], delimiter: str = "\n") -> "SegmentedText":
|
|
105
|
+
segmented = [cls.from_text(text) for text in texts]
|
|
106
|
+
segments = segmented[0].segments.copy()
|
|
107
|
+
delimiters = segmented[0].delimiters.copy()
|
|
108
|
+
for st in segmented[1:]:
|
|
109
|
+
delimiters.append(delimiter)
|
|
110
|
+
segments.extend(st.segments)
|
|
111
|
+
delimiters.extend(st.delimiters)
|
|
112
|
+
return cls(segments, delimiters)
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def from_text(cls, text: str) -> "SegmentedText":
|
|
105
116
|
max_len = 500
|
|
106
117
|
min_len = 10
|
|
107
118
|
conditional_splitters: List[Splitter] = [
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from aidial_rag_eval.generation.metric_binds import (
|
|
2
|
+
ANSWER_REFUSAL,
|
|
3
|
+
ANSWER_TO_FACTS_INFERENCE,
|
|
4
|
+
ANSWER_TO_GROUND_TRUTH_INFERENCE,
|
|
5
|
+
CONTEXT_TO_ANSWER_INFERENCE,
|
|
6
|
+
FACTS_TO_ANSWER_INFERENCE,
|
|
7
|
+
GROUND_TRUTH_REFUSAL,
|
|
8
|
+
GROUND_TRUTH_TO_ANSWER_INFERENCE,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"CONTEXT_TO_ANSWER_INFERENCE",
|
|
13
|
+
"ANSWER_TO_GROUND_TRUTH_INFERENCE",
|
|
14
|
+
"ANSWER_TO_FACTS_INFERENCE",
|
|
15
|
+
"FACTS_TO_ANSWER_INFERENCE",
|
|
16
|
+
"GROUND_TRUTH_TO_ANSWER_INFERENCE",
|
|
17
|
+
"ANSWER_REFUSAL",
|
|
18
|
+
"GROUND_TRUTH_REFUSAL",
|
|
19
|
+
]
|
|
@@ -5,14 +5,13 @@ from typing import List, TypeVar
|
|
|
5
5
|
FactType = TypeVar("FactType")
|
|
6
6
|
ContextChunk = str
|
|
7
7
|
Document = str
|
|
8
|
-
Text = str
|
|
9
8
|
|
|
10
9
|
Context = List[ContextChunk]
|
|
11
10
|
Facts = List[FactType]
|
|
12
11
|
Documents = List[Document]
|
|
13
|
-
Question =
|
|
14
|
-
Answer =
|
|
15
|
-
GroundTruthAnswer =
|
|
12
|
+
Question = str
|
|
13
|
+
Answer = str
|
|
14
|
+
GroundTruthAnswer = str
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
@dataclass
|
|
@@ -52,7 +51,6 @@ class MergedColumns(str, Enum):
|
|
|
52
51
|
GROUND_TRUTH_ANSWER = "ground_truth_answer"
|
|
53
52
|
DOCUMENTS = GroundTruthColumns.DOCUMENTS.value
|
|
54
53
|
FACTS = GroundTruthColumns.FACTS.value
|
|
55
|
-
JOINED_CONTEXT = "joined_context"
|
|
56
54
|
|
|
57
55
|
|
|
58
56
|
MERGED_KEY_COLUMNS = [MergedColumns.DOCUMENTS, MergedColumns.QUESTION]
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import dataclasses
|
|
2
|
-
from typing import Any, Callable, Dict, List, Optional
|
|
3
|
-
|
|
4
|
-
import pandas as pd
|
|
5
|
-
from langchain_core.language_models import BaseChatModel
|
|
6
|
-
|
|
7
|
-
from aidial_rag_eval.generation.inference import calculate_batch_inference
|
|
8
|
-
from aidial_rag_eval.generation.refusal import calculate_batch_refusal
|
|
9
|
-
from aidial_rag_eval.generation.types import MetricBind
|
|
10
|
-
from aidial_rag_eval.types import MergedColumns
|
|
11
|
-
|
|
12
|
-
C2A_INFERENCE_PREFIX = "ctx_ans_"
|
|
13
|
-
A2GT_INFERENCE_PREFIX = "ans_gt_"
|
|
14
|
-
GT2A_INFERENCE_PREFIX = "gt_ans_"
|
|
15
|
-
|
|
16
|
-
ANSWER_REFUSAL_PREFIX = "answer_"
|
|
17
|
-
GT_ANSWER_REFUSAL_PREFIX = "ground_truth_"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def _get_column_as_list_str(dataframe: pd.DataFrame, column: str) -> List[Any]:
|
|
21
|
-
list_str = dataframe[column].to_list()
|
|
22
|
-
assert isinstance(list_str, list)
|
|
23
|
-
return list_str
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def _wrapped_dataframe_inference(
|
|
27
|
-
df_merged: pd.DataFrame,
|
|
28
|
-
premise_column: str,
|
|
29
|
-
hypothesis_column: str,
|
|
30
|
-
llm: BaseChatModel,
|
|
31
|
-
prefix: str,
|
|
32
|
-
question_column: Optional[str] = None,
|
|
33
|
-
document_column: Optional[str] = None,
|
|
34
|
-
max_concurrency: int = 8,
|
|
35
|
-
show_progress_bar: bool = True,
|
|
36
|
-
) -> pd.DataFrame:
|
|
37
|
-
inference_returns = calculate_batch_inference(
|
|
38
|
-
premises=_get_column_as_list_str(df_merged, premise_column),
|
|
39
|
-
hypotheses=_get_column_as_list_str(df_merged, hypothesis_column),
|
|
40
|
-
llm=llm,
|
|
41
|
-
questions=(
|
|
42
|
-
_get_column_as_list_str(df_merged, question_column)
|
|
43
|
-
if question_column is not None
|
|
44
|
-
else None
|
|
45
|
-
),
|
|
46
|
-
list_documents=(
|
|
47
|
-
_get_column_as_list_str(df_merged, document_column)
|
|
48
|
-
if document_column is not None
|
|
49
|
-
else None
|
|
50
|
-
),
|
|
51
|
-
max_concurrency=max_concurrency,
|
|
52
|
-
show_progress_bar=show_progress_bar,
|
|
53
|
-
)
|
|
54
|
-
return pd.DataFrame(
|
|
55
|
-
[dataclasses.asdict(inference_return) for inference_return in inference_returns]
|
|
56
|
-
).add_prefix(prefix)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _wrapped_dataframe_refusal(
|
|
60
|
-
df_merged: pd.DataFrame,
|
|
61
|
-
answer_column: str,
|
|
62
|
-
llm: BaseChatModel,
|
|
63
|
-
prefix: str,
|
|
64
|
-
max_concurrency: int = 8,
|
|
65
|
-
show_progress_bar: bool = True,
|
|
66
|
-
) -> pd.DataFrame:
|
|
67
|
-
refusal_returns = calculate_batch_refusal(
|
|
68
|
-
answers=_get_column_as_list_str(df_merged, answer_column),
|
|
69
|
-
llm=llm,
|
|
70
|
-
max_concurrency=max_concurrency,
|
|
71
|
-
show_progress_bar=show_progress_bar,
|
|
72
|
-
)
|
|
73
|
-
return pd.DataFrame(
|
|
74
|
-
[dataclasses.asdict(refusal) for refusal in refusal_returns]
|
|
75
|
-
).add_prefix(prefix)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def context_to_answer_inference(
|
|
79
|
-
df_merged, llm, max_concurrency, show_progress_bar, **kwargs
|
|
80
|
-
) -> pd.DataFrame:
|
|
81
|
-
return _wrapped_dataframe_inference(
|
|
82
|
-
df_merged=df_merged,
|
|
83
|
-
premise_column=MergedColumns.JOINED_CONTEXT,
|
|
84
|
-
hypothesis_column=MergedColumns.ANSWER,
|
|
85
|
-
llm=llm,
|
|
86
|
-
prefix=C2A_INFERENCE_PREFIX,
|
|
87
|
-
# The last segment(sentence) of the question is attached to the premise.
|
|
88
|
-
# This can be helpful when the premise is the answer or ground truth
|
|
89
|
-
# and it is simple. Example:
|
|
90
|
-
# question: how many boxes are in the cupboard?
|
|
91
|
-
# answer (premise): 3.
|
|
92
|
-
# When the premise is the context, the question is not needed.
|
|
93
|
-
question_column=None,
|
|
94
|
-
document_column=MergedColumns.DOCUMENTS,
|
|
95
|
-
max_concurrency=max_concurrency,
|
|
96
|
-
show_progress_bar=show_progress_bar,
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def answer_to_ground_truth_inference(
|
|
101
|
-
df_merged, llm, max_concurrency, show_progress_bar, **kwargs
|
|
102
|
-
) -> pd.DataFrame:
|
|
103
|
-
return _wrapped_dataframe_inference(
|
|
104
|
-
df_merged=df_merged,
|
|
105
|
-
premise_column=MergedColumns.ANSWER,
|
|
106
|
-
hypothesis_column=MergedColumns.GROUND_TRUTH_ANSWER,
|
|
107
|
-
llm=llm,
|
|
108
|
-
prefix=A2GT_INFERENCE_PREFIX,
|
|
109
|
-
question_column=MergedColumns.QUESTION,
|
|
110
|
-
document_column=MergedColumns.DOCUMENTS,
|
|
111
|
-
max_concurrency=max_concurrency,
|
|
112
|
-
show_progress_bar=show_progress_bar,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def ground_truth_to_answer_inference(
|
|
117
|
-
df_merged, llm, max_concurrency, show_progress_bar, **kwargs
|
|
118
|
-
) -> pd.DataFrame:
|
|
119
|
-
return _wrapped_dataframe_inference(
|
|
120
|
-
df_merged=df_merged,
|
|
121
|
-
premise_column=MergedColumns.GROUND_TRUTH_ANSWER,
|
|
122
|
-
hypothesis_column=MergedColumns.ANSWER,
|
|
123
|
-
llm=llm,
|
|
124
|
-
prefix=GT2A_INFERENCE_PREFIX,
|
|
125
|
-
question_column=MergedColumns.QUESTION,
|
|
126
|
-
document_column=MergedColumns.DOCUMENTS,
|
|
127
|
-
max_concurrency=max_concurrency,
|
|
128
|
-
show_progress_bar=show_progress_bar,
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def answer_refusal(
|
|
133
|
-
df_merged, llm, max_concurrency, show_progress_bar, **kwargs
|
|
134
|
-
) -> pd.DataFrame:
|
|
135
|
-
return _wrapped_dataframe_refusal(
|
|
136
|
-
df_merged=df_merged,
|
|
137
|
-
answer_column=MergedColumns.ANSWER,
|
|
138
|
-
llm=llm,
|
|
139
|
-
prefix=ANSWER_REFUSAL_PREFIX,
|
|
140
|
-
max_concurrency=max_concurrency,
|
|
141
|
-
show_progress_bar=show_progress_bar,
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def ground_truth_refusal(
|
|
146
|
-
df_merged, llm, max_concurrency, show_progress_bar, **kwargs
|
|
147
|
-
) -> pd.DataFrame:
|
|
148
|
-
return _wrapped_dataframe_refusal(
|
|
149
|
-
df_merged=df_merged,
|
|
150
|
-
answer_column=MergedColumns.GROUND_TRUTH_ANSWER,
|
|
151
|
-
llm=llm,
|
|
152
|
-
prefix=GT_ANSWER_REFUSAL_PREFIX,
|
|
153
|
-
max_concurrency=max_concurrency,
|
|
154
|
-
show_progress_bar=show_progress_bar,
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
metric_binds_dict: Dict[MetricBind, Callable] = {
|
|
159
|
-
"context_to_answer_inference": context_to_answer_inference,
|
|
160
|
-
"answer_to_ground_truth_inference": answer_to_ground_truth_inference,
|
|
161
|
-
"ground_truth_to_answer_inference": ground_truth_to_answer_inference,
|
|
162
|
-
"answer_refusal": answer_refusal,
|
|
163
|
-
"ground_truth_refusal": ground_truth_refusal,
|
|
164
|
-
}
|
|
165
|
-
metric_bind_keys: List[MetricBind] = list(metric_binds_dict.keys())
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
from aidial_rag_eval.generation.metric_binds import metric_bind_keys
|
|
2
|
-
|
|
3
|
-
CONTEXT_TO_ANSWER_INFERENCE = metric_bind_keys[0]
|
|
4
|
-
ANSWER_TO_GROUND_TRUTH_INFERENCE = metric_bind_keys[1]
|
|
5
|
-
GROUND_TRUTH_TO_ANSWER_INFERENCE = metric_bind_keys[2]
|
|
6
|
-
ANSWER_REFUSAL = metric_bind_keys[3]
|
|
7
|
-
GROUND_TRUTH_REFUSAL = metric_bind_keys[4]
|
|
8
|
-
|
|
9
|
-
__all__ = [
|
|
10
|
-
"CONTEXT_TO_ANSWER_INFERENCE",
|
|
11
|
-
"ANSWER_TO_GROUND_TRUTH_INFERENCE",
|
|
12
|
-
"GROUND_TRUTH_TO_ANSWER_INFERENCE",
|
|
13
|
-
"ANSWER_REFUSAL",
|
|
14
|
-
"GROUND_TRUTH_REFUSAL",
|
|
15
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/dataframe/merge.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/__init__.py
RENAMED
|
File without changes
|
{aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/citation.py
RENAMED
|
File without changes
|
{aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/facts/exact.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/metrics.py
RENAMED
|
File without changes
|
{aidial_rag_eval-0.6.0.dev19 → aidial_rag_eval-0.6.0.dev20}/src/aidial_rag_eval/retrieval/types.py
RENAMED
|
File without changes
|
|
File without changes
|