电商搜索推荐(如亚马逊的A9、COSMO) 和**视频推流(如ABR)**这两个方向,拆解它们的底层数学或逻辑实现。
一、电商搜索排序:A9 算法的技术骨架
A9 的本质是一个线性可加的打分模型,每个商品按如下公式计算总分:
Score=∑iwi⋅fi(商品,查询,用户)Score=i∑wi⋅fi(商品,查询,用户)
其中 fifi 是特征函数,wiwi 是权重(通过机器学习从点击、购买日志中训练得到)。
关键特征组(技术细节)
| 特征类型 | 具体例子 | 计算方式 |
|---|---|---|
| 文本相关性 | 查询词与标题、描述、卖点的匹配度 | TF-IDF 或 BM25,现在已升级为 BERT 双塔模型 |
| 行为反馈 | 历史点击率、加购率、购买率 | 按时间衰减加权 (e.g., e−λΔte−λΔt) |
| 商品质量 | 图片质量分、退货率、好评率 | 基于统计分布的标准分 (z-score) |
| 流行度 | 近24小时销量 | 对数平滑 log(1+sales)log(1+sales) |
| 个性化 | 用户历史类目偏好 | 协同过滤 + 双塔向量召回 |
A9 不是单一算法,而是一个排序漏斗:
-
召回 (布尔匹配 + 向量相似度) → 几百个候选
-
粗排 (轻量级LR模型) → 几十个候选
-
精排 (GBDT + DNN) → 最终排序
二、COSMO 的多模态理解(如何"看懂"主图)
COSMO 的核心技术是多模态Transformer,同时处理文本和图像。
输入表示
-
文本:标题、描述 → 通过 BERT 编码为向量 T∈R768T∈R768
-
图像:主图 → 通过 Vision Transformer (ViT) 切分为16×16的patch,编码为向量 I∈R768I∈R768
跨模态融合
使用 Cross-Attention 机制:
Attention(Q,K,V)=softmax(QKTdk)VAttention(Q,K,V)=softmax(dkQKT)V
其中 QQ 来自文本特征,K,VK,V 来自图像特征。这样模型能学到"户外草地 + 便携音响 → 露营场景"这类关联。
训练目标
-
对比学习:让匹配的(图,文)向量距离近,不匹配的远(InfoNCE loss)
-
掩码建模:随机遮盖图像的一块,让模型从剩余部分预测(类似BERT的MLM)
最终,COSMO 输出一个场景向量(例如露营、居家、办公),作为召回或排序的特征。
三、ABR (自适应比特率) 的技术实现细节
以亚马逊的 SODA 算法为例,它解决的核心问题是:未来 N 个视频块应该选什么码率?
传统 ABR 的局限性
大多数 ABR 算法(如 BOLA)只看当前吞吐量 和缓冲区,容易频繁切换画质。
SODA 的"码率地平线规划"
SODA 维护一个未来 K 块的码率序列 R1,R2,...,RKR1,R2,...,RK,目标函数为:
max∑t=1KQ(Rt)−λ⋅∑t=1K−1∣Rt+1−Rt∣maxt=1∑KQ(Rt)−λ⋅t=1∑K−1∣Rt+1−Rt∣
-
Q(Rt)Q(Rt):码率为 RtRt 时的视频质量(用VMAF或PSNR衡量)
-
第二项:惩罚相邻块的码率变化,实现平滑
-
λλ:平滑强度系数(通过离线实验调参)
在线决策
SODA 不直接求解整个序列,而是用滚动优化 (Receding Horizon):
-
基于当前吞吐量和缓冲区,预测未来 K 块的可用带宽
-
用动态规划在 O(K×M) 时间内求出最优码率序列(M是可用码率等级数)
-
只执行第一块的码率,下一时刻重复
这种方法相比贪婪策略,能将码率切换次数减少近 90%。
四、Rufus(亚马逊AI助手)中的视觉搜索
Rufus 允许用户上传图片,然后返回相关商品。技术流程:
-
图像编码 :使用 CLIP 或类似的多模态模型,将图片映射为向量 vimgvimg
-
商品索引 :所有商品的主图也预计算向量 vprodvprod,存入 FAISS 或 SCaNN 向量数据库
-
近似最近邻搜索:给定 vimgvimg,在毫秒级内找到最相似的 vprodvprod(使用乘积量化或HNSW图索引)
-
重排序:结合文本匹配和用户个性化信号,给出最终推荐
关键技术参数
-
向量维度:512 或 768
-
召回数量:Top-100
-
延迟要求:<50ms
总结:算法的本质
算法就是一个确定的计算步骤序列,将输入(用户查询、主图、历史行为)映射为输出(商品排序、码率选择)。技术细节体现在:
-
数学模型(如线性加权、Transformer)
-
优化目标(如最大化CTR、最小化卡顿)
-
数据结构与工程技巧(如向量索引、滚动规划)
1. A9 排序中的线性模型(逻辑回归)
用于粗排阶段,输出点击概率。

