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/
作者
Liu Zijian
发布于
2026年9月2日
许可协议