AI Tools

本地跑 SmolLM 当你的私人改写工具:不花 API 钱,数据不出本机

本地跑 SmolLM 当你的私人改写工具:不花 API 钱,数据不出本机
目录

一个 SaaS 客户的合规官曾经用一行邮件回绝了我催了三周的事:"不能用 ChatGPT,不能用 Claude,产品描述不能用任何外部 AI。"

行。他们要重写 4000 个产品页面来给整站迁移做准备,内容都在 NDA 保护下,法务不可能让数据离开公司。我打开钱包准备算"人工重写团队"的预算——然后停下了。我在自己笔记本上调 SmolLM 1.7B 已经玩了几周。模型不大,输出也不是 GPT-4 那个档次,但 4000 个页面里 80% 是那种没营养的改写活?它够用。

我们整本产品目录在本地重写完了。数据没离开过笔记本。账单是零。

那一刻起,"跑本地模型"不再是爱好,是工作流。

为什么是 SmolLM,为什么是本地

SmolLM 是 Hugging Face 的小模型家族——目前是 SmolLM2 这一代,三个尺寸:135M、360M、1.7B 参数。我做内容活只用最大的 1.7B;前两个做分类和抽取还行,写不出一段通顺的段落。

SmolLM 对营销人有趣的原因不是绝对智力。是这个实用三角:在普通笔记本上能跑(1.7B 大概占 2-3GB 内存,16GB 内存的机器完全放得下)、改写 200 字内容 2-5 秒出结果、对日常文案改写质量在"轻度编辑就能用"这个档位。

对比调用 API:

  • 没有按 token 收费。 4000 个页面用 OpenAI GPT-4o-mini 改写大概 30-60 美元。同样活走本地 SmolLM,电费成本——可能 30 美分。
  • 数据不离开你的机器。 合规团队睡得着觉。NDA 不会被动测试。
  • 没有 rate limit,没有宕机。 你的改写流水线不会因为 OpenAI 那天心情不好就断。
  • 延迟稳定。 第一次调用慢(模型加载),之后每次改写 2-5 秒,没有网络往返。

代价也是真的——质量比 GPT-4o 在细腻的创意工作上低一档,你用 0 美元的 API 账单换来了用自己的算力。但对营销里不性感的 80% 内容活(产品描述、Meta 改写、广告文案变体、邮件标题 A/B 测试),SmolLM 1.7B 是我用过最实用的本地方案。

十分钟装完

你需要三样:Ollama、SmolLM 模型、一种从脚本里调用它的方式。

第一步——装 Ollama。 它是一个单独的二进制,在本地跑模型并暴露一个简单 API。macOS、Linux、Windows(WSL2 或原生)都支持。去 ollama.com 下载安装。完事。

第二步——拉模型。 开一个终端:

bashollama pull smollm:1.7b

下载大概 1.1GB。之后模型就在你硬盘上,第一次调用时加载进内存。

第三步——冒烟测试。 同一个终端:

bashollama run smollm:1.7b "Rewrite this product description in a friendlier tone: Our CRM helps sales teams close more deals."

如果 3-5 秒后返回一个改写版本,就齐活。如果 20 秒没响应,笔记本风扇呼呼转,说明你的机器在边缘——关掉 Chrome 再试。

装完了。剩下就是 Python 脚本。

改写脚本本体

Ollama API 是模型外面包了一层薄壳——你 POST 一个 prompt,它返回响应。对内容改写工具,你想要的循环很简单:读源文本,丢给模型,存改写。下面是我用的起手式。

pythonimport requests
import json
import csv
from pathlib import Path

OLLAMA_URL = "http://localhost:11434/api/generate"
MODEL = "smollm:1.7b"

REWRITE_PROMPT = """你是一名营销文案编辑。请将下面的文本改写成
{tone} 的语气。保持原意不变。长度控制在原文的 {word_limit}% 以内。
只返回改写后的文本——不要前言,不要注释。

原文:
\"\"\"
{source}
\"\"\"

改写:"""

def rewrite(text: str, tone: str = "更亲切", word_limit: int = 120) -> str:
    prompt = REWRITE_PROMPT.format(
        tone=tone,
        word_limit=word_limit,
        source=text.strip()
    )
    response = requests.post(OLLAMA_URL, json={
        "model": MODEL,
        "prompt": prompt,
        "stream": False,
        "options": {
            "temperature": 0.4,   # 越低改写越稳定
            "num_predict": 400,   # 硬性截断输出长度
        }
    })
    response.raise_for_status()
    return response.json()["response"].strip()

def batch_rewrite(input_csv: str, output_csv: str, tone: str = "更亲切"):
    with open(input_csv, newline="", encoding="utf-8") as fin, \
         open(output_csv, "w", newline="", encoding="utf-8") as fout:
        reader = csv.DictReader(fin)
        writer = csv.DictWriter(fout, fieldnames=reader.fieldnames + ["rewrite"])
        writer.writeheader()
        for row in reader:
            row["rewrite"] = rewrite(row["source"], tone=tone)
            writer.writerow(row)
            print(f"已改写: {row.get('id', '?')[:30]}")

