用Jlama本地部署gemma-2

部署模型推理

安装huggingface_hub:

py -m pip install huggingface_hub

我们用hf下载 量化版本:FP16 -> JQ4(4-bit) 这个是社区重打包的,完全公开。

但下面这些情况需要hugging face token:

  • 门控模型(gated model),比如原始的 google/gemma-2-2b-it 需要去 huggingface 点一下同意协议
  • 私有模型、上传操作
hf download tjake/gemma-2-2b-it-JQ4 --local-dir D:\huggingface\gemma-2-2b-it-JQ4  

量化版大小约2GB,是原始版1/3

本地springboot web,加jlama-core、jlama-native就可以把这个模型跑起来,其他配置:

jlama:
  model:
    # 已下载的 JQ4 量化模型路径
    path: D:\huggingface\gemma-2-2b-it-JQ4
  generation:
    temperature: 0.3
    max-tokens: 512

上下文记忆用内存里的Map,测试了一下基本能用,说实话 2B 参数就这么大,能正确记住上下文已经算及格了,偶尔兜不住是正常的。

实践心得总结
本地模型就是"聪明胶水"
上游确定性输出(订单号、用户意图、检索结果)
        ↓
    本地小模型  ← 系统提示词 + RAG 上下文 + Tool Schema
        ↓
结构化输出 / 工具调用 / 最终回复

一般不用做开放式闲聊,而是做这些事:

  • 意图识别、实体抽取、情感判断
  • 把 RAG 召回的多段文本提炼成一个答案
  • 根据语境选合适的工具并填参数
  • 格式化输出(JSON、特定话术)

这类任务对模型不需要强创造力,需要的是指令遵循 + 格式稳定 + 低延迟。

不同量级模型的定位
┌───────────────────┬───────────────┬────────────────────────────────────────────┐
│      参数量       │     角色      │                  典型场景                  │
├───────────────────┼───────────────┼────────────────────────────────────────────┤
│ 1B-3B(现在的)    │ 胶水 / 筛选器 │ 单步分类、简单抽取、边缘端,不太稳         │
├───────────────────┼───────────────┼────────────────────────────────────────────┤
│ 7B-14B            │ 本地主力      │ 意图路由、RAG 合成、Tool Calling,够用且快 │
├───────────────────┼───────────────┼────────────────────────────────────────────┤
│ 30B-70B           │ 本地天花板    │ 复杂推理、多步 Agent,能打但吃显存         │
├───────────────────┼───────────────┼────────────────────────────────────────────┤
│ 70B-400B+         │ 云端满血      │ 全开放对话、深度推理、代码生成             │
└───────────────────┴───────────────┴────────────────────────────────────────────┘

本地部署的甜点在 7B-14B,日常"胶水"任务完全胜任,普通机器跑得动。

满血模型

云端闭源的都不公开参数了(Claude、GPT-5),开源的几个大玩家:

┌─────────────────┬──────┬────────────────┐
│      模型       │ 参数 │      架构      │
├─────────────────┼──────┼────────────────┤
│ DeepSeek-V3     │ 671B │ MoE,激活 ~37B │
├─────────────────┼──────┼────────────────┤
│ Llama 4         │ 405B │ Dense          │
├─────────────────┼──────┼────────────────┤
│ Qwen 3          │ 235B │ MoE            │
├─────────────────┼──────┼────────────────┤
│ Mistral Large 2 │ 123B │ Dense          │
└─────────────────┴──────┴────────────────┘

所以 Gemma 2B 跑通链路没问题,但真要当"胶水"用,上个 7B 的模型体验会好很多(比如 Qwen2.5-7B-Instruct 对中文友好,JLama 也支持)。本地部署 7B 量化版大概 4-5GB 。

笔者的笔记本电脑配置比较低,开了jlama-native加速的情况下,一次chat也要10几秒,所以就只用了2B的模型。

下载下来的LLM文件说明

目录结构

gemma-2-2b-it-JQ4/
├── config.json              # 模型架构定义
├── model.safetensors        # 模型权重(JQ4 量化)
├── tokenizer.json           # 分词器词表
├── tokenizer_config.json    # 分词器配置
├── .gitattributes           # Git LFS 元数据
├── README.md                # 模型说明
└── .cache/                  # huggingface-hub 下载缓存

config.json — 模型架构

{
  "model_type": "gemma2",        // JLama 靠这个字段决定用什么 Java 类加载
  "hidden_size": 2304,           // 隐藏层维度
  "num_hidden_layers": 26,       // Transformer 层数 → 2B 参数的来源
  "num_attention_heads": 8,      // 注意力头数
  "num_key_value_heads": 4,      // KV 头数(GQA 分组查询)
  "vocab_size": 256000,          // 词表大小
  "torch_dtype": "bfloat16",     // 原始精度(注:实际已被 JQ4 量化覆盖)
  ...
}

JLama 的 ModelSupport.loadModel() 就是读这个 json 判断走 Gemma2Model 还是 LlamaModel。

model.safetensors — 权重文件(2.3GB)

  • SafeTensors 格式:比 pickle 安全,不含可执行代码,直接 mmap 加载
  • JQ4 量化:原始 BF16(~5GB)被压缩到 Q4(4-bit),体积减半,精度损失很小
  • 加载时 JLama 按需反量化到 F32 计算

tokenizer.json — 词表(16.7MB)
把文本切成 token 的映射表。256000 个 token,每个 token 有 id 和对应的字符串。比如"你好"可能被切成[token_12345, token_67890]。

tokenizer_config.json — 分词器配置
特殊 token 的定义:

{
  "bos_token": "<bos>",           // 序列开头
  "eos_token": "<end_of_turn>",   // 轮次结束
  "chat_template": "..."          // 对话格式模板
}

其中 chat_template 就是拼 <start_of_turn>user\n...<end_of_turn>\n<start_of_turn>model\n...<end_of_turn> 的规则,JLama 的 promptSupport().builder() 自动按这个模板格式化。

.cache/ — 下载缓存
huggingface-hub 的内部缓存,删掉无所谓,不影响模型使用。

model.safetensors 权重文件 = 智能的载体

文件里存储的是 26 层 Transformer 的全部参数,每层包含:

Layer_i:
  ├── Self-Attention 权重(Q、K、V 投影矩阵 + 输出投影)
  ├── MLP 权重(两个全连接层,9216 → 2304 → 9216)
  └── RMSNorm 参数

加上词嵌入表(256000 × 2304)、输出投影、位置编码等。总共 ~2B 个浮点数,每个数字都是在海量语料上训练出来的结果。知识不是存在某个地方,而是分布在这些数字之间的数学关系里。

推理过程 = Transformer Decoder
就是典型的 自回归 Transformer Decoder 推理:

输入 "你好"
  → tokenizer → [token_123, token_456]
  → Embedding → 两个 2304 维向量
  → Layer 1:
      Self-Attention: 当前位置对前文加权(Masked,只看左边)
      MLP: 非线性变换
      → 输出 2304 维向量
  → Layer 2...26(同上)
  → LM Head: 2304 维向量 → 256000 维(词表大小)
  → Softmax → 概率分布
  → 采样 → 下一个 token "!"
  → 拼回去 "你好!" → 继续循环直到 <end_of_turn>

我们常所说的"矩阵运算"就是每一层里 Q×K^TSoftmax × V、全连接层的 W×x + b 这些。JLama 做的就是连续 26 层的矩阵乘法和激活函数运算,参数来自 model.safetensors,一次跑出一个 token,每次拼回输入继续跑,直到生出完整回复。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容