flashrag-dev 0.1.3.dev20241117__tar.gz → 0.1.3.dev20241120__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.
- {flashrag-dev-0.1.3.dev20241117/flashrag_dev.egg-info → flashrag-dev-0.1.3.dev20241120}/PKG-INFO +1 -1
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/dataset/dataset.py +5 -2
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/dataset/utils.py +2 -0
- flashrag-dev-0.1.3.dev20241120/flashrag/generator/fid.py +206 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/generator.py +17 -10
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/active_pipeline.py +85 -48
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/pipeline.py +8 -6
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/retriever.py +8 -3
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/utils.py +17 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/utils/utils.py +1 -1
- flashrag-dev-0.1.3.dev20241120/flashrag/version.py +1 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120/flashrag_dev.egg-info}/PKG-INFO +1 -1
- flashrag-dev-0.1.3.dev20241117/flashrag/generator/fid.py +0 -247
- flashrag-dev-0.1.3.dev20241117/flashrag/version.py +0 -1
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/LICENSE +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/README.md +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/config/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/config/basic_config.yaml +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/config/config.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/dataset/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/_bleu.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/evaluator.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/metrics.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/utils.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/openai_generator.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/stop_word_criteria.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/utils.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/judger/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/judger/judger.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/branching_pipeline.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/replug_utils.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/prompt/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/prompt/base_prompt.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/prompt/selfask_examplars.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/prompt/trace_examplars.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/kg_refiner.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/llmlingua_compressor.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/refiner.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/selective_context_compressor.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/__main__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/encoder.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/index_builder.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/reranker.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/utils/__init__.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/utils/constants.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/utils/pred_parse.py +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag_dev.egg-info/SOURCES.txt +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag_dev.egg-info/dependency_links.txt +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag_dev.egg-info/requires.txt +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag_dev.egg-info/top_level.txt +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/pyproject.toml +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/setup.cfg +0 -0
- {flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/setup.py +0 -0
{flashrag-dev-0.1.3.dev20241117/flashrag_dev.egg-info → flashrag-dev-0.1.3.dev20241120}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flashrag-dev
|
|
3
|
-
Version: 0.1.3.
|
|
3
|
+
Version: 0.1.3.dev20241120
|
|
4
4
|
Summary: A library for efficient Retrieval-Augmented Generation research
|
|
5
5
|
Home-page: https://github.com/RUC-NLPIR/FlashRAG
|
|
6
6
|
Author: Jiajie Jin, Yutao Zhu, Chenghao Zhang, Xinyu Yang, Zhicheng Dou
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/dataset/dataset.py
RENAMED
|
@@ -174,9 +174,12 @@ class Dataset:
|
|
|
174
174
|
"""Save the dataset into the original format."""
|
|
175
175
|
|
|
176
176
|
save_data = [item.to_dict() for item in self.data]
|
|
177
|
-
|
|
177
|
+
def custom_serializer(obj):
|
|
178
|
+
if isinstance(obj, np.float32):
|
|
179
|
+
return float(obj)
|
|
180
|
+
raise TypeError(f"Type {type(obj)} not serializable")
|
|
178
181
|
with open(save_path, "w", encoding="utf-8") as f:
|
|
179
|
-
json.dump(save_data, f, indent=4)
|
|
182
|
+
json.dump(save_data, f, indent=4, default=custom_serializer)
|
|
180
183
|
|
|
181
184
|
def __str__(self) -> str:
|
|
182
185
|
"""Return a string representation of the dataset with a summary of items."""
|
|
@@ -13,6 +13,8 @@ def convert_numpy(obj: Union[Dict, list, np.ndarray, np.generic]) -> Any:
|
|
|
13
13
|
return obj.tolist() # Convert numpy arrays to lists
|
|
14
14
|
elif isinstance(obj, (np.integer, np.floating)):
|
|
15
15
|
return obj.item() # Convert numpy scalars to native Python scalars
|
|
16
|
+
elif isinstance(obj, np.float32):
|
|
17
|
+
return float(obj)
|
|
16
18
|
else:
|
|
17
19
|
return obj # Return the object as-is if it's neither a dict, list, nor numpy type
|
|
18
20
|
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Source: FiD official repo: https://github.com/facebookresearch/FiD
|
|
2
|
+
# This software is released under Creative Commons public licenses.
|
|
3
|
+
|
|
4
|
+
import torch
|
|
5
|
+
import torch.nn as nn
|
|
6
|
+
import transformers
|
|
7
|
+
import types
|
|
8
|
+
import torch.nn.functional as F
|
|
9
|
+
from torch.nn import CrossEntropyLoss
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
class FiDT5(transformers.T5ForConditionalGeneration):
|
|
13
|
+
def __init__(self, config):
|
|
14
|
+
super().__init__(config)
|
|
15
|
+
self.wrap_encoder()
|
|
16
|
+
|
|
17
|
+
def forward_(self, **kwargs):
|
|
18
|
+
if 'input_ids' in kwargs:
|
|
19
|
+
kwargs['input_ids'] = kwargs['input_ids'].view(kwargs['input_ids'].size(0), -1)
|
|
20
|
+
if 'attention_mask' in kwargs:
|
|
21
|
+
kwargs['attention_mask'] = kwargs['attention_mask'].view(kwargs['attention_mask'].size(0), -1)
|
|
22
|
+
|
|
23
|
+
return super(FiDT5, self).forward(
|
|
24
|
+
**kwargs
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# input ids : bs, n, seq_len -> bs, n*seq_len
|
|
28
|
+
# We need to resize as B x (N * L) instead of (B * N) x L here
|
|
29
|
+
# because the T5 forward method uses the input tensors to infer
|
|
30
|
+
# dimensions used in the decoder.
|
|
31
|
+
# EncoderWrapper resizes the inputs as (B * N) x L.
|
|
32
|
+
def forward(self, input_ids=None, attention_mask=None, **kwargs):
|
|
33
|
+
if input_ids != None:
|
|
34
|
+
# (bs, n, seq_len) -> (bs, n*seq_len)
|
|
35
|
+
# inputs might have already be resized in the generate method
|
|
36
|
+
if input_ids.dim() == 3:
|
|
37
|
+
self.encoder.n_passages = input_ids.size(1)
|
|
38
|
+
input_ids = input_ids.view(input_ids.size(0), -1)
|
|
39
|
+
if attention_mask != None:
|
|
40
|
+
attention_mask = attention_mask.view(attention_mask.size(0), -1)
|
|
41
|
+
#print(input_ids.shape)
|
|
42
|
+
return super().forward(
|
|
43
|
+
input_ids=input_ids,
|
|
44
|
+
attention_mask=attention_mask,
|
|
45
|
+
**kwargs
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def generate(self, input_ids, attention_mask, **kwargs):
|
|
49
|
+
# input ids - bs, n, seq_len -> bs, n*seq_len
|
|
50
|
+
self.encoder.n_passages = input_ids.size(1)
|
|
51
|
+
return super().generate(
|
|
52
|
+
input_ids=input_ids.view(input_ids.size(0), -1),
|
|
53
|
+
attention_mask=attention_mask.view(attention_mask.size(0), -1),
|
|
54
|
+
**kwargs,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def wrap_encoder(self, use_checkpoint=False):
|
|
58
|
+
"""
|
|
59
|
+
Wrap T5 encoder to obtain a Fusion-in-Decoder model.
|
|
60
|
+
"""
|
|
61
|
+
self.encoder = EncoderWrapper(self.encoder)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def unwrap_encoder(self):
|
|
65
|
+
"""
|
|
66
|
+
Unwrap Fusion-in-Decoder encoder, useful to load T5 weights.
|
|
67
|
+
"""
|
|
68
|
+
self.encoder = self.encoder.encoder
|
|
69
|
+
block = []
|
|
70
|
+
for mod in self.encoder.block:
|
|
71
|
+
block.append(mod.module)
|
|
72
|
+
block = nn.ModuleList(block)
|
|
73
|
+
self.encoder.block = block
|
|
74
|
+
|
|
75
|
+
def load_t5(self, state_dict):
|
|
76
|
+
self.unwrap_encoder()
|
|
77
|
+
self.load_state_dict(state_dict)
|
|
78
|
+
self.wrap_encoder()
|
|
79
|
+
|
|
80
|
+
def set_checkpoint(self, use_checkpoint):
|
|
81
|
+
"""
|
|
82
|
+
Enable or disable checkpointing in the encoder.
|
|
83
|
+
See https://pytorch.org/docs/stable/checkpoint.html
|
|
84
|
+
"""
|
|
85
|
+
for mod in self.encoder.encoder.block:
|
|
86
|
+
mod.use_checkpoint = use_checkpoint
|
|
87
|
+
|
|
88
|
+
def tie_weights(self):
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
class CheckpointWrapper(torch.nn.Module):
|
|
92
|
+
"""
|
|
93
|
+
Wrapper replacing None outputs by empty tensors, which allows the use of
|
|
94
|
+
checkpointing.
|
|
95
|
+
"""
|
|
96
|
+
def __init__(self, module, use_checkpoint=False):
|
|
97
|
+
super().__init__()
|
|
98
|
+
self.module = module
|
|
99
|
+
self.use_checkpoint = use_checkpoint
|
|
100
|
+
|
|
101
|
+
def forward(self, hidden_states, attention_mask, position_bias, **kwargs):
|
|
102
|
+
if self.use_checkpoint and self.training:
|
|
103
|
+
kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
|
104
|
+
def custom_forward(*inputs):
|
|
105
|
+
output = self.module(*inputs, **kwargs)
|
|
106
|
+
empty = torch.tensor(
|
|
107
|
+
[],
|
|
108
|
+
dtype=torch.float,
|
|
109
|
+
device=output[0].device,
|
|
110
|
+
requires_grad=True)
|
|
111
|
+
output = tuple(x if x is not None else empty for x in output)
|
|
112
|
+
return output
|
|
113
|
+
|
|
114
|
+
output = torch.utils.checkpoint.checkpoint(
|
|
115
|
+
custom_forward,
|
|
116
|
+
hidden_states,
|
|
117
|
+
attention_mask,
|
|
118
|
+
position_bias
|
|
119
|
+
)
|
|
120
|
+
output = tuple(x if x.size() != 0 else None for x in output)
|
|
121
|
+
else:
|
|
122
|
+
output = self.module(hidden_states, attention_mask, position_bias, **kwargs)
|
|
123
|
+
return output
|
|
124
|
+
|
|
125
|
+
def apply_checkpoint_wrapper(t5stack, use_checkpoint):
|
|
126
|
+
"""
|
|
127
|
+
Wrap each block of the encoder to enable checkpointing.
|
|
128
|
+
"""
|
|
129
|
+
block = []
|
|
130
|
+
for mod in t5stack.block:
|
|
131
|
+
wrapped_mod = CheckpointWrapper(mod, use_checkpoint)
|
|
132
|
+
block.append(wrapped_mod)
|
|
133
|
+
block = nn.ModuleList(block)
|
|
134
|
+
t5stack.block = block
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class FiDBart(transformers.BartForConditionalGeneration):
|
|
138
|
+
def __init__(self, config):
|
|
139
|
+
super().__init__(config)
|
|
140
|
+
self.wrap_encoder()
|
|
141
|
+
|
|
142
|
+
def forward(self, input_ids=None, attention_mask=None, **kwargs):
|
|
143
|
+
|
|
144
|
+
if input_ids != None:
|
|
145
|
+
# (bs, n, seq_len) -> (bs, n*seq_len)
|
|
146
|
+
# inputs might have already be resized in the generate method
|
|
147
|
+
if input_ids.dim() == 3:
|
|
148
|
+
self.model.encoder.n_passages = input_ids.size(1)
|
|
149
|
+
input_ids = input_ids.view(input_ids.size(0), -1)
|
|
150
|
+
|
|
151
|
+
if attention_mask != None:
|
|
152
|
+
attention_mask = attention_mask.view(attention_mask.size(0), -1)
|
|
153
|
+
|
|
154
|
+
return super().forward(input_ids=input_ids, attention_mask=attention_mask, **kwargs)
|
|
155
|
+
|
|
156
|
+
def generate(self, input_ids, attention_mask, **kwargs):
|
|
157
|
+
self.model.encoder.n_passages = input_ids.size(1)
|
|
158
|
+
return super().generate(
|
|
159
|
+
input_ids=input_ids.view(input_ids.size(0), -1),
|
|
160
|
+
attention_mask=attention_mask.view(attention_mask.size(0),-1),
|
|
161
|
+
**kwargs)
|
|
162
|
+
|
|
163
|
+
def wrap_encoder(self):
|
|
164
|
+
"""
|
|
165
|
+
Wrap T5 encoder to obtain a Fusion-in-Decoder model.
|
|
166
|
+
"""
|
|
167
|
+
self.model.encoder = EncoderWrapper(self.model.encoder)
|
|
168
|
+
|
|
169
|
+
def unwrap_encoder(self):
|
|
170
|
+
"""
|
|
171
|
+
Unwrap Fusion-in-Decoder encoder, useful to load bart weights.
|
|
172
|
+
"""
|
|
173
|
+
self.model.encoder = self.model.encoder.encoder
|
|
174
|
+
block = []
|
|
175
|
+
for mod in self.model.encoder.layers:
|
|
176
|
+
block.append(mod)
|
|
177
|
+
block = nn.ModuleList(block)
|
|
178
|
+
self.model.encoder.layers = block
|
|
179
|
+
|
|
180
|
+
def load_pretrained_model(self, state_dict):
|
|
181
|
+
self.unwrap_encoder()
|
|
182
|
+
self.load_state_dict(state_dict)
|
|
183
|
+
self.wrap_encoder()
|
|
184
|
+
def tie_weights(self):
|
|
185
|
+
pass
|
|
186
|
+
|
|
187
|
+
class EncoderWrapper(torch.nn.Module):
|
|
188
|
+
def __init__(self, encoder,use_checkpoint=False):
|
|
189
|
+
super().__init__()
|
|
190
|
+
self.encoder = encoder
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
self.main_input_name = encoder.main_input_name
|
|
194
|
+
except:
|
|
195
|
+
pass
|
|
196
|
+
apply_checkpoint_wrapper(self.encoder, use_checkpoint)
|
|
197
|
+
|
|
198
|
+
def forward(self, input_ids=None, attention_mask=None,**kwargs):
|
|
199
|
+
bsz, total_length = input_ids.shape
|
|
200
|
+
passage_length = total_length // self.n_passages
|
|
201
|
+
# total_input
|
|
202
|
+
input_ids = input_ids.view(bsz*self.n_passages, passage_length)
|
|
203
|
+
attention_mask = attention_mask.view(bsz*self.n_passages, passage_length)
|
|
204
|
+
outputs = self.encoder(input_ids=input_ids, attention_mask=attention_mask, **kwargs)
|
|
205
|
+
outputs.last_hidden_state = outputs.last_hidden_state.view(bsz, self.n_passages*passage_length, -1)
|
|
206
|
+
return outputs
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/generator.py
RENAMED
|
@@ -49,10 +49,9 @@ class EncoderDecoderGenerator(BaseGenerator):
|
|
|
49
49
|
self.fid = config["use_fid"]
|
|
50
50
|
model_config = AutoConfig.from_pretrained(self.model_path)
|
|
51
51
|
arch = model_config.architectures[0].lower()
|
|
52
|
-
if "t5" in arch:
|
|
52
|
+
if "t5" in arch or 'fusionindecoder' in arch:
|
|
53
53
|
if self.fid:
|
|
54
54
|
from flashrag.generator.fid import FiDT5
|
|
55
|
-
|
|
56
55
|
self.model = FiDT5.from_pretrained(self.model_path)
|
|
57
56
|
else:
|
|
58
57
|
self.model = T5ForConditionalGeneration.from_pretrained(self.model_path)
|
|
@@ -65,17 +64,18 @@ class EncoderDecoderGenerator(BaseGenerator):
|
|
|
65
64
|
self.tokenizer = AutoTokenizer.from_pretrained(self.model_path)
|
|
66
65
|
|
|
67
66
|
def encode_passages(self, batch_text_passages: List[List[str]]):
|
|
67
|
+
# need size: [batch_size, passage_num, passage_len]
|
|
68
68
|
passage_ids, passage_masks = [], []
|
|
69
|
-
for
|
|
70
|
-
p = self.tokenizer
|
|
69
|
+
for text_passages in batch_text_passages:
|
|
70
|
+
p = self.tokenizer(
|
|
71
71
|
text_passages,
|
|
72
72
|
max_length=self.max_input_len,
|
|
73
|
-
|
|
74
|
-
return_tensors="pt",
|
|
73
|
+
padding='max_length',
|
|
75
74
|
truncation=True,
|
|
75
|
+
return_tensors='pt'
|
|
76
76
|
)
|
|
77
|
-
passage_ids.append(p[
|
|
78
|
-
passage_masks.append(p[
|
|
77
|
+
passage_ids.append(p['input_ids'][None])
|
|
78
|
+
passage_masks.append(p['attention_mask'][None])
|
|
79
79
|
|
|
80
80
|
passage_ids = torch.cat(passage_ids, dim=0)
|
|
81
81
|
passage_masks = torch.cat(passage_masks, dim=0)
|
|
@@ -128,8 +128,15 @@ class EncoderDecoderGenerator(BaseGenerator):
|
|
|
128
128
|
).to(self.device)
|
|
129
129
|
|
|
130
130
|
# TODO: multi-gpu inference
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
if self.fid:
|
|
132
|
+
if 'max_new_tokens' in generation_params:
|
|
133
|
+
max_new_tokens = generation_params.pop('max_new_tokens')
|
|
134
|
+
else:
|
|
135
|
+
max_new_tokens = 32
|
|
136
|
+
|
|
137
|
+
outputs = self.model.generate(**inputs, max_new_tokens=max_new_tokens, pad_token_id=self.tokenizer.pad_token_id, decoder_start_token_id=self.tokenizer.pad_token_id)
|
|
138
|
+
else:
|
|
139
|
+
outputs = self.model.generate(**inputs, **generation_params)
|
|
133
140
|
outputs = self.tokenizer.batch_decode(
|
|
134
141
|
outputs,
|
|
135
142
|
skip_special_tokens=True,
|
|
@@ -898,12 +898,12 @@ class SelfAskPipeline(BasicPipeline):
|
|
|
898
898
|
dataset = self.evaluate(dataset, do_eval=do_eval, pred_process_fun=pred_process_fun)
|
|
899
899
|
return dataset
|
|
900
900
|
|
|
901
|
-
|
|
901
|
+
|
|
902
902
|
class IRCOTPipeline(BasicPipeline):
|
|
903
903
|
IRCOT_INSTRUCTION = 'You serve as an intelligent assistant, adept at facilitating users through complex, multi-hop reasoning across multiple documents. This task is illustrated through demonstrations, each consisting of a document set paired with a relevant question and its multi-hop reasoning thoughts. Your task is to generate one thought for current step, DON\'T generate the whole thoughts at once! If you reach what you believe to be the final step, start with "So the answer is:".'
|
|
904
904
|
IRCOT_EXAMPLE = "Wikipedia Title: Kurram Garhi\nKurram Garhi is a small village located near the city of Bannu, which is the part of Khyber Pakhtunkhwa province of Pakistan. Its population is approximately 35000. Barren hills are near this village. This village is on the border of Kurram Agency. Other nearby villages are Peppal, Surwangi and Amandi Kala.\n\nWikipedia Title: 2001–02 UEFA Champions League second group stage\nEight winners and eight runners- up from the first group stage were drawn into four groups of four teams, each containing two group winners and two runners- up. Teams from the same country or from the same first round group could not be drawn together. The top two teams in each group advanced to the quarter- finals.\n\nWikipedia Title: Satellite tournament\nA satellite tournament is either a minor tournament or event on a competitive sporting tour or one of a group of such tournaments that form a series played in the same country or region.\n\nWikipedia Title: Trojkrsti\nTrojkrsti is a village in Municipality of Prilep, Republic of Macedonia.\n\nWikipedia Title: Telephone numbers in Ascension Island\nCountry Code:+ 247< br> International Call Prefix: 00 Ascension Island does not share the same country code( +290) with the rest of St Helena.\n\nQuestion: Are both Kurram Garhi and Trojkrsti located in the same country?\nThought: Kurram Garhi is located in the country of Pakistan. Trojkrsti is located in the country of Republic of Macedonia. Thus, they are not in the same country. So the answer is: no.\n\n"
|
|
905
905
|
|
|
906
|
-
def __init__(self, config, prompt_template=None, retriever=None, generator=None, max_iter=
|
|
906
|
+
def __init__(self, config, prompt_template=None, retriever=None, generator=None, max_iter=5):
|
|
907
907
|
# if not provide prompt template, use default template provided by IRCOT
|
|
908
908
|
if prompt_template is None:
|
|
909
909
|
prompt_template = PromptTemplate(
|
|
@@ -920,60 +920,97 @@ class IRCOTPipeline(BasicPipeline):
|
|
|
920
920
|
|
|
921
921
|
self.max_iter = max_iter
|
|
922
922
|
|
|
923
|
-
def
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
doc2score = {doc_item["id"]: score for doc_item, score in zip(retrieval_result, scores)}
|
|
927
|
-
id2doc = {doc_item["id"]: doc_item for doc_item in retrieval_result}
|
|
928
|
-
|
|
929
|
-
thoughts = []
|
|
923
|
+
def run_batch(self, items):
|
|
924
|
+
# Initialize the necessary data structures
|
|
925
|
+
batch_thoughts = {item_id: [] for item_id in range(len(items))}
|
|
930
926
|
iter_num = 0
|
|
927
|
+
batch_retrieval_results = []
|
|
928
|
+
doc2score_batch = []
|
|
929
|
+
id2doc_batch = []
|
|
930
|
+
|
|
931
|
+
# Initial retrieval for all items in the batch
|
|
932
|
+
questions = [item.question for item in items]
|
|
933
|
+
retrieval_results, scoress = self.retriever.batch_search(questions, return_score=True)
|
|
934
|
+
for retrieval_result, scores in zip(retrieval_results,scoress):
|
|
935
|
+
|
|
936
|
+
doc2score = {doc_item['id']: score for doc_item, score in zip(retrieval_result, scores)}
|
|
937
|
+
id2doc = {doc_item['id']: doc_item for doc_item in retrieval_result}
|
|
938
|
+
batch_retrieval_results.append(retrieval_result)
|
|
939
|
+
doc2score_batch.append(doc2score)
|
|
940
|
+
id2doc_batch.append(id2doc)
|
|
941
|
+
|
|
942
|
+
# Start the iterative process
|
|
943
|
+
active_item_ids = list(range(len(items))) # Track items that need more iterations
|
|
931
944
|
while iter_num < self.max_iter:
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
if "So the answer is:" in new_thought:
|
|
939
|
-
item.update_output(
|
|
940
|
-
f"intermediate_output_iter{iter_num}",
|
|
941
|
-
{
|
|
942
|
-
"input_prompt": input_prompt,
|
|
943
|
-
"new_thought": new_thought,
|
|
944
|
-
},
|
|
945
|
+
# Generate prompts and new thoughts for the active items
|
|
946
|
+
input_prompts = [
|
|
947
|
+
self.prompt_template.get_string(
|
|
948
|
+
question=items[item_id].question,
|
|
949
|
+
retrieval_result=batch_retrieval_results[item_id],
|
|
950
|
+
previous_gen=' '.join(batch_thoughts[item_id])
|
|
945
951
|
)
|
|
946
|
-
|
|
952
|
+
for item_id in active_item_ids
|
|
953
|
+
]
|
|
947
954
|
|
|
948
|
-
#
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
+
# Batch generation for active items
|
|
956
|
+
new_thoughts_batch = self.generator.generate(input_prompts, stop=['.', '\n'])
|
|
957
|
+
|
|
958
|
+
# Update thoughts and determine next active items
|
|
959
|
+
new_active_item_ids = []
|
|
960
|
+
for idx, item_id in enumerate(active_item_ids):
|
|
961
|
+
new_thought = new_thoughts_batch[idx]
|
|
962
|
+
batch_thoughts[item_id].append(new_thought)
|
|
963
|
+
|
|
964
|
+
# Check for termination condition
|
|
965
|
+
# Store intermediate outputs
|
|
966
|
+
if "So the answer is:" in new_thought:
|
|
967
|
+
items[item_id].update_output(
|
|
968
|
+
f'intermediate_output_iter{iter_num}',
|
|
969
|
+
{
|
|
970
|
+
'input_prompt': input_prompts[idx],
|
|
971
|
+
'new_thought': new_thought,
|
|
972
|
+
},
|
|
973
|
+
)
|
|
955
974
|
else:
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
975
|
+
new_active_item_ids.append(item_id)
|
|
976
|
+
|
|
977
|
+
# Update active item IDs for the next iteration
|
|
978
|
+
active_item_ids = new_active_item_ids
|
|
979
|
+
|
|
980
|
+
# Perform batch retrieval for new thoughts of active items
|
|
981
|
+
if active_item_ids:
|
|
982
|
+
print(len(active_item_ids))
|
|
983
|
+
print(active_item_ids)
|
|
984
|
+
new_thoughts_for_retrieval = [batch_thoughts[item_id][-1] for item_id in active_item_ids]
|
|
985
|
+
new_retrieval_results, new_scoress = self.retriever.batch_search(new_thoughts_for_retrieval, return_score=True)
|
|
986
|
+
|
|
987
|
+
for i, item_id in enumerate(active_item_ids):
|
|
988
|
+
new_retrieval_result, new_scores = new_retrieval_results[i],new_scoress[i]
|
|
989
|
+
|
|
990
|
+
# Update doc2score and id2doc for the current item
|
|
991
|
+
for doc_item, score in zip(new_retrieval_result, new_scores):
|
|
992
|
+
doc_id = doc_item['id']
|
|
993
|
+
id2doc_batch[item_id][doc_id] = doc_item
|
|
994
|
+
if doc_id in doc2score_batch[item_id]:
|
|
995
|
+
doc2score_batch[item_id][doc_id] = max(doc2score_batch[item_id][doc_id], score)
|
|
996
|
+
else:
|
|
997
|
+
doc2score_batch[item_id][doc_id] = score
|
|
969
998
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
999
|
+
# Sort and update retrieval results
|
|
1000
|
+
sorted_doc_score = sorted(doc2score_batch[item_id].items(), key=lambda x: x[1], reverse=False)
|
|
1001
|
+
sorted_doc_id = [t[0] for t in sorted_doc_score]
|
|
1002
|
+
batch_retrieval_results[item_id] = [id2doc_batch[item_id][id] for id in sorted_doc_id]
|
|
1003
|
+
|
|
1004
|
+
iter_num += 1
|
|
1005
|
+
|
|
1006
|
+
# Final update for each item in the batch
|
|
1007
|
+
for item_id, item in enumerate(items):
|
|
1008
|
+
item.update_output('retrieval_result', batch_retrieval_results[item_id])
|
|
1009
|
+
item.update_output('pred', ' '.join(batch_thoughts[item_id]))
|
|
973
1010
|
|
|
974
1011
|
def run(self, dataset, do_eval=True, pred_process_fun=ircot_pred_parse):
|
|
975
|
-
|
|
976
|
-
|
|
1012
|
+
|
|
1013
|
+
self.run_batch(dataset)
|
|
977
1014
|
|
|
978
1015
|
dataset = self.evaluate(dataset, do_eval=do_eval, pred_process_fun=pred_process_fun)
|
|
979
1016
|
return dataset
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/pipeline.py
RENAMED
|
@@ -107,11 +107,11 @@ class SequentialPipeline(BasicPipeline):
|
|
|
107
107
|
]
|
|
108
108
|
|
|
109
109
|
else:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
if not self.use_fid:
|
|
111
|
+
input_prompts = [
|
|
112
|
+
self.prompt_template.get_string(question=q, retrieval_result=r)
|
|
113
|
+
for q, r in zip(dataset.question, dataset.retrieval_result)
|
|
114
|
+
]
|
|
115
115
|
|
|
116
116
|
if self.use_fid:
|
|
117
117
|
print("Use FiD generation")
|
|
@@ -119,7 +119,9 @@ class SequentialPipeline(BasicPipeline):
|
|
|
119
119
|
for item in dataset:
|
|
120
120
|
q = item.question
|
|
121
121
|
docs = item.retrieval_result
|
|
122
|
-
input_prompts.append([q + " " + doc for doc in docs])
|
|
122
|
+
input_prompts.append([q + " " + doc['contents'] for doc in docs])
|
|
123
|
+
dataset.update_output("prompt", input_prompts)
|
|
124
|
+
|
|
123
125
|
# delete used refiner to release memory
|
|
124
126
|
if self.refiner:
|
|
125
127
|
del self.refiner
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/retriever.py
RENAMED
|
@@ -7,9 +7,9 @@ from typing import List, Dict
|
|
|
7
7
|
import functools
|
|
8
8
|
from tqdm import tqdm
|
|
9
9
|
import faiss
|
|
10
|
-
|
|
10
|
+
import numpy as np
|
|
11
11
|
from flashrag.utils import get_reranker
|
|
12
|
-
from flashrag.retriever.utils import load_corpus, load_docs
|
|
12
|
+
from flashrag.retriever.utils import load_corpus, load_docs, convert_numpy
|
|
13
13
|
from flashrag.retriever.encoder import Encoder, STEncoder
|
|
14
14
|
|
|
15
15
|
|
|
@@ -136,8 +136,13 @@ class BaseRetriever:
|
|
|
136
136
|
self.cache = json.load(f)
|
|
137
137
|
|
|
138
138
|
def _save_cache(self):
|
|
139
|
+
self.cache = convert_numpy(self.cache)
|
|
140
|
+
def custom_serializer(obj):
|
|
141
|
+
if isinstance(obj, np.float32):
|
|
142
|
+
return float(obj)
|
|
143
|
+
raise TypeError(f"Type {type(obj)} not serializable")
|
|
139
144
|
with open(self.cache_save_path, "w") as f:
|
|
140
|
-
json.dump(self.cache, f, indent=4)
|
|
145
|
+
json.dump(self.cache, f, indent=4, default=custom_serializer)
|
|
141
146
|
|
|
142
147
|
def _search(self, query: str, num: int, return_score: bool) -> List[Dict[str, str]]:
|
|
143
148
|
r"""Retrieve topk relevant documents in corpus.
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/utils.py
RENAMED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import warnings
|
|
3
|
+
from typing import Dict, Any, Union, List, Dict
|
|
4
|
+
import numpy as np
|
|
3
5
|
import datasets
|
|
4
6
|
from transformers import AutoTokenizer, AutoModel, AutoConfig
|
|
5
7
|
|
|
8
|
+
def convert_numpy(obj: Union[Dict, list, np.ndarray, np.generic]) -> Any:
|
|
9
|
+
"""Recursively convert numpy objects in nested dictionaries or lists to native Python types."""
|
|
10
|
+
if isinstance(obj, dict):
|
|
11
|
+
return {k: convert_numpy(v) for k, v in obj.items()}
|
|
12
|
+
elif isinstance(obj, list):
|
|
13
|
+
return [convert_numpy(i) for i in obj]
|
|
14
|
+
elif isinstance(obj, np.ndarray):
|
|
15
|
+
return obj.tolist() # Convert numpy arrays to lists
|
|
16
|
+
elif isinstance(obj, (np.integer, np.floating)):
|
|
17
|
+
return obj.item() # Convert numpy scalars to native Python scalars
|
|
18
|
+
elif isinstance(obj, np.float32):
|
|
19
|
+
return float(obj)
|
|
20
|
+
else:
|
|
21
|
+
return obj # Return the object as-is if it's neither a dict, list, nor numpy type
|
|
22
|
+
|
|
6
23
|
|
|
7
24
|
def load_model(model_path: str, use_fp16: bool = False):
|
|
8
25
|
model_config = AutoConfig.from_pretrained(model_path, trust_remote_code=True)
|
|
@@ -36,7 +36,7 @@ def get_generator(config, **params):
|
|
|
36
36
|
elif config["framework"] == "hf":
|
|
37
37
|
model_config = AutoConfig.from_pretrained(config["generator_model_path"])
|
|
38
38
|
arch = model_config.architectures[0]
|
|
39
|
-
if "t5" in arch.lower() or "bart" in arch.lower():
|
|
39
|
+
if "t5" in arch.lower() or "bart" in arch.lower() or 'fusionindecoder' in arch.lower():
|
|
40
40
|
return getattr(importlib.import_module("flashrag.generator"), "EncoderDecoderGenerator")(config, **params)
|
|
41
41
|
else:
|
|
42
42
|
return getattr(importlib.import_module("flashrag.generator"), "HFCausalLMGenerator")(config, **params)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.3dev20241120"
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120/flashrag_dev.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flashrag-dev
|
|
3
|
-
Version: 0.1.3.
|
|
3
|
+
Version: 0.1.3.dev20241120
|
|
4
4
|
Summary: A library for efficient Retrieval-Augmented Generation research
|
|
5
5
|
Home-page: https://github.com/RUC-NLPIR/FlashRAG
|
|
6
6
|
Author: Jiajie Jin, Yutao Zhu, Chenghao Zhang, Xinyu Yang, Zhicheng Dou
|
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
# Source: FiD official repo: https://github.com/facebookresearch/FiD
|
|
2
|
-
# This software is released under Creative Commons public licenses.
|
|
3
|
-
|
|
4
|
-
import types
|
|
5
|
-
import torch
|
|
6
|
-
import transformers
|
|
7
|
-
import torch.nn.functional as F
|
|
8
|
-
from torch import nn
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class FiDT5(transformers.T5ForConditionalGeneration):
|
|
12
|
-
def __init__(self, config):
|
|
13
|
-
super().__init__(config)
|
|
14
|
-
self.wrap_encoder()
|
|
15
|
-
|
|
16
|
-
def forward_(self, **kwargs):
|
|
17
|
-
if "input_ids" in kwargs:
|
|
18
|
-
kwargs["input_ids"] = kwargs["input_ids"].view(kwargs["input_ids"].size(0), -1)
|
|
19
|
-
if "attention_mask" in kwargs:
|
|
20
|
-
kwargs["attention_mask"] = kwargs["attention_mask"].view(kwargs["attention_mask"].size(0), -1)
|
|
21
|
-
|
|
22
|
-
return super(FiDT5, self).forward(**kwargs)
|
|
23
|
-
|
|
24
|
-
# We need to resize as B x (N * L) instead of (B * N) x L here
|
|
25
|
-
# because the T5 forward method uses the input tensors to infer
|
|
26
|
-
# dimensions used in the decoder.
|
|
27
|
-
# EncoderWrapper resizes the inputs as (B * N) x L.
|
|
28
|
-
def forward(self, input_ids=None, attention_mask=None, **kwargs):
|
|
29
|
-
if input_ids != None:
|
|
30
|
-
# inputs might have already be resized in the generate method
|
|
31
|
-
if input_ids.dim() == 3:
|
|
32
|
-
self.encoder.n_passages = input_ids.size(1)
|
|
33
|
-
input_ids = input_ids.view(input_ids.size(0), -1)
|
|
34
|
-
if attention_mask != None:
|
|
35
|
-
attention_mask = attention_mask.view(attention_mask.size(0), -1)
|
|
36
|
-
return super().forward(input_ids=input_ids, attention_mask=attention_mask, **kwargs)
|
|
37
|
-
|
|
38
|
-
# We need to resize the inputs here, as the generate method expect 2D tensors
|
|
39
|
-
def generate(self, input_ids, attention_mask, max_length):
|
|
40
|
-
self.encoder.n_passages = input_ids.size(1)
|
|
41
|
-
return super().generate(
|
|
42
|
-
input_ids=input_ids.view(input_ids.size(0), -1),
|
|
43
|
-
attention_mask=attention_mask.view(attention_mask.size(0), -1),
|
|
44
|
-
max_length=max_length,
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
def wrap_encoder(self, use_checkpoint=False):
|
|
48
|
-
"""
|
|
49
|
-
Wrap T5 encoder to obtain a Fusion-in-Decoder model.
|
|
50
|
-
"""
|
|
51
|
-
self.encoder = EncoderWrapper(self.encoder, use_checkpoint=use_checkpoint)
|
|
52
|
-
|
|
53
|
-
def unwrap_encoder(self):
|
|
54
|
-
"""
|
|
55
|
-
Unwrap Fusion-in-Decoder encoder, useful to load T5 weights.
|
|
56
|
-
"""
|
|
57
|
-
self.encoder = self.encoder.encoder
|
|
58
|
-
block = []
|
|
59
|
-
for mod in self.encoder.block:
|
|
60
|
-
block.append(mod.module)
|
|
61
|
-
block = nn.ModuleList(block)
|
|
62
|
-
self.encoder.block = block
|
|
63
|
-
|
|
64
|
-
def load_t5(self, state_dict):
|
|
65
|
-
self.unwrap_encoder()
|
|
66
|
-
self.load_state_dict(state_dict)
|
|
67
|
-
self.wrap_encoder()
|
|
68
|
-
|
|
69
|
-
def set_checkpoint(self, use_checkpoint):
|
|
70
|
-
"""
|
|
71
|
-
Enable or disable checkpointing in the encoder.
|
|
72
|
-
See https://pytorch.org/docs/stable/checkpoint.html
|
|
73
|
-
"""
|
|
74
|
-
for mod in self.encoder.encoder.block:
|
|
75
|
-
mod.use_checkpoint = use_checkpoint
|
|
76
|
-
|
|
77
|
-
def reset_score_storage(self):
|
|
78
|
-
"""
|
|
79
|
-
Reset score storage, only used when cross-attention scores are saved
|
|
80
|
-
to train a retriever.
|
|
81
|
-
"""
|
|
82
|
-
for mod in self.decoder.block:
|
|
83
|
-
mod.layer[1].EncDecAttention.score_storage = None
|
|
84
|
-
|
|
85
|
-
def get_crossattention_scores(self, context_mask):
|
|
86
|
-
"""
|
|
87
|
-
Cross-attention scores are aggregated to obtain a single scalar per
|
|
88
|
-
passage. This scalar can be seen as a similarity score between the
|
|
89
|
-
question and the input passage. It is obtained by averaging the
|
|
90
|
-
cross-attention scores obtained on the first decoded token over heads,
|
|
91
|
-
layers, and tokens of the input passage.
|
|
92
|
-
|
|
93
|
-
More details in Distilling Knowledge from Reader to Retriever:
|
|
94
|
-
https://arxiv.org/abs/2012.04584.
|
|
95
|
-
"""
|
|
96
|
-
scores = []
|
|
97
|
-
n_passages = context_mask.size(1)
|
|
98
|
-
for mod in self.decoder.block:
|
|
99
|
-
scores.append(mod.layer[1].EncDecAttention.score_storage)
|
|
100
|
-
scores = torch.cat(scores, dim=2)
|
|
101
|
-
bsz, n_heads, n_layers, _ = scores.size()
|
|
102
|
-
# batch_size, n_head, n_layers, n_passages, text_maxlength
|
|
103
|
-
scores = scores.view(bsz, n_heads, n_layers, n_passages, -1)
|
|
104
|
-
scores = scores.masked_fill(~context_mask[:, None, None], 0.0)
|
|
105
|
-
scores = scores.sum(dim=[1, 2, 4])
|
|
106
|
-
ntokens = context_mask.sum(dim=[2]) * n_layers * n_heads
|
|
107
|
-
scores = scores / ntokens
|
|
108
|
-
return scores
|
|
109
|
-
|
|
110
|
-
def overwrite_forward_crossattention(self):
|
|
111
|
-
"""
|
|
112
|
-
Replace cross-attention forward function, only used to save
|
|
113
|
-
cross-attention scores.
|
|
114
|
-
"""
|
|
115
|
-
for mod in self.decoder.block:
|
|
116
|
-
attn = mod.layer[1].EncDecAttention
|
|
117
|
-
attn.forward = types.MethodType(cross_attention_forward, attn)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class EncoderWrapper(torch.nn.Module):
|
|
121
|
-
"""
|
|
122
|
-
Encoder Wrapper for T5 Wrapper to obtain a Fusion-in-Decoder model.
|
|
123
|
-
"""
|
|
124
|
-
|
|
125
|
-
def __init__(self, encoder, use_checkpoint=False):
|
|
126
|
-
super().__init__()
|
|
127
|
-
|
|
128
|
-
self.encoder = encoder
|
|
129
|
-
apply_checkpoint_wrapper(self.encoder, use_checkpoint)
|
|
130
|
-
|
|
131
|
-
def forward(
|
|
132
|
-
self,
|
|
133
|
-
input_ids=None,
|
|
134
|
-
attention_mask=None,
|
|
135
|
-
**kwargs,
|
|
136
|
-
):
|
|
137
|
-
# total_length = n_passages * passage_length
|
|
138
|
-
bsz, total_length = input_ids.shape
|
|
139
|
-
passage_length = total_length // self.n_passages
|
|
140
|
-
input_ids = input_ids.view(bsz * self.n_passages, passage_length)
|
|
141
|
-
attention_mask = attention_mask.view(bsz * self.n_passages, passage_length)
|
|
142
|
-
outputs = self.encoder(input_ids, attention_mask, **kwargs)
|
|
143
|
-
outputs = (outputs[0].view(bsz, self.n_passages * passage_length, -1),) + outputs[1:]
|
|
144
|
-
return outputs
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
class CheckpointWrapper(torch.nn.Module):
|
|
148
|
-
"""
|
|
149
|
-
Wrapper replacing None outputs by empty tensors, which allows the use of
|
|
150
|
-
checkpointing.
|
|
151
|
-
"""
|
|
152
|
-
|
|
153
|
-
def __init__(self, module, use_checkpoint=False):
|
|
154
|
-
super().__init__()
|
|
155
|
-
self.module = module
|
|
156
|
-
self.use_checkpoint = use_checkpoint
|
|
157
|
-
|
|
158
|
-
def forward(self, hidden_states, attention_mask, position_bias, **kwargs):
|
|
159
|
-
if self.use_checkpoint and self.training:
|
|
160
|
-
kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
|
161
|
-
|
|
162
|
-
def custom_forward(*inputs):
|
|
163
|
-
output = self.module(*inputs, **kwargs)
|
|
164
|
-
empty = torch.tensor([], dtype=torch.float, device=output[0].device, requires_grad=True)
|
|
165
|
-
output = tuple(x if x is not None else empty for x in output)
|
|
166
|
-
return output
|
|
167
|
-
|
|
168
|
-
output = torch.utils.checkpoint.checkpoint(custom_forward, hidden_states, attention_mask, position_bias)
|
|
169
|
-
output = tuple(x if x.size() != 0 else None for x in output)
|
|
170
|
-
else:
|
|
171
|
-
output = self.module(hidden_states, attention_mask, position_bias, **kwargs)
|
|
172
|
-
return output
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def apply_checkpoint_wrapper(t5stack, use_checkpoint):
|
|
176
|
-
"""
|
|
177
|
-
Wrap each block of the encoder to enable checkpointing.
|
|
178
|
-
"""
|
|
179
|
-
block = []
|
|
180
|
-
for mod in t5stack.block:
|
|
181
|
-
wrapped_mod = CheckpointWrapper(mod, use_checkpoint)
|
|
182
|
-
block.append(wrapped_mod)
|
|
183
|
-
block = nn.ModuleList(block)
|
|
184
|
-
t5stack.block = block
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def cross_attention_forward(
|
|
188
|
-
self,
|
|
189
|
-
input,
|
|
190
|
-
mask=None,
|
|
191
|
-
kv=None,
|
|
192
|
-
position_bias=None,
|
|
193
|
-
past_key_value_state=None,
|
|
194
|
-
head_mask=None,
|
|
195
|
-
query_length=None,
|
|
196
|
-
use_cache=False,
|
|
197
|
-
output_attentions=False,
|
|
198
|
-
):
|
|
199
|
-
"""
|
|
200
|
-
This only works for computing cross attention over the input
|
|
201
|
-
"""
|
|
202
|
-
assert kv != None
|
|
203
|
-
assert head_mask == None
|
|
204
|
-
assert position_bias != None or self.has_relative_attention_bias
|
|
205
|
-
|
|
206
|
-
bsz, qlen, dim = input.size()
|
|
207
|
-
n_heads, d_heads = self.n_heads, self.d_kv
|
|
208
|
-
klen = kv.size(1)
|
|
209
|
-
|
|
210
|
-
q = self.q(input).view(bsz, -1, n_heads, d_heads).transpose(1, 2)
|
|
211
|
-
if past_key_value_state == None:
|
|
212
|
-
k = self.k(kv).view(bsz, -1, n_heads, d_heads).transpose(1, 2)
|
|
213
|
-
v = self.v(kv).view(bsz, -1, n_heads, d_heads).transpose(1, 2)
|
|
214
|
-
else:
|
|
215
|
-
k, v = past_key_value_state
|
|
216
|
-
|
|
217
|
-
scores = torch.einsum("bnqd,bnkd->bnqk", q, k)
|
|
218
|
-
|
|
219
|
-
if mask is not None:
|
|
220
|
-
scores += mask
|
|
221
|
-
|
|
222
|
-
if position_bias is None:
|
|
223
|
-
position_bias = self.compute_bias(qlen, klen)
|
|
224
|
-
scores += position_bias
|
|
225
|
-
|
|
226
|
-
if self.score_storage is None:
|
|
227
|
-
self.score_storage = scores
|
|
228
|
-
|
|
229
|
-
attn = F.softmax(scores.float(), dim=-1).type_as(scores)
|
|
230
|
-
attn = F.dropout(attn, p=self.dropout, training=self.training)
|
|
231
|
-
|
|
232
|
-
output = torch.matmul(attn, v)
|
|
233
|
-
output = output.transpose(1, 2).contiguous().view(bsz, -1, self.inner_dim)
|
|
234
|
-
output = self.o(output)
|
|
235
|
-
|
|
236
|
-
if use_cache:
|
|
237
|
-
output = (output,) + ((k, v),)
|
|
238
|
-
else:
|
|
239
|
-
output = (output,) + (None,)
|
|
240
|
-
|
|
241
|
-
if output_attentions:
|
|
242
|
-
output = output + (attn,)
|
|
243
|
-
|
|
244
|
-
if self.has_relative_attention_bias:
|
|
245
|
-
output = output + (position_bias,)
|
|
246
|
-
|
|
247
|
-
return output
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.3dev20241117"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/config/__init__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/config/basic_config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/dataset/__init__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/__init__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/_bleu.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/evaluator.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/metrics.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/evaluator/utils.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/generator/utils.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/judger/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/pipeline/replug_utils.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/prompt/__init__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/prompt/base_prompt.py
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/prompt/trace_examplars.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/__init__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/kg_refiner.py
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/refiner/refiner.py
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/__init__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/__main__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/encoder.py
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/retriever/reranker.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/utils/__init__.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/utils/constants.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag/utils/pred_parse.py
RENAMED
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag_dev.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{flashrag-dev-0.1.3.dev20241117 → flashrag-dev-0.1.3.dev20241120}/flashrag_dev.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|