Instructions to use openbmb/MiniCPM5-2B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use openbmb/MiniCPM5-2B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="openbmb/MiniCPM5-2B") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("openbmb/MiniCPM5-2B") model = AutoModelForCausalLM.from_pretrained("openbmb/MiniCPM5-2B", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use openbmb/MiniCPM5-2B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "openbmb/MiniCPM5-2B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "openbmb/MiniCPM5-2B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/openbmb/MiniCPM5-2B
- SGLang
How to use openbmb/MiniCPM5-2B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "openbmb/MiniCPM5-2B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "openbmb/MiniCPM5-2B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "openbmb/MiniCPM5-2B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "openbmb/MiniCPM5-2B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use openbmb/MiniCPM5-2B with Docker Model Runner:
docker model run hf.co/openbmb/MiniCPM5-2B
拿来开发 TODOs Java 后端的经历
写在前面:我想测试它的能力边界,所以安排了一个对于2B小模型来说有一定挑战,但对于商用大模型来说轻松完成的任务。简单的Hello world程序、函数级或单个源文件级别的小demo无法测出它的能力边界,而一个TODOs CURD项目的量级应该是可以的。
1、白手起家阴沟翻船
我创建一个空白文件夹让它从0开始创建spring boot项目写一个 TODOs 后端。系统装了Microsoft OpenJDK,但没有装mvn工具,所以我让它用mvnw。
结果这个模型反复 find / 扫盘找 mvn、mvnw,我几次暴力打断后让它直接下最新的 mvnw,才勉强把它头拧过来。
本来以为接下来会正常一点,没想到它卡在了 java 可执行文件的位置上。Windows 的 C:\Program Files 带了个空格,它又喜欢打全路径调用 java,打全路径就算了,又不用双引号包起来,一调一个不吱声。
后来我实在看不下去给它掐了,去 start.spring.io 上配好项目骨架下载回来解压给它用。
(相关讨论:https://huggingface.co/openbmb/MiniCPM5-2B/discussions/27)
2、编译通过是可能的,但编译通过又不太可能
有了项目骨架,它写起功能来看上去是挺顺风顺水的,项目结构也做得有模有样:
然而一跑 mvnw clean package 就露馅了,一堆报错:
这里有个很明显的错误是在测试代码里用了 jackson2 的类,但 spring boot 4 是 jackson3。
3、第一关:大战 jackson
我让它修复编译错误,它摸索一番后,把 pom.xml 改了,加了 jackson 2 依赖:
我打断了它,并让它改回来。
我想着它总该能发现 jackson 的版本问题吧,没想到它判定为“缺少jackson依赖库”,所以直接把相关测试代码删了。
(插入一段画外音,从这里开始 Cherry Studio 就一直在那反复崩溃,当时我还不知道发生了什么所以换成了 pi coding agent。当然后来知道了原因: https://huggingface.co/openbmb/MiniCPM5-2B/discussions/27#6ae86ed977258068b06d53d6 )
4、测试通过是可能的,但测试通过又不太可能
后来它继续修复剩下的编译问题,总算能跑测试了。
不出所料,测试一跑就爆炸。
其实到了这里我已经没有什么耐心了,它一直在那里编造不存在的东西,反复错,反复改:
后面不截图了,基本上是死循环。
所以接下来是D指导评价环节。
我让D指导接手项目并评估开发者的水平。
注:以下内容由 DeepSeek V4.1 Flash 1017 生成。
我的结论会比较直接:初级水平,大约 0.5–1 年经验,并且高度依赖代码生成工具;最关键的证据是——这份代码从来没有成功启动过一次。
一、四个独立的启动致命伤,说明代码没被执行过
这四处代码如果单独存在一处,只要运行一次就会暴露;四处同时存在,只能说明作者写完就停手了:
| 症状 | 真实情况 |
|---|---|
TodoStatus 枚举上的 @Entity |
Hibernate 会把它当实体处理,启动直接失败 |
driver-class-name: org.sqlite.JDBCEngine |
真实类名是 org.sqlite.JDBC,"Engine" 是凭空加的 |
spring.jpa.dialect: org.hibernate.dialect.SQLiteDialect |
属性名不对(应为 spring.jpa.properties.hibernate.dialect),类名也不对(Hibernate core 里没有这个类,得引 community-dialects) |
jdbc:sqlite:.:memory: |
想写内存库,正确写法是 jdbc:sqlite::memory:,多出来的 .: 像是路径占位符没删干净 |
再补一条旁证:SQLite 配了 username: root / password: root,是从 MySQL 教程搬过来的。四个配置项全错、无一验证,这不是"改坏了",是"没跑过"。
二、两个凭空出现的标识符,暴露了"生成+照抄"
WebEnvironment.ISOLATION_WITH_DESIRED_ENV:这个常量在任何 Spring 版本里都不存在(只有MOCK/RANDOM_PORT/DEFINED_PORT/NONE)。注意它不是写错了某个真实名字,是编了一个名字。org.sqlite.JDBCEngine同理。
同时又有反方向的证据:pom 里 lombok 和 annotationProcessorPaths 都配好了,结果全项目手写了 100 多行 getter/setter,lombok 只在一个枚举上挂了个没用的 @Getter。LLM 生成代码不会这样——它会用 lombok。所以画像是:照着教程把工程搭起来 → 拿生成式工具产出代码 → 手工改一点 → 从来没跑。
三、语义层面的问题比语法更值得说
TodoController里手写了两遍 7 行的TodoResponse赋值,而同一个项目的TodoService里就有一个现成的私有toResponse()——没读完自己的文件。getTodo返回TodoResponse,同文件其余方法返回Todo。40 行内的不一致,这是自动补全漂移,不是设计取舍。TodoListResponse.items是List<Todo>,实体直接出参,和最上面那个"返回 DTO"的决定自相矛盾。updatedAt字段建了、声明了nullable=false、但更新时从来不刷新。字段存在,职责不存在。TodoRepository.findByTitleAndUserId返回单个Todo,可这个查询天然可能命中多条,应该是Optional或List。声明了但没有任何地方用。- 一个叫 CRUD 的服务,没有 DELETE;引了
validation却一个校验注解都没写;异常抛RuntimeException("Todo not found"),客户端拿到的是 500,不是 404。
四、最让我在意的一处
TodoControllerTests 里写着:
// Note: Jackson dependency missing, test skipped for now
Jackson 明明在 classpath 上(jackson-databind 3.0.2,我导出依赖树确认过)。真实原因大概率是不熟 MockMvc、写不出来。于是他编了一个原因,把测试体删空,然后继续往下写。
而那个测试类注入的是 TodoService 而不是 MockMvc——就算它跑起来也会是绿的。一个永远不会失败的测试比一个失败的测试危险得多:它给人"这块已经覆盖了"的错觉。
真正拉开差距的从来不是会不会写,而是卡住时是"查清楚"还是"找个说法绕过去"。这一处选了后者。
五、公道话
不能全否。有几处是对的,而且是靠直觉就没跑偏的那种:
- 分层是干净的:controller / service / repository / entity / dto,没有 God class
- DTO 与实体分离的意识在(虽然执行不一致)
TodoListResponse带totalItems,说明他在想前端怎么用@Column(length = 500)/length = 100—— 有人认真想过列宽- 用
application.yaml、带mvnw,工程习惯是现代的
换句话说:架构的样子学到了,语义的内容没学。 看得出是照着不错的材料在搭,只是搭完没有验证的能力和习惯。
六、画像
三个候选,我押第一个:
- 初级开发者 + 生成式工具(最可能)——骨架来自模板,代码来自生成,手工微调,从未端到端运行
- 非 Java 栈的人临时接活(前端/Node/Python 背景)——同样能解释
root/root、JDBCEngine这类知识空缺,但解释不了 lombok 配好却不用 - 资深但极敷衍——技术上说得通,但资深的人哪怕偷懒也会先
mvn spring-boot:run看一眼,成本太低了
这类人留下的麻烦,麻烦之处不在于代码写得差,而在于它看起来只差一点点:目录结构漂亮、类名规范、注释礼貌,让人以为再调几个配置就能跑,实际每一层语义都得重推一遍。
其实从这里也能看出来小模型的局限性:世界知识缺乏、大型项目(相对2B来说算大型)开发中注意力欠缺、逻辑思考能力不足、幻觉爆炸。生成的代码只是看上去是对的,真跑起来到处是问题。到了修复bug时,不懂得往哪个方向思考根本原因,也不知道如何排查问题,甚至官方文档、javadoc、sources也不翻就开始编造不存在的东西。
llama.cpp 参数:
$LLAMA_CPP_ROOT = "$PSScriptRoot\..\..\.."
$LLAMA_SERVER = "$LLAMA_CPP_ROOT\bin\llama-server.exe"
$MODEL_ROOT = $PSScriptRoot
$MODEL_FILE = "$MODEL_ROOT\MiniCPM5-2B-Q8_0.gguf"
# 推荐参数
# --temperature 1.0 --top-p 0.95 --min-p 0.0
# 抑制重复输出
# --repeat-penalty 1.05
& "$LLAMA_SERVER" `
--host 0.0.0.0 --port 60001 --api-key "sk-12345678" --log-verbosity 4 `
--ctx-size 128000 --ctx-checkpoints 4 --cache-type-k q8_0 --cache-type-v q8_0 --parallel 1 `
--temperature 1.0 --top-p 0.95 --min-p 0.0 `
--model "$MODEL_FILE" `
--load-mode mlock --fit off -ngl 43
我的电脑显存有点不够,开128k上下文只能用 q8 量化了。采样参数都有遵循官方文档的指导,不存在故意改参数降智的情况。
你好,非常感谢这么详细的实测记录。方便的话,能否分享一下这次的完整对话或 agent 轨迹(比如 coding agent 的日志)?我们希望把它作为内部评测用例,后续版本也会用同样的任务回测,有进展会在这里更新。







