Views
No views yet
promptriever-llama3.1-8b-v1 was instruction-trained on a corpus of 490k MSMarco samples with instructions and 490k without instructions. See the paper for more details.| Binary | Description |
|---|---|
| samaya-ai/promptriever-llama2-7b-v1 | A Promptriever bi-encoder model based on LLaMA 2 (7B parameters). |
| samaya-ai/promptriever-llama3.1-8b-instruct-v1 | A Promptriever bi-encoder model based on LLaMA 3.1 Instruct (8B parameters). |
| samaya-ai/promptriever-llama3.1-8b-v1 | A Promptriever bi-encoder model based on LLaMA 3.1 (8B parameters). |
| samaya-ai/promptriever-mistral-v0.1-7b-v1 | A Promptriever bi-encoder model based on Mistral v0.1 (7B parameters). |
| samaya-ai/RepLLaMA-reproduced | A reproduction of the RepLLaMA model (no instructions). A bi-encoder based on LLaMA 2, trained on the tevatron/msmarco-passage-aug dataset. |
| samaya-ai/msmarco-w-instructions | A dataset of MS MARCO with added instructions and instruction-negatives, used for training the above models. |
1import mteb
2model = mteb.get_model("samaya-ai/promptriever-llama3.1-8b-v1")
3tasks = mteb.get_tasks(tasks=["NFCorpus"], languages=["eng"])
4evaluation = mteb.MTEB(tasks=tasks)
5evaluation.run(model, batch_size=16)1import torch
2import torch.nn.functional as F
3from transformers import AutoTokenizer, AutoModel
4from peft import PeftModel, PeftConfig
5import numpy as np
6
7class Promptriever:
8 def __init__(self, model_name_or_path):
9 self.model, self.tokenizer = self.get_model(model_name_or_path)
10 self.model.eval().cuda()
11
12 def get_model(self, peft_model_name):
13 # Load the PEFT configuration to get the base model name
14 peft_config = PeftConfig.from_pretrained(peft_model_name)
15 base_model_name = peft_config.base_model_name_or_path
16
17 # Load the base model and tokenizer
18 base_model = AutoModel.from_pretrained(base_model_name)
19 tokenizer = AutoTokenizer.from_pretrained(base_model_name)
20 tokenizer.pad_token = tokenizer.eos_token
21 tokenizer.pad_token_id = tokenizer.eos_token_id
22 tokenizer.padding_side = "right"
23
24 # Load and merge the PEFT model
25 model = PeftModel.from_pretrained(base_model, peft_model_name)
26 model = model.merge_and_unload()
27
28 # can be much longer, but for the example 512 is enough
29 model.config.max_length = 512
30 tokenizer.model_max_length = 512
31
32 return model, tokenizer
33
34 def create_batch_dict(self, tokenizer, input_texts):
35 max_length = self.model.config.max_length
36 batch_dict = tokenizer(
37 input_texts,
38 max_length=max_length - 1,
39 return_token_type_ids=False,
40 return_attention_mask=False,
41 padding=False,
42 truncation=True,
43 )
44 batch_dict["input_ids"] = [
45 input_ids + [tokenizer.eos_token_id]
46 for input_ids in batch_dict["input_ids"]
47 ]
48 return tokenizer.pad(
49 batch_dict,
50 padding=True,
51 pad_to_multiple_of=8,
52 return_attention_mask=True,
53 return_tensors="pt",
54 )
55
56 def encode(self, sentences, max_length: int = 2048, batch_size: int = 4):
57 all_embeddings = []
58 for i in range(0, len(sentences), batch_size):
59 batch_texts = sentences[i : i + batch_size]
60
61 batch_dict = self.create_batch_dict(self.tokenizer, batch_texts)
62 batch_dict = {
63 key: value.to(self.model.device) for key, value in batch_dict.items()
64 }
65
66 with torch.cuda.amp.autocast():
67 with torch.no_grad():
68 outputs = self.model(**batch_dict)
69 last_hidden_state = outputs.last_hidden_state
70 sequence_lengths = batch_dict["attention_mask"].sum(dim=1) - 1
71 batch_size = last_hidden_state.shape[0]
72 reps = last_hidden_state[
73 torch.arange(batch_size, device=last_hidden_state.device),
74 sequence_lengths,
75 ]
76 embeddings = F.normalize(reps, p=2, dim=-1)
77 all_embeddings.append(embeddings.cpu().numpy())
78
79 return np.concatenate(all_embeddings, axis=0)
80
81# Initialize the model
82model = Promptriever("samaya-ai/promptriever-llama2-7b-v1")
83
84# Example query and instruction
85query = "What universities are in Baltimore, Maryland?"
86
87# add specific relevance conditions if desired (and/or/not) and any other prompts
88instruction = "A relevant document would describe any university in Baltimore. I am not interested in any university that was the first American university. Think carefully about these conditions when determining relevance."
89
90# Combine query and instruction with **two spaces** after "query: "
91input_text = f"query: {query.strip()} {instruction.strip()}".strip()
92
93# Example documents
94# NOTE: double space after `passage:`
95doc1 = "passage: Johns Hopkins University (often abbreviated as Johns Hopkins, Hopkins, or JHU) is a private research university in Baltimore, Maryland. Founded in 1876, Johns Hopkins was the first American university based on the European research institution model."
96doc2 = "passage: Johns Hopkins University (often abbreviated as Johns Hopkins, Hopkins, or JHU) is a private research university in Baltimore, Maryland. Founded in 1876, Johns Hopkins was the second American university based on the European research institution model."
97
98# Encode query and documents
99query_embedding = model.encode([input_text])
100doc_embeddings = model.encode([doc1, doc2])
101
102# Calculate similarities
103similarities = np.dot(query_embedding, doc_embeddings.T)[0]
104print(f"Similarities: {similarities}") # Similarities: [0.53341305 0.53451955]
105assert similarities[1] > similarities[0]
106
107
108# change up the instruction to the opposite, to see it works
109instruction = "A relevant document would describe any university in Baltimore. I am interested in any university that was the first American university. Think carefully about these conditions when determining relevance."
110input_text = f"query: {query.strip()} {instruction.strip()}".strip()
111query_embedding = model.encode([input_text])
112similarities = np.dot(query_embedding, doc_embeddings.T)[0]
113print(f"Similarities: {similarities}") # Similarities: [0.60182875 0.5874183 ]
114assert similarities[0] > similarities[1]1#!/bin/bash
2deepspeed --include localhost:$3 --master_port "6000$4" --module tevatron.retriever.driver.train \
3 --deepspeed deepspeed/ds_zero3_config.json \
4 --output_dir retriever-llama3-$1 \
5 --model_name_or_path meta-llama/Meta-Llama-3.1-8B \
6 --lora \
7 --lora_r 32 \
8 --lora_target_modules q_proj,k_proj,v_proj,o_proj,down_proj,up_proj,gate_proj \
9 --save_steps 500 \
10 --dataset_name $2 \
11 --query_prefix "query: " \
12 --passage_prefix "passage: " \
13 --bf16 \
14 --pooling eos \
15 --append_eos_token \
16 --normalize \
17 --temperature 0.01 \
18 --per_device_train_batch_size 8 \
19 --gradient_checkpointing \
20 --train_group_size 16 \
21 --learning_rate 1e-4 \
22 --query_max_len 304 \
23 --passage_max_len 196 \
24 --num_train_epochs 1 \
25 --logging_steps 10 \
26 --overwrite_output_dir \
27 --warmup_steps 100 \
28 --gradient_accumulation_steps 4 \
29 --negatives_first_n 3 1@article{weller2024promptriever,
2 title={Promptriever: Instruction-Trained Retrievers Can Be Prompted Like Language Models},
3 author={Orion Weller and Benjamin Van Durme and Dawn Lawrie and Ashwin Paranjape and Yuhao Zhang and Jack Hessel},
4 year={2024},
5 eprint={2409.11136},
6 archivePrefix={arXiv},
7 primaryClass={cs.IR},
8 url={https://arxiv.org/abs/2409.11136},
9}