CLIP 这条对比学习(contrastive learning,把"配对"的样本拉近、"不配"的推远)路线,本质就是你做推荐/搜索时熟悉的双塔召回模型(two-tower retrieval)——user 塔和 item 塔各自把输入编码成向量,在同一空间算内积。CLIP 把"图像塔"和"文本塔"训到同一个向量空间,配对的图文内积大、错配的小。而现代生成式 VLM(LLaVA 那一路)走的是另一条:在 LLM 前面接一个"图像→token"的编码器,相当于给只懂文本的查询引擎加一层 ETL 适配器,把图像翻译成 LLM 能直接消费的 token。
痛点:LLM 的输入只有文本 token,它根本"看不见"像素。要让模型理解图像,业界分出两条范式:
import base64 from anthropic import Anthropic client = Anthropic() # 需要 ANTHROPIC_API_KEY img = base64.b64encode(open("chart.png", "rb").read()).decode() resp = client.messages.create( model="claude-opus-4-8", max_tokens=512, messages=[{"role": "user", "content": [ {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": img}}, {"type": "text", "text": "这张图表的核心结论是什么?"} ]}] ) # 图和文字放进同一条 message —— 它们最终都是 token print(resp.content[0].text)
音频是一条一维时间序列流——像数据库的 binlog 或消息队列里的事件流,连续不断。Whisper 的做法:把波形切成 30 秒窗口、转成 log-Mel 频谱图(一张"时间 × 频率"的二维图),再用 encoder-decoder Transformer 把它"翻译"成文字 token。本质和 seq2seq 机器翻译同构:源序列是声音,目标序列是文字,中间隔着一个编码器和一个解码器。
痛点:传统语音识别要拼接好几个模块——语音活动检测、声学模型、语言模型、强制对齐,每个独立训练、接口脆弱。Whisper(2022)用一个端到端 seq2seq 模型替换整条流水线,靠 68 万小时"弱监督"(weak supervision,即从网络抓的不保证完全准确的字幕)数据训练,做到 zero-shot 跨语言、跨口音的鲁棒识别。机制四步:波形 → log-Mel 频谱 → encoder 编码 → decoder 自回归吐文字 token,用特殊控制 token 切换任务(转写 / 翻译 / 语言识别 / 时间戳)。
新一代 audio LLM(如 GPT-4o、Gemini 的原生语音)更进一步:把音频 token 和文本 token 放进同一个 LLM,直接做语音对话、情感与语气理解,而不只是"转成文字"。这又回到那个统一主题——音频也被编码成 token。
from openai import OpenAI client = OpenAI() # 需要 OPENAI_API_KEY # Whisper 把音频文件直接转成文字(官方托管 API) with open("meeting.mp3", "rb") as f: tr = client.audio.transcriptions.create( model="whisper-1", file=f, response_format="text", # language="zh" 可显式指定,避免短音频语种误判 ) print(tr) # 拿到文字后,再喂给 LLM 做总结 / 抽取行动项
视频 = 图像在时间维度上的分片(sharding)。1 分钟 30fps 的视频 = 1800 帧,每帧又是几百个 patch token——token 量直接爆炸,等于对一张超大表做全表扫描。工程上必须像数据库做采样 + 分区裁剪一样:抽帧(frame sampling)+ 时序池化,只保留信息增量大的帧,把冗余的"增量日志"丢掉。
视频理解的核心难题就两个字:太多——token 爆炸 + 时序冗余。相邻帧往往 99% 重复(像几乎没变化的增量日志),全塞进去既贵又会稀释注意力。两类机制应对:
import cv2, base64 # 用 OpenCV 按 1fps 稀疏抽帧,而不是把每一帧都送进模型 cap = cv2.VideoCapture("lesson.mp4") fps = cap.get(cv2.CAP_PROP_FPS) frames = [] i = 0 while True: ok, frame = cap.read() if not ok: break if i % int(fps) == 0: # 每秒取 1 帧 _, buf = cv2.imencode(".jpg", frame) frames.append(base64.b64encode(buf).decode()) i += 1 # 把这些帧 + 时间戳一起送进 VLM,问"第几秒发生了什么" print(len(frames), "帧送入模型(已稀疏化)")
VLA 把机器人的"感知 → 决策 → 执行"做成一个端到端服务。传统机器人是微服务架构:感知模块、规划模块、控制模块各自独立、靠接口拼接,一处出错全链路崩。VLA(RT-2 / OpenVLA)是单体大模型:图像 + 自然语言指令进,机器人动作直接出——而且动作被编码成 token(像把一次 RPC 调用序列化成 token),让机器人控制直接复用 LLM 那套"预测下一个 token"的机器。
痛点:机器人极难泛化——换一个没见过的物体、没见过的厨房就失败,因为真实机器人数据稀缺(采集一条轨迹要真机操作,慢且贵)。VLA 的关键洞见:把动作离散化成 token,机器人控制就变成"序列生成",于是能复用 VLM 在互联网级图文数据上学到的常识。
RT-2(2023)把 7 自由度动作(xyz 位移 + 姿态 roll/pitch/yaw + 夹爪开合)离散成 token,和文本放进同一个词表,在机器人轨迹和网络图文上联合微调。结果机器人涌现出"常识推理"能力:让它"把草莓放进正确的碗",它能从预训练知识里推出草莓和碗的语义关系——这是纯机器人数据训不出来的。
from transformers import AutoModelForVision2Seq, AutoProcessor import torch # OpenVLA:开源 7B 视觉-语言-动作模型(需 GPU) proc = AutoProcessor.from_pretrained("openvla/openvla-7b", trust_remote_code=True) vla = AutoModelForVision2Seq.from_pretrained( "openvla/openvla-7b", torch_dtype=torch.bfloat16, trust_remote_code=True).to("cuda:0") image = get_from_camera() # PIL 图像,来自机器人摄像头 prompt = "In: What action should the robot take to pick up the cup?\nOut:" inputs = proc(prompt, image).to("cuda:0", dtype=torch.bfloat16) # 输出 7 自由度动作(xyz+姿态+夹爪),再反归一化送给真机 action = vla.predict_action(**inputs, unnorm_key="bridge_orig", do_sample=False) print(action) # 动作其实就是被"解码"出来的 token