Text Ranking
sentence-transformers
Safetensors
Transformers
multilingual
t5gemma2
text2text-generation
reranker
encoder-decoder
FBNL
matryoshka
retrieval
RAG
cosyy commited on
Commit
1d71536
·
verified ·
1 Parent(s): 2b55e15

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +182 -0
README.md CHANGED
@@ -157,6 +157,188 @@ On LMEB-Dialogue, a compact embedding model paired with our Nano reranker, which
157
  ![lmeb](./assets/lmeb.jpg)
158
  ![lmeb_emb](./assets/lmeb_emb.jpg)
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  #### Ablation on multi-stage training
161
 
162
  Across all three model sizes and all seven compression ratios, performance on BEIR and MIRACL improves consistently from Stage 1 to Stage 3, demonstrating the effectiveness of our multi-stage training pipeline. Concretely, Stage 1 establishes a robust foundation for document reranking, distillation in Stage 2 substantially improves performance, and Stage 3 yields further modest gains. More importantly, robustness to compression generally improves across the three training stages. For example, from Stage 1 to Stage 3, the performance retention of KaLM-Reranker-V1-Nano at r = 128 relative to r = 2 increases from 92.88% to 93.80% on BEIR and from 90.93% to 92.15% on MIRACL.
 
157
  ![lmeb](./assets/lmeb.jpg)
158
  ![lmeb_emb](./assets/lmeb_emb.jpg)
159
 
