在电商搜索和AI助手场景中,如何准确理解用户查询意图并返回最相关的商品结果是一个核心挑战。传统搜索引擎通常采用多阶段处理流程:召回(retrieval)→重排序(reranking)→后处理(post-processing)。其中,重排序环节对最终结果质量影响最大,因为它决定了用户实际看到的商品排序。
我们开发的RexRerankers系列模型专门针对现代电商搜索场景优化,通过创新的训练方法和数据架构,在商品相关性评估任务上达到了业界领先水平。本文将深入解析这套方案的技术细节、实现原理和实际应用。
提示:本文涉及的所有模型和数据集均已开源,读者可以直接在Hugging Face上获取并使用。
与通用网页搜索相比,电商搜索面临几个独特挑战:
商品属性复杂性:一个"iPhone 15 Pro Max 256GB 深空黑"的查询,需要精确匹配型号、容量、颜色等多个属性维度。即使文本匹配度高,如果关键属性不符(如只有128GB版本),仍然是不相关结果。
查询意图多样性:
语言表达噪声:
传统重排序方法主要存在三个问题:
标注噪声处理不足:同一商品在不同上下文可能获得不同相关性评分,现有模型通常将标注视为绝对真理,导致过拟合。
意图覆盖不完整:公开数据集(如Amazon-ESCI)主要覆盖传统搜索查询,缺乏现代AI助手常见的长尾、多属性查询。
效率与效果难以兼顾:生成式模型效果虽好但推理成本高,小型分类模型效率高但效果欠佳。
我们从UC San Diego发布的Amazon 2023商品评论快照出发,构建了包含3700万商品的标准化目录:
去重处理:
模式统一:
python复制class ProductSchema:
title: str # 商品标题
brand: str # 品牌
category: str # 类目路径
features: List[str] # 关键属性
description: str # 详细描述
为覆盖多样化的购物意图,我们使用GPT-OSS-20B生成合成查询,并分为6大类:
通过embedding-gemma-300M模型对生成的110万查询进行语义聚类,确保最终数据集覆盖广泛而不冗余。
采用LLM委员会投票机制进行高质量标注:
召回阶段:对每个查询,从两个索引中各取top-128候选商品
标注阶段:使用三个LLM模型并行标注
python复制council = [
GPT-OSS-120B,
Qwen3-32B,
Olmo-3.1-32B
]
标注后处理:
最终得到的Amazebay-Relevance数据集包含:
阶段一:分布训练(处理标注噪声)
传统方法直接将相关性分数作为回归目标,忽略了标注本身的不确定性。我们创新性地将单点标签转换为概率分布:
math复制y_i \propto \exp\Big(-\frac{(c_i - s)^2}{2\sigma^2}\Big)
阶段二:标量对齐(适配生产环境)
注意:这种两阶段设计既保留了分布学习对噪声的鲁棒性,又能输出生产系统需要的单一分数。
我们基于RexBERT预训练模型,提供四个规格:
| 模型规格 | 参数量 | 适用场景 |
|---|---|---|
| micro | 16.8M | 移动端/边缘设备 |
| mini | 68M | 中小规模部署 |
| base | 149M | 标准服务器 |
| large | 400M | 高精度场景 |
基于Qwen3-Reranker-0.6B架构,我们设计了生成式版本:
输入格式:
code复制<Instruct>: 判断商品是否符合查询需求
<Query>: 送女友的生日礼物
<Document>: 施华洛世奇 天鹅项链 情人节礼物
评分机制:
量化版本:
传统电商评估集存在三个主要局限:
ERESS评估套件包含:
| 模型 | 参数量 | nDCG@5 | nDCG@10 |
|---|---|---|---|
| RexReranker-0.6B | 0.6B | 0.9794 | 0.9722 |
| Qwen3-Reranker-8B | 8.0B | 0.9158 | 0.9034 |
| jina-reranker-v3 | 0.6B | 0.8377 | 0.7952 |
我们的0.6B小模型超越8B大模型,证明了训练方法的有效性。
在ERESS上的nDCG@5:
模型效果随规模稳定提升,表明架构具有良好的扩展性。
使用Hugging Face Transformers库:
python复制from transformers import AutoModelForSequenceClassification, AutoTokenizer
import torch
model_id = "thebajajra/RexReranker-base"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSequenceClassification.from_pretrained(model_id).eval()
query = "男士商务皮鞋 防滑"
title = "金利来男士皮鞋 商务正装鞋"
description = "经典商务款式,防滑橡胶底,头层牛皮"
inputs = tokenizer(
f"Query: {query}",
f"Title: {title}\nDescription: {description}",
return_tensors="pt",
truncation=True,
max_length=512
)
with torch.no_grad():
outputs = model(**inputs)
score = outputs.logits.squeeze(-1).item()
print(f"相关性分数: {score:.4f}")
使用vLLM进行高效推理:
python复制from vllm import LLM, SamplingParams
model = LLM(
model="thebajajra/RexReranker-0.6B",
tensor_parallel_size=2,
quantization="fp8"
)
sampling_params = SamplingParams(
temperature=0,
max_tokens=1,
logprobs=2,
allowed_tokens=["yes", "no"]
)
def score_query_product(query, product):
prompt = f"""<Instruct>: 判断商品是否符合查询需求
<Query>: {query}
<Document>: {product}"""
outputs = model.generate([prompt], sampling_params)
logprobs = outputs[0].outputs[0].logprobs[0]
yes_prob = math.exp(logprobs["yes"])
no_prob = math.exp(logprobs["no"])
return yes_prob / (yes_prob + no_prob)
混合部署策略:
缓存优化:
python复制from functools import lru_cache
@lru_cache(maxsize=10000)
def cached_scoring(query, product):
return score_query_product(query, product)
量化部署:
异步处理:
python复制from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as executor:
futures = [executor.submit(score_query_product, q, p)
for q, p in query_product_pairs]
scores = [f.result() for f in futures]
RexRerankers支持最大8192token的输入,但建议通过以下方式优化:
关键信息提取:
python复制def preprocess_text(text):
# 保留标题、品牌、关键属性
important_parts = []
if "Title:" in text:
important_parts.append(text.split("Title:")[1].split("\n")[0])
if "Brand:" in text:
important_parts.append(text.split("Brand:")[1].split("\n")[0])
return " ".join(important_parts)
分段处理:
python复制def chunk_text(text, chunk_size=512):
words = text.split()
return [" ".join(words[i:i+chunk_size])
for i in range(0, len(words), chunk_size)]
对于新上架商品,建议:
模型支持增量训练以适应数据分布变化:
python复制from transformers import Trainer, TrainingArguments
training_args = TrainingArguments(
output_dir="./retrain",
per_device_train_batch_size=8,
num_train_epochs=1,
save_steps=1000
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=new_data
)
trainer.train()
RexRerankers已在Hugging Face开源,包括预训练模型、训练代码和评估工具。无论是构建电商搜索系统,还是改进AI助手的产品推荐能力,这套方案都能提供强大的基线支持。