|
from datasets import load_dataset |
|
from sentence_transformers import ( |
|
SparseEncoder, |
|
SparseEncoderTrainer, |
|
SparseEncoderTrainingArguments, |
|
SparseEncoderModelCardData, |
|
) |
|
from sentence_transformers.sparse_encoder.losses import SpladeLoss, SparseMultipleNegativesRankingLoss |
|
from sentence_transformers.training_args import BatchSamplers |
|
from sentence_transformers.sparse_encoder.evaluation import SparseNanoBEIREvaluator |
|
from sentence_transformers.sparse_encoder.models import SpladePooling, MLMTransformer, IDF |
|
from sentence_transformers.models import Asym |
|
|
|
import logging |
|
|
|
logging.basicConfig(format="%(asctime)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.INFO) |
|
|
|
|
|
mlm_transformer = MLMTransformer("prajjwal1/bert-tiny", tokenizer_args={"model_max_length": 512}) |
|
splade_pooling = SpladePooling(pooling_strategy="max", word_embedding_dimension=mlm_transformer.get_sentence_embedding_dimension()) |
|
|
|
asym = Asym({ |
|
"query": [IDF(tokenizer=mlm_transformer.tokenizer, frozen=False)], |
|
"document": [mlm_transformer, splade_pooling], |
|
}) |
|
|
|
model = SparseEncoder( |
|
modules=[asym], |
|
model_card_data=SparseEncoderModelCardData( |
|
language="en", |
|
license="apache-2.0", |
|
model_name="Inference-free SPLADE BERT-tiny trained on Natural-Questions tuples", |
|
) |
|
) |
|
|
|
|
|
full_dataset = load_dataset("sentence-transformers/natural-questions", split="train").select(range(100_000)) |
|
|
|
dataset_dict = full_dataset.train_test_split(test_size=1_000, seed=12) |
|
train_dataset = dataset_dict["train"] |
|
eval_dataset = dataset_dict["test"] |
|
print(train_dataset) |
|
print(train_dataset[0]) |
|
|
|
|
|
loss = SpladeLoss( |
|
model=model, |
|
loss=SparseMultipleNegativesRankingLoss(model=model), |
|
lambda_query=0, |
|
lambda_corpus=3e-2, |
|
) |
|
|
|
|
|
run_name = "inference-free-splade-bert-tiny-nq-fresh-3e-2-lambda-corpus-1e-3-idf-lr-2e-5-lr" |
|
args = SparseEncoderTrainingArguments( |
|
|
|
output_dir=f"models/{run_name}", |
|
|
|
num_train_epochs=1, |
|
per_device_train_batch_size=64, |
|
per_device_eval_batch_size=64, |
|
learning_rate=2e-5, |
|
learning_rate_mapping={"IDF\.weight": 1e-3}, |
|
warmup_ratio=0.1, |
|
fp16=True, |
|
bf16=False, |
|
batch_sampler=BatchSamplers.NO_DUPLICATES, |
|
router_mapping=["query", "document"], |
|
|
|
eval_strategy="steps", |
|
eval_steps=200, |
|
save_strategy="steps", |
|
save_steps=200, |
|
save_total_limit=2, |
|
logging_steps=20, |
|
run_name=run_name, |
|
) |
|
|
|
|
|
dev_evaluator = SparseNanoBEIREvaluator(dataset_names=["msmarco", "nfcorpus", "nq"], batch_size=128) |
|
|
|
|
|
trainer = SparseEncoderTrainer( |
|
model=model, |
|
args=args, |
|
train_dataset=train_dataset, |
|
eval_dataset=eval_dataset, |
|
loss=loss, |
|
evaluator=dev_evaluator, |
|
) |
|
trainer.train() |
|
|
|
|
|
dev_evaluator(model) |
|
|
|
|
|
model.save_pretrained(f"models/{run_name}/final") |
|
|
|
|
|
model.push_to_hub(run_name) |