mps代替cuda运行bge-m3模型
概述
BAAI/bge-m3是一款同时支持稠密和稀疏向量的嵌入模型,双重检索有利于提高RAG检索的精确率,但是在线的bge-m3 API服务很少,而且不一定将稠密和稀疏向量都返回,因此可以自己下载和部署模型,目前笔者这边没有集成了nvdia显卡可以使用cuda加速的设备,仅有一台M4 Pro Mac mini,不过苹果发布了可以调用自家Apple Silicon GPU加速的mps,并且很多计算框架底层都支持了使用mps加速,比如一些版本的PyTorch,因此这里采用Mac mini完成部署。
部署
模型的下载地址是:https://modelscope.cn/models/BAAI/bge-m3,下载后,新建一个项目,虚拟环境安装以下依赖包运行模型
pip install torch torchvision torchaudio
pip install -U FlagEmbedding新建main.py,装载并调用模型,FlagEmbedding用于运行BAAI/bge-m3,其底层调用的就是PyTorch,与传统的nvdia cuda加速在使用上的唯一区别就是加速设备指定为mps而不是nvdia设备上的cuda
import torch
from FlagEmbedding import BGEM3FlagModel
device = "mps" if torch.backends.mps.is_available() else "cpu"
model = BGEM3FlagModel(
model_name_or_path="/Users/liuzijian/model/bge-m3", #模型文件夹位置
devices=device,
use_fp16=False
)
texts = [
"苹果 M4 芯片非常适合运行本地 AI 模型",
"BGE-M3 支持稠密检索和稀疏检索"
]
output = model.encode(
texts,
return_dense=True,
return_sparse=True,
return_colbert_vecs=False,
)
dense = output["dense_vecs"] #稠密向量[]
sparse = output["lexical_weights"] #稀疏向量[]成功启动并装载和调用模型,活动监视器显示gpu有python进程在大量占用
liuzijian@Mac-mini bge % source .venv/bin/activate
(.venv) liuzijian@Mac-mini bge % python main.py
Loading weights: 100%|█████████████████████████████████████████████████████████████| 391/391 [00:00<00:00, 8420.74it/s]
还可以与fastapi配合,做成api服务对外暴露,供Agent调用
import uvicorn
from fastapi import FastAPI, HTTPException, Header
from pydantic import BaseModel
from FlagEmbedding import BGEM3FlagModel
import torch
import os
app = FastAPI()
device = "mps" if torch.backends.mps.is_available() else "cpu"
model = BGEM3FlagModel(
model_name_or_path="/Users/liuzijian/model/bge-m3",
devices=device,
use_fp16=True
)
# 简单的 API Keys 列表(可以从环境变量读取)
VALID_API_KEYS = [""]
class Request(BaseModel):
texts: list[str]
@app.post("/embed")
def embed(req: Request, x_api_key: str = Header(default=None)):
# 简单鉴权
print(req.texts)
if x_api_key not in VALID_API_KEYS:
raise HTTPException(status_code=401, detail="Invalid API Key")
result = model.encode(
req.texts,
return_dense=True,
return_sparse=True,
return_colbert_vecs=False,
)
return {
"dense": result["dense_vecs"].tolist(),
"sparse": [
{
str(k): float(v)
for k, v in x.items()
}
for x in result["lexical_weights"]
]
}
@app.get("/health")
def health():
return {"status": "ok"}
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="127.0.0.1", # 开发时用127.0.0.1,生产用0.0.0.0
port=8000,
reload=False, # 开发时开启热重载
log_level="info"
)
HTTP调用,即可实现远程调用模型
POST 127.0.0.1:8001/embed
x-api-key: 1111111111
Content-Type: application/json
{
"texts":["苹果"]
}{
"dense": [
[
-0.0270538330078125,,,,,,
]
],
"sparse": [
{
"6": 0.0648193359375,
"64046": 0.321533203125
}
]
}"如果文章对您有帮助,可以请作者喝杯咖啡吗?"
微信支付
支付宝
mps代替cuda运行bge-m3模型
https://blog.liuzijian.com/post/2026/09/02/apple-mps-run-bge-m3-embedding/