if __name__ == "__main__":
    batch_rewrite("products.csv", "products_rewritten.csv", tone="更亲切")

三件事决定质量:

  1. temperature: 0.4 本地小模型比 GPT-4 更容易跑偏。温度低一点能让改写稳定在轨道上。想要更多创意变体?推到 0.7——但要做好扔掉更多的准备。
  2. num_predict: 400 硬性截断输出 token。不加这个,模型偶尔会"再写一版"或者在改写完之后继续编。截断它就不得不停。
  3. Prompt 模板。 告诉模型"只返回改写后的文本——不要前言"能砍掉 80% 的垃圾输出。小模型最爱解释它接下来要做什么。

4000 行的批次,这脚本在 M1 MacBook Pro 上大概一小时跑 150-250 条改写。换成带独立显卡的台式机快 3-4 倍。怎么都得设好让它自己跑。

小模型的 Prompt 工程

这块是大部分指南跳过的,也是你真实输出质量赢或输的地方。SmolLM 1.7B 聪明到能用,但不够聪明到猜你想要什么。Prompt 就是全部的接口。

讲角色、讲任务、讲约束。 上面那个三段式 prompt(角色 / 任务 / 约束)是能跑起来的最小结构。少一块,质量掉一档。

明确说不要做什么。 加一句"不要添加原文中没有的信息"和"不要用营销陈词滥调('赋能'、'重塑'、'颠覆')"。小模型会本能地往套话走,大模型不会这么明显。

控制语气时给一组对比。 别只说"更亲切",试试:

语气:比原文更亲切。更亲切的例子:"我们做这个就是想让你的团队别再和 Excel 较劲。"
更冷的例子(避免):"本方案提供电子表格自动化能力。"

一好一坏两个例子,模型就有了靶子。光这一处改动,我的产品描述"无需编辑直接可用"率从 55% 升到了 75%。

按长度分批,不要按来源分批。 把输入按字数分组。50 字的产品描述和 500 字的博客开头不要走同一个 prompt——模型会把输出长度对齐到它在对话上下文里最先看到的那条。短文案一个 prompt,长文案另一个 prompt,同一批里别混。

先测 20 条样本。 拿数据集里 20 条有代表性的跑一下脚本。每条输出都读一遍。如果模型反复添加原文没有的产品功能,把 prompt 收紧。如果反复"换个词就算改完",把温度调高。在跑完 4000 条之前别信它,让它先过你的抽查。

SmolLM 1.7B 擅长什么——不擅长什么

老实清单,过去一年大概跑了 30 个客户项目:

做得好的:

  • 产品描述改写(那个 SaaS 客户的 4000 个页面)
  • Meta 标题和描述的 A/B 变体
  • 邮件标题变体
  • 付费社交的广告文案变体
  • 博客草稿的段落级意译
  • 语气切换:正式 ↔ 口语

做不好的:

  • 长内容生成(超过 400 字就会跑偏,连贯性断崖式下降)
  • 任何需要真实调研或事实的工作——模型会自信地编
  • 细腻的品牌声音——太小了,hold 不住复杂的声音简报
  • 非英语的多语言改写(多语言 benchmark 对 1.7B 模型算好的,但法文或日文改写质量比英文低几档)

心智模型:SmolLM 1.7B 是一个听话的初级文案编辑,能干但需要监督。它不是策略型写手。把它用在你本来要按 0.1 美元/字付给自由职业的高量低质活上,策略性写作留给更大的模型或人。

合规角度:内部推这个的理由

如果你要向安全或法务团队推这件事,谈话会比你想的简单。"我们调 OpenAI API"会触发供应商评审、数据处理协议、数据存储位置审计,对 NDA 下的内容基本就是一口回绝。"我们在笔记本上跑开源模型"是完全不同的对话。数据流图就是一个框。供应商评审就是一张一页纸。

我到现在在四家不同的公司谈过这个事,三家直接答应了。第四家要求只能用某台物理隔离的机器——也算答应,就是戏剧化了一点。

硬件小贴士

不需要 GPU。16GB 内存的 M1/M2/M3 MacBook 跑 1.7B 模型很轻松。16GB+ 内存的现代 Windows 笔记本也行(用 Windows 原生 Ollama 或 WSL2)。普通 Linux 小机器也够。

不能这么干的:8GB 内存且只用电池的笔记本。模型会同时吃掉你的内存和电池。如果你只有 8GB,凑合用 360M 模型,质量降一档。

真正的取舍

跑本地模型不是免费的。它吃掉你的安装时间、调试时间、笔记本的电、以及模型吐出 200 字改写但你只要 100 字时的耐心。你省下来的是钱、供应商风险、以及发现新用例时 API 成本慢慢渗血的痛。

对我对接的营销团队,平衡点大概在每月 5 万字改写量。低于这个,API 大概率是更好的答案。高于这个,本地赢在成本,隐私故事是白送的福利——等第一次有客户问"我们的内容会送到 OpenAI 吗"你就懂它的价值了。

从小做起。先改 50 个产品描述,看看质量能不能过你的标准。过了再放大。