Integrate with Sentence Transformers

#1
by tomaarsen HF Staff - opened

Hello!

Preface

This is the same integration as proposed for LightOn-rerank-PW-0.8B, applied to PW-4B. All explanations there (module pipeline, chat template handling, system prompt overriding, dtype behaviour) apply verbatim, so this description only lists the differences.

Heads up, this PR was AI-generated and human-reviewed.

Pull Request overview

  • Integrate this model with Sentence Transformers (v5.4.0+) as a CrossEncoder

Details

The PW siblings share the same tokenizer, chat template, and Yes/No scoring format, so the five added integration files (modules.json, sentence_bert_config.json, config_sentence_transformers.json, 1_LogitScore/config.json, additional_chat_templates/reranker.jinja) are byte-identical to the ones in the 0.8B PR. No weights were changed. The differences with that PR:

  • Qwen3.5-4B enables thinking by default in its chat template (the 0.8B and 2B backbones default to non-thinking). This changes nothing in the integration files: the bundled reranker chat template already hardcodes the non-thinking generation prompt, so CrossEncoder users get correctly positioned Yes/No logits without ever passing enable_thinking=False. The "Thinking must be disabled" note in the README now mentions this.
  • README.md: the same sentence-transformers tag and "Using Sentence Transformers" section, but with this model's expected outputs, plus an expected-output comment (# [-3.0, -8.0625]) in the existing transformers snippet.
  • Verification was re-run against this checkpoint's own plain-transformers baseline (with enable_thinking=False) in fp32 (text-only, image-only, and mixed text+image batches): max |diff| is about 4e-5, on the released sentence-transformers 5.4.0 and 5.6.0 with transformers 5.4.0 and 5.13.1.
from sentence_transformers import CrossEncoder

model = CrossEncoder("lightonai/LightOn-rerank-PW-4B")

query = "What is late interaction in neural information retrieval?"
documents = [
    "ColBERT computes token-level query-document interactions at search time...",
    "The Eiffel Tower is located on the Champ de Mars in Paris.",
]

pairs = [(query, doc) for doc in documents]
scores = model.predict(pairs)
print(scores)
# [-3.     -8.0625]

rankings = model.rank(query, documents)
print(rankings)
# [{'corpus_id': 0, 'score': -3.0}, {'corpus_id': 1, 'score': -8.0625}]

As before, page images can be passed directly as documents (PIL.Image, URL, or file path), text and image candidates can be mixed in one predict call, and none of the existing transformers/vLLM usage is affected.

Happy to tweak anything you'd like changed. Please let me know if you have any questions or feedback!

  • Tom Aarsen
tomaarsen changed pull request status to open
NohTow changed pull request status to merged

Sign up or log in to comment