Ollama 支持模型微调也可以支持词库,支持RAG,go语言开发的大模型的推理应用,

Ollama 只支持有限的模型,就是他提供的那些大模型

https://github.com/ollama/ollama?tab=readme-ov-file#community-integrations

他支持的库 再这里 https://ollama.com/library
deepseekR1也是支持的

你想了解 Ollama 平台上的模型是否支持微调,以及是否专门支持“词库微调”这类场景,对吧?我先明确核心结论,再给你具体的实现方式和建议。

一、Ollama 支持模型微调,但无“一键式”可视化操作

Ollama 本身支持对模型进行微调(主要是轻量级的 LoRA 微调),但它没有图形化的微调界面,也没有内置“词库微调”的专属功能——“词库微调”本质是让模型记住特定知识库内容,Ollama 更推荐用「检索增强生成(RAG)」替代这种场景,而非传统微调。

1. Ollama 模型微调的核心方式(LoRA 微调)

Ollama 基于 Llama.cpp 构建,支持加载 LoRA 微调后的权重文件,核心步骤如下(以常见的 Llama 系列模型为例):

步骤 1:准备微调环境和数据

先安装依赖(需 Python 环境):

pip install transformers peft accelerate datasets bitsandbytes

准备微调数据(JSONL 格式,示例如下,聚焦你要“固化”的词库/知识):

{"instruction": "什么是即梦AI?", "input": "", "output": "即梦AI是字节跳动旗下的AI创作平台。"}
{"instruction": "即梦AI的所属公司是哪家?", "input": "", "output": "即梦AI所属的公司是字节跳动。"}
步骤 2:用工具训练 LoRA 权重

llama.cppunsloth 等工具训练 LoRA 微调权重(以 unsloth 为例,轻量化、速度快):

from unsloth import FastLanguageModel
import torch

# 加载基础模型(需先通过 Ollama 下载,或本地已有)
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "llama-3-8b",  # 替换为你要微调的 Ollama 基础模型
    max_seq_length = 2048,
    dtype = torch.float16,
    load_in_4bit = True,
)

# 启用 LoRA 微调
model = FastLanguageModel.get_peft_model(
    model,
    r = 16,  # LoRA 秩,越小越轻量化
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj"],
    lora_alpha = 16,
    lora_dropout = 0,
    bias = "none",
)

# 加载微调数据(上述 JSONL 文件)
from datasets import load_dataset
dataset = load_dataset("json", data_files="your_data.jsonl")["train"]

# 训练(简化版,具体可参考 unsloth 官方文档)
FastLanguageModel.train(
    model=model,
    tokenizer=tokenizer,
    dataset=dataset,
    batch_size=2,
    max_steps=100,  # 小数据量微调足够
)

# 保存 LoRA 权重
model.save_pretrained("lora_weights")
步骤 3:在 Ollama 中加载微调后的模型

编写 Modelfile(Ollama 的模型配置文件),指定基础模型 + 加载 LoRA 权重:

# 基础模型(需先通过 ollama pull 下载)
FROM llama3:8b

# 加载 LoRA 微调权重(替换为你的权重路径)
LODAD lora_weights

# 配置模型参数
PARAMETER temperature 0.1
SYSTEM "你是一个精通即梦AI知识的助手,所有回答必须基于给定的词库。"

用 Ollama 构建自定义模型:

ollama create my-llama3-custom -f Modelfile

启动自定义模型:

ollama run my-llama3-custom
2. “词库微调”的替代方案:RAG(更轻量、易维护)

如果你的核心需求是让 Ollama 模型“调用词库”而非“记住词库”,RAG 比微调更合适(无需训练,词库可动态更新),以下是极简实现示例:

import ollama
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer

# 1. 准备词库并构建向量库
# 词库内容(可替换为你的自定义词库)
knowledge_base = [
    "即梦AI是字节跳动旗下的AI创作平台。",
    "即梦AI专注于AI创作领域,由字节跳动开发维护。"
]

# 加载向量模型(生成文本向量)
embed_model = SentenceTransformer("all-MiniLM-L6-v2")
# 生成词库向量
knowledge_embeddings = embed_model.encode(knowledge_base)
# 构建 FAISS 向量库
index = faiss.IndexFlatL2(knowledge_embeddings.shape[1])
index.add(np.array(knowledge_embeddings))

# 2. 实现检索 + 调用 Ollama 生成回答
def rag_answer(question):
    # 检索相关词库内容
    q_embedding = embed_model.encode([question])
    _, idx = index.search(np.array(q_embedding), k=1)  # 取最相关的1条
    relevant_knowledge = knowledge_base[idx[0][0]]
    
    # 拼接问题和检索结果,传给 Ollama
    prompt = f"""基于以下知识回答问题:
{relevant_knowledge}

问题:{question}
回答:"""
    
    # 调用 Ollama 模型
    response = ollama.generate(model="llama3:8b", prompt=prompt)
    return response["response"]

# 测试
print(rag_answer("即梦AI属于哪家公司?"))
# 输出:即梦AI属于字节跳动旗下,是字节跳动开发的AI创作平台。