160
+ ### Using Sentence Transformers
161
+
162
+ KaLM-Reranker-V1-Large-R2 can be loaded as a modular Sentence Transformers
163
+ `CrossEncoder`. This integration requires `sentence-transformers>=5.6,<6`,
164
+ `transformers>=5.3,<6`, and the PyTorch backend. The repository contains custom
165
+ modeling code, so load only trusted revisions and pass `trust_remote_code=True`.
166
+
167
+ ```bash
168
+ pip install "sentence-transformers>=5.6,<6" "transformers>=5.3,<6"
169
+ ```
170
+
171
+ ```python
172
+ import torch
173
+ from sentence_transformers import CrossEncoder
174
+
175
+ model = CrossEncoder(
176
+ "KaLM-Embedding/KaLM-Reranker-V1-Large-R2",
177
+ trust_remote_code=True,
178
+ device="cuda",
179
+ model_kwargs={"dtype": torch.bfloat16, "chunk_size": 4},
180
+ )
181
+
182
+ query = "What is the capital of China?"
183
+ documents = [
184
+ "The capital of China is Beijing.",
185
+ "Gravity attracts bodies toward one another.",
186
+ ]
187
+ pairs = [(query, document) for document in documents]
188
+
189
+ # The default output is P(yes).
190
+ scores = model.predict(pairs)
191
+ rankings = model.rank(query, documents, return_documents=True)
192
+
193
+ # CrossEncoder prompts are interpreted as KaLM task instructions.
194
+ instruction = "Given a web search query, retrieve passages that answer the query."
195
+ custom_scores = model.predict(pairs, prompt=instruction)
196
+ custom_rankings = model.rank(query, documents, prompt=instruction)
197
+
198
+ # Use Identity to return yes_logit - no_logit instead of P(yes).
199
+ margins = model.predict(pairs, activation_fn=torch.nn.Identity())
200
+
201
+ print(f"scores: {scores}")
202
+ print(f"rankings: {rankings}")
203
+ print(f"custom_scores: {custom_scores}")
204
+ print(f"custom_rankings: {custom_rankings}")
205
+ print(f"margins: {margins}")
206
+
207
+ '''
208
+ scores: [9.8677725e-01 9.0574264e-05]
209
+ rankings: [{'corpus_id': 0, 'score': 0.98677725, 'text': 'The capital of China is Beijing.'}, {'corpus_id': 1, 'score': 9.057426e-05, 'text': 'Gravity attracts bodies toward one another.'}]
210
+ custom_scores: [9.7241479e-01 3.2129523e-05]
211
+ custom_rankings: [{'corpus_id': 0, 'score': 0.9724148}, {'corpus_id': 1, 'score': 3.2129523e-05}]
212
+ margins: [ 4.3125 -9.30925]
213
+ '''
214
+
215
+ ```
216
+
217
+ Inputs must be ordered as `(query, document)`. By default, queries are
218
+ truncated to 512 tokens and documents to 1024 tokens. `chunk_size=4` performs a
219
+ mask-aware mean over each consecutive group of four encoder token states before
220
+ passing the compressed encoder output to the decoder. Set `chunk_size=None` to
221
+ disable compression, or change `model[0].chunk_size` after loading.
222
+
223
+ For CPU inference, use `device="cpu"` and
224
+ `model_kwargs={"dtype": torch.float32, "chunk_size": 4}`. Only the PyTorch
225
+ inference backend is currently supported; training, ONNX, and OpenVINO are not
226
+ included in this release.
227
+
228
+
229
+ ### Using transformers
230
+ ```python
231
+ import argparse
232
+ from typing import Optional
233
+
234
+
235
+ def optional_positive_int(value: str) -> Optional[int]:
236
+ if value.lower() == "none":
237
+ return None
238
+ try:
239
+ parsed = int(value)
240
+ except ValueError as error:
241
+ raise argparse.ArgumentTypeError(
242
+ "must be a positive integer or 'none'"
243
+ ) from error
244
+ if parsed <= 0:
245
+ raise argparse.ArgumentTypeError("must be a positive integer or 'none'")
246
+ return parsed
247
+
248
+
249
+ def build_parser() -> argparse.ArgumentParser:
250
+ parser = argparse.ArgumentParser(
251
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
252
+ )
253
+ parser.add_argument(
254
+ "--model",
255
+ default="KaLM-Embedding/KaLM-Reranker-V1-Large-R2",
256
+ help="Hugging Face model ID or local checkpoint path.",
257
+ )
258
+ parser.add_argument(
259
+ "--device",
260
+ default=None,
261
+ help="Inference device, such as 'cuda', 'cuda:0', or 'cpu'.",
262
+ )
263
+ parser.add_argument(
264
+ "--dtype",
265
+ default=None,
266
+ choices=("bfloat16", "bf16", "float16", "fp16", "float32", "fp32"),
267
+ help="Model parameter dtype. By default, use BF16 on CUDA and FP32 on CPU.",
268
+ )
269
+ parser.add_argument(
270
+ "--batch-size",
271
+ type=int,
272
+ default=32,
273
+ help="Number of query-document pairs scored per inference batch.",
274
+ )
275
+ parser.add_argument(
276
+ "--query-max-length",
277
+ type=int,
278
+ default=512,
279
+ help=(
280
+ "Maximum tokens in the raw query before it is inserted into the "
281
+ "decoder prompt; prompt tokens are not included in this limit."
282
+ ),
283
+ )
284
+ parser.add_argument(
285
+ "--reranker-max-length",
286
+ type=int,
287
+ default=1024,
288
+ help=(
289
+ "Maximum encoder tokens for '<Document>: {passage}'. This is not a "
290
+ "combined query-document context limit."
291
+ ),
292
+ )
293
+ parser.add_argument(
294
+ "--chunk-size",
295
+ type=optional_positive_int,
296
+ default=4,
297
+ metavar="N|none",
298
+ help=(
299
+ "Number of encoder token hidden states per mean-pooled chunk; use "
300
+ "'none' to disable encoder chunk pooling."
301
+ ),
302
+ )
303
+ return parser
304
+
305
+
306
+ def main() -> None:
307
+ args = build_parser().parse_args()
308
+
309
+ from kalm_reranker import KaLMReranker
310
+
311
+ reranker = KaLMReranker(
312
+ args.model,
313
+ device=args.device,
314
+ dtype=args.dtype,
315
+ batch_size=args.batch_size,
316
+ query_max_length=args.query_max_length,
317
+ max_length=args.reranker_max_length,
318
+ chunk_size=args.chunk_size,
319
+ )
320
+ query = "What is the capital of China?"
321
+ documents = [
322
+ "The capital of China is Beijing.",
323
+ "Gravity attracts bodies toward one another.",
324
+ ]
325
+ instruction = "Given a query, retrieve documents that answer the query."
326
+
327
+ pairs = [(query, document) for document in documents]
328
+ print("scores:", reranker.predict(pairs, instruction=instruction))
329
+ print("rankings:", reranker.rank(query, documents, instruction=instruction))
330
+
331
+
332
+ if __name__ == "__main__":
333
+ main()
334
+
335
+ '''
336
+ scores: [0.9867772459983826, 9.0574256319087e-05]
337
+ rankings: [{'corpus_id': 0, 'score': 0.9867772459983826}, {'corpus_id': 1, 'score': 9.0574256319087e-05}]
338
+ '''
339
+
340
+ ```
341
+
342
  #### Ablation on multi-stage training
343
 
344
  Across all three model sizes and all seven compression ratios, performance on BEIR and MIRACL improves consistently from Stage 1 to Stage 3, demonstrating the effectiveness of our multi-stage training pipeline. Concretely, Stage 1 establishes a robust foundation for document reranking, distillation in Stage 2 substantially improves performance, and Stage 3 yields further modest gains. More importantly, robustness to compression generally improves across the three training stages. For example, from Stage 1 to Stage 3, the performance retention of KaLM-Reranker-V1-Nano at r = 128 relative to r = 2 increases from 92.88% to 93.80% on BEIR and from 90.93% to 92.15% on MIRACL.