python
import numpy as np
class LogisticRegression:
def __init__(self, dim, lr=0.01):
self.w = np.zeros(dim)
self.b = 0.0
self.lr = lr
def sigmoid(self, z):
return 1 / (1 + np.exp(-z))
def predict_proba(self, X):
return self.sigmoid(X @ self.w + self.b)
def train_step(self, X, y):
# X: (batch, dim), y: (batch,)
pred = self.predict_proba(X)
grad_w = X.T @ (pred - y) / len(y)
grad_b = np.mean(pred - y)
self.w -= self.lr * grad_w
self.b -= self.lr * grad_b
loss = -np.mean(y * np.log(pred + 1e-8) + (1-y) * np.log(1-pred + 1e-8))
return loss
2. GBDT(梯度提升决策树)用于精排
亚马逊精排使用 LightGBM 或 XGBoost。这里展示最简单的回归树提升版本(用于预测CTR)。

python
from sklearn.tree import DecisionTreeRegressor
class SimpleGBDT:
def __init__(self, n_estimators=100, learning_rate=0.1, max_depth=3):
self.n_estimators = n_estimators
self.lr = learning_rate
self.trees = []
self.max_depth = max_depth
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def fit(self, X, y):
# 初始化预测值为 log-odds (默认 0)
self.initial_pred = np.log(np.mean(y) / (1 - np.mean(y) + 1e-8))
F = np.full(len(y), self.initial_pred)
for _ in range(self.n_estimators):
# 计算负梯度(残差)
p = self.sigmoid(F)
residuals = y - p
# 训练回归树拟合残差
tree = DecisionTreeRegressor(max_depth=self.max_depth)
tree.fit(X, residuals)
self.trees.append(tree)
# 更新预测值(只使用树的叶节点均值,此处简化)
F += self.lr * tree.predict(X)
def predict_proba(self, X):
F = np.full(len(X), self.initial_pred)
for tree in self.trees:
F += self.lr * tree.predict(X)
return self.sigmoid(F)
3. COSMO 中的跨模态注意力(Transformer 风格)
这是多模态模型中"看图识字"的核心计算。
python
import torch
import torch.nn as nn
import torch.nn.functional as F
class CrossModalAttention(nn.Module):
def __init__(self, d_model=768, n_heads=12):
super().__init__()
self.mha = nn.MultiheadAttention(d_model, n_heads, batch_first=True)
def forward(self, text_feat, image_feat):
# text_feat: (batch, seq_len_text, d_model)
# image_feat: (batch, seq_len_img, d_model)
# 让文本作为 query,图像作为 key/value
attended, attn_weights = self.mha(
query=text_feat, # 文本
key=image_feat, # 图像
value=image_feat
)
# attended: 融合了图像信息的文本特征
return attended, attn_weights
# 使用示例
d_model = 768
text = torch.randn(4, 10, d_model) # batch=4, 10个文本token
image = torch.randn(4, 49, d_model) # 49个图像patch
model = CrossModalAttention(d_model)
output, weights = model(text, image)
print(output.shape) # torch.Size([4, 10, 768])
4. SODA 动态规划求解最优码率序列
SODA 的核心是在带宽预测下,求解未来 K 个块的码率组合,最大化质量并最小化切换。
5. CLIP 对比损失(用于 Rufus 视觉搜索)
Rufus 使用 CLIP 风格的对比学习,使匹配的(图像,文本)对向量相似度高。
python
import torch
import torch.nn.functional as F
def clip_loss(image_embeds, text_embeds, temperature=0.07):
"""
image_embeds, text_embeds: (batch, d)
"""
# 归一化
image_embeds = F.normalize(image_embeds, dim=1)
text_embeds = F.normalize(text_embeds, dim=1)
# 相似度矩阵
logits = image_embeds @ text_embeds.T / temperature
batch_size = logits.shape[0]
# 标签:对角线位置
labels = torch.arange(batch_size).to(logits.device)
# 图像到文本的损失
loss_i2t = F.cross_entropy(logits, labels)
# 文本到图像的损失
loss_t2i = F.cross_entropy(logits.T, labels)
return (loss_i2t + loss_t2i) / 2
# 模拟数据
img_vec = torch.randn(64, 512)
txt_vec = torch.randn(64, 512)
loss = clip_loss(img_vec, txt_vec)
print("Contrastive Loss:", loss.item())
总结
| 模型 | 核心数学 | 关键代码技巧 |
|---|---|---|
| 逻辑回归 | sigmoid + 交叉熵 | 向量化梯度更新 |
| GBDT | 拟合负梯度残差 | 递归拟合回归树 |
| 跨模态注意力 | softmax(QK^T)V | PyTorch MultiheadAttention |
| SODA | 动态规划 | 二维状态 + 回溯 |
| CLIP | InfoNCE 对比损失 | 归一化 + 交叉熵 |