二、核心场景对比:微调 vs RAG(词库场景优先选 RAG)

方式 适用场景 优点 缺点
LoRA 微调 固化核心/静态词库知识 回答速度快,无需外部依赖 词库更新需重新微调,占用显存
RAG 动态更新的词库/知识库 词库可实时修改,轻量化 需额外搭建向量库,检索耗时

总结

  1. Ollama 支持模型微调(主要是 LoRA 轻量微调),需结合外部工具训练权重 + Modelfile 加载;
  2. 无直接“词库微调”功能,词库增强优先用 RAG 实现(更易维护、成本更低);
  3. 只有需要“固化核心词库知识、无动态更新需求”时,才考虑 LoRA 微调。

如果你的词库是固定的小体量知识(比如几十条),微调是可行的;如果词库会频繁更新,RAG 是更优解。

自定义词库

在Unsloth中设置自定义词库通常涉及以下步骤,具体取决于你想要实现的目标:

  1. 如果是要扩展分词器词汇表

from transformers import AutoTokenizer
from unsloth import FastLanguageModel

加载模型和分词器

model, tokenizer = FastLanguageModel.from_pretrained(
model_name = “unsloth/mistral-7b-bnb-4bit”,
max_seq_length = 2048,
dtype = None,
load_in_4bit = True,
)

添加自定义词汇

new_tokens = [“<special_token1>”, “<special_token2>”, “特定领域术语”]
tokenizer.add_tokens(new_tokens)

调整模型嵌入层大小

model.resize_token_embeddings(len(tokenizer))

  1. 如果需要完全自定义分词器

from transformers import AutoTokenizer, PreTrainedTokenizerFast

创建自定义分词器

custom_tokenizer = PreTrainedTokenizerFast(
tokenizer_file=“your_custom_tokenizer.json”,
# 或从现有分词器扩展
bos_token=“”,
eos_token=“
”,
unk_token=“”,
pad_token=“”,
)

加载Unsloth模型时使用自定义分词器

model, _ = FastLanguageModel.from_pretrained(
model_name = “unsloth/mistral-7b-bnb-4bit”,
tokenizer = custom_tokenizer, # 传入自定义分词器
max_seq_length = 2048,
load_in_4bit = True,
)

  1. 对于特定场景的配置

添加领域特定词汇

从文件读取自定义词汇

with open(“custom_vocab.txt”, “r”, encoding=“utf-8”) as f:
domain_tokens = [line.strip() for line in f]

添加到分词器

num_added = tokenizer.add_tokens(domain_tokens)
print(f"Added {num_added} new tokens")

如果需要,初始化新token的嵌入

if num_added > 0:
model.resize_token_embeddings(len(tokenizer))
# 可以初始化新token的嵌入为现有token的平均值
with torch.no_grad():
for token in domain_tokens:
token_id = tokenizer.convert_tokens_to_ids(token)
# 初始化逻辑…

训练时使用自定义词汇表

from unsloth import FastLanguageModel, is_bfloat16_supported

在训练配置中指定

model, tokenizer = FastLanguageModel.from_pretrained(
model_name = “unsloth/llama-2-7b-bnb-4bit”,
max_seq_length = 2048,
tokenizer_add_special_tokens = True, # 控制是否添加特殊token
)

训练配置

from trl import SFTTrainer
from transformers import TrainingArguments

trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
args = TrainingArguments(
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4,
warmup_steps = 5,
max_steps = 60,
learning_rate = 2e-4,
fp16 = not is_bfloat16_supported(),
bf16 = is_bfloat16_supported(),
logging_steps = 1,
output_dir = “outputs”,
optim = “adamw_8bit”,
seed = 3407,
),
)

  1. 常见注意事项

  2. 词汇表大小对齐:确保模型嵌入层与分词器词汇表大小一致

  3. 特殊token处理:注意处理pad、eos、bos等特殊token

  4. 性能考虑:添加过多新token可能影响推理速度

  5. 完整示例

import torch
from unsloth import FastLanguageModel

def setup_custom_vocabulary(model_name, custom_tokens_file):
“”“设置自定义词汇表”“”

# 1. 加载基础模型
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name=model_name,
    max_seq_length=2048,
    dtype=None,
    load_in_4bit=True,
)

# 2. 加载自定义词汇
with open(custom_tokens_file, 'r') as f:
    custom_tokens = [line.strip() for line in f if line.strip()]

# 3. 添加到分词器
num_added = tokenizer.add_tokens(custom_tokens)
print(f"成功添加 {num_added} 个新token")

# 4. 调整模型嵌入层
if num_added > 0:
    model.resize_token_embeddings(len(tokenizer))
    # 可以在这里添加新token的初始化逻辑

return model, tokenizer

使用示例

if name == “main”:
model, tokenizer = setup_custom_vocabulary(
“unsloth/llama-2-7b-bnb-4bit”,
“my_custom_vocab.txt”
)

根据你的具体需求选择合适的方法,如果遇到问题,可以查看Unsloth的官方文档或GitHub issues获取更多帮助。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