Views
No views yet
⚠️ See Disclaimer below before using.
(query, passage) pair, it outputs a single relevance score for that pair.1import getpass
2import teradataml as tdml
3from huggingface_hub import hf_hub_download
4
5repo_id = "martinhillebrandtd/mxbai-rerank-xsmall-v1"
6model_id = "mxbai-rerank-xsmall-v1"
7
8# 1. Download artifacts from this repo
9hf_hub_download(repo_id=repo_id, filename="onnx/model.onnx", local_dir="./")
10hf_hub_download(repo_id=repo_id, filename="tokenizer.json", local_dir="./")
11
12# 2. Connect to Teradata
13tdml.create_context(host=input("host: "), username=input("user: "), password=getpass.getpass("password: "))
14
15# 3. Load model + tokenizer into BYOM tables
16tdml.save_byom(model_id=model_id, model_file="onnx/model.onnx", table_name="reranker_models")
17tdml.save_byom(model_id=model_id, model_file="tokenizer.json", table_name="reranker_tokenizers")
18
19# 4. Score an existing chunks table against one fixed query.
20# DeBERTa's own pair-separator is [SEP] (see "How it works" below for why concatenation
21# is a valid substitute for real pair-encoding, for this specific model).
22chunks_table = "your_chunks_table" # columns: chunk_id, chunk_txt
23QUERY = "What is the best-known landmark in Paris?"
24
25query = f"""
26SELECT chunk_id, chunk_txt, emb_0 AS relevance_score
27FROM mldb.ONNXEmbeddings(
28 ON (SELECT chunk_id, chunk_txt, '{QUERY}' || '[SEP]' || chunk_txt AS txt
29 FROM {chunks_table}) AS InputTable
30 ON (SELECT * FROM reranker_models WHERE model_id = '{model_id}') AS ModelTable DIMENSION
31 ON (SELECT model AS tokenizer FROM reranker_tokenizers WHERE model_id = '{model_id}') AS TokenizerTable DIMENSION
32 USING
33 Accumulate('chunk_id', 'chunk_txt')
34 ModelOutputTensor('sentence_embedding')
35 OutputFormat('FLOAT32(1)')
36 OverwriteCachedModel('true')
37) a
38"""
39result = tdml.DataFrame.from_query(query).to_pandas().sort_values("relevance_score", ascending=False)relevance_score is the model's raw logit -- sorting by it directly already gives the correct
ranking, since sigmoid is monotonic. If you need an actual [0, 1] probability rather than
just a ranking, compute it in SQL instead of Python: 1 / (1 + EXP(-emb_0)).VectorDistance to get a shortlist of candidates by cosine distance, and rerank only that
shortlist with this model.1-- Stage 1: shortlist the 20 nearest chunks to the query embedding
2CREATE VOLATILE TABLE shortlist AS (
3 SELECT ref_id AS chunk_id, distance
4 FROM TD_VECTORDISTANCE(
5 ON query_embedding AS TargetTable
6 ON chunk_embeddings AS ReferenceTable DIMENSION
7 USING
8 TargetIDColumn('query_id')
9 TargetFeatureColumns('[emb_0:emb_383]')
10 RefIDColumn('chunk_id')
11 RefFeatureColumns('[emb_0:emb_383]')
12 DistanceMeasure('cosine')
13 TopK(20)
14 ) AS dt
15) WITH DATA ON COMMIT PRESERVE ROWS;
16
17-- Stage 2: rerank only those 20 shortlisted chunks (see Quickstart above, with
18-- your_chunks_table replaced by a join against `shortlist`)ONNXEmbeddings is built to map one text column to a fixed-size float vector -- it has no
native concept of a (query, passage) pair, and doesn't care that its output is semantically an
"embedding": any graph with the right tensor names/shapes runs. This repo reuses it as a generic
text-to-number function instead: query and passage are concatenated into a single string before
tokenization, and the model's one classification logit comes back through the (1-value)
sentence_embedding output.type_vocab_size=0 -- its exported
graph never uses token_type_ids to mark the query/passage boundary -- confirmed by testing the
concatenated score against the model's true pair-encoded score
(AutoModelForSequenceClassification, real two-argument tokenizer call), both locally and
against a live Vantage instance:| mean |delta| | max |delta| | |
|---|---|---|
| Local ONNX (concat) vs. true PyTorch (pair) | 7.2e-8 | 3.9e-7 |
Live Teradata ONNXEmbeddings vs. true PyTorch (pair) | 9.5e-8 | 5.2e-7 |
token_type_ids as an input -- if it does, this concat
trick is not valid for that model.mixedbread-ai/mxbai-rerank-xsmall-v1 already ships a ready-made ONNX export
(onnx/model.onnx, fp32, opset 12) -- no re-export via optimum was needed. The only change
required was renaming the graph's native output tensor (logits) to sentence_embedding, since
ONNXEmbeddings's model_output_tensor argument only accepts the literal values
sentence_embedding or token_embeddings. See convert.py for the conversion
steps, and test_local.py for the ONNX-vs-PyTorch parity check above.