--- license: apache-2.0 language: - en - ar tags: - retrieval - search - sparse-encoder - splade - bge-m3 - lora library_name: peft --- # Search Stack — query towers The **query-side** encoders for a two-stage product search over a multilingual (EN + AR) fashion catalogue. These are the exact weights that produced the vectors in the Qdrant collection they are used against — a cosine ANN is only meaningful if query and documents share an encoder, so these are part of the retrieval contract, not an interchangeable dependency. | path | size | what it is | |---|---|---| | `adapter/` | 4.7 MB | LoRA (r=8, q/k/v) on `BAAI/bge-m3` — the dense query tower | | `tokenizer/` | 17 MB | matching bge-m3 tokenizer | | `splade_v6_v2/` | 545 MB | fine-tuned SPLADE sparse encoder (distilbert-base-multilingual-cased) | The `BAAI/bge-m3` backbone is not included — it is unmodified upstream and `transformers` fetches it on first run. ## Use ```python from huggingface_hub import snapshot_download snapshot_download("rdxtremity/jev-reranking", allow_patterns=["adapter/*", "tokenizer/*", "splade_v6_v2/*"], local_dir="models") ``` Dense query encoding is CLS-pool + L2-normalise, max 64 tokens, producing a 1024-d unit vector: ```python from transformers import AutoModel, AutoTokenizer from peft import PeftModel import torch tok = AutoTokenizer.from_pretrained("models/tokenizer") model = PeftModel.from_pretrained(AutoModel.from_pretrained("BAAI/bge-m3"), "models/adapter").eval() enc = tok(["red dress"], return_tensors="pt", truncation=True, max_length=64) with torch.no_grad(): out = model(**enc) vec = torch.nn.functional.normalize(out.last_hidden_state[:, 0], p=2, dim=-1) ``` Sparse encoding uses `sentence_transformers.SparseEncoder` on `splade_v6_v2/`, with `max_seq_length = 128`. Only one short forward pass runs at query time, so CPU is sufficient.