泰语教学塔:我们关于 TowerInstruct LoRA 的计划

posted in: Uncategorized | 0

3DN,我们已经在本地工作站GPU(RTX 3090)上运行本地推理,用于家庭网站机器翻译和混合AI工程。大量的EN→NL和EN→ZH草稿通过Ollama的Tower进行;泰语一直是薄弱环节,所以今天我们依赖Typhoon进行TH。下一步不是“购买更多的API”——而是在我们自己的屋檐下,在相同的基础设施上进行有意的LoRA实验,以实现数字主权和降低长期的token成本

这篇文章是公共计划:我们训练什么,为什么选择那个基础模型,我们如何保持生产安全,以及Unbabel的工作如何融入其中。下面的片段是实验室的形状——不是一个粘贴和遗忘的食谱。

为什么要有LoRA?

对数十亿参数的翻译模型进行全精调很昂贵且容易过拟合。LoRA(低秩适配器)在冻结的基础上训练一组薄矩阵。对于已经托管Tower权重的桌面来说,这是正确的学习曲线:可衡量的EN→TH收益,一个我们可以发布的Hugging Face适配器,以及如果我们想要一个专门的Ollama插头,稍后可以选择合并。

我们训练Ollama日常使用的GGUF blob。训练使用Hugging Face / PEFT风格的权重;服务可以保持在当前的Tower-Plus Q4路径,直到评估结果另行通知。

# 精神模型:冻结基础,训练薄适配器
# ΔW ≈ B @ A  with rank r << d_model
# 只有A、B(和可能偏置)获得梯度。

from peft import LoraConfig, get_peft_model, TaskType

lora = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],  # 小规模开始;如果欠拟合则扩展
    lora_dropout=0.05,
    bias="none",
    task_type=TaskType.CAUSAL_LM,
)
# model = get_peft_model(base_model, lora)
# model.print_trainable_parameters()  # 预期可训练的比例为~0.1–1%

基础模型:TowerInstruct-7B v0.2

社区指导(和我们自己的阅读)指出从TowerInstruct开始,而不是一个通用的聊天LLM。这个系列是为翻译形状的提示构建的——与我们已经在桌面上的相同模式。

我们正在安装Unbabel/TowerInstruct-7B-v0.2作为第一个训练基础:

  • 7B适合QLoRA在台式机3090上舒适运行,有迭代的空间。
  • v0.2比v0.1更干净的instruct/MT行为。
  • 13B或Tower-Plus-9B只有在7B配方有效后才考虑——更多容量,更慢的循环。

Unbabel 的 Tower 产品线可在 unbabel.com 查看。公共权重:Hugging Face Unbabel/TowerInstruct-7B-v0.2

# 在本地工作站上的实验室布局(HF 权重,不是 Ollama GGUF)
# .../tower-lora/
#   modelsTowerInstruct-7B-v0.2   # safetensors 分片
#   datasetsen-th                 # jsonl 对
#   adaptersen-th-r16             # PEFT 输出
#   out

# 在构建主机上下载阶段,然后通过局域网复制(多 GB,稍后离线训练):
python -c "from huggingface_hub import snapshot_download; 
snapshot_download('Unbabel/TowerInstruct-7B-v0.2', 
local_dir='/var/tmp/hf-models/TowerInstruct-7B-v0.2')"

数据形状(程序员关心模式)

一行,一个任务。与我们已经在生产 MT 中使用的提示风格相匹配,以便训练≈服务:

{
  "instruction": "将以下英文源文本翻译成泰语。",
  "input": "Every voter deserves a market.",
  "output": "ผู้มีสิทธิเลือกตั้งทุกคนสมควรได้รับตลาด"
}
# Tiny loader sketch — holdout 是神圣的
import json
from pathlib import Path

def load_jsonl(path: Path):
    rows = []
    for line in path.read_text(encoding="utf-8").splitlines():
        if line.strip():
            rows.append(json.loads(line))
    return rows

def split_holdout(rows, frac=0.1, seed=7):
    import random
    rng = random.Random(seed)
    idx = list(range(len(rows)))
    rng.shuffle(idx)
    n = max(1, int(len(rows) * frac))
    hold = {idx[i] for i in range(n)}
    train = [rows[i] for i in idx if i not in hold]
    test  = [rows[i] for i in idx if i in hold]
    return train, test

# 优先:我们的 EN 桌面副本 + Typhoon 草稿 + 轻量级人工黄金编辑
# 避免:未编辑的大批量 MT 汤,HTML 碎片,混合双语行

我们如何进行工作

  1. 在本地工作站上安装 HF 基础.../tower-lora/models/ 下的完整 safetensors 树(下载阶段在我们的构建主机上进行,然后通过局域网复制)。
  2. 数据优先于排名 — 几百到几千个干净的 EN→TH 对;永远保留 ~10%。
  3. 训练 QLoRA — 排名 8–16,短上下文,一次在 3090 上进行一个繁重任务(卸载竞争的 Ollama 模型)。
  4. 诚实评估 — 基于 Tower vs LoRA(以及稍后的 Typhoon);chrF/BLEU 作为指南,人类用于名称和产品术语。第一个保留表在上面。
  5. 发布获胜时 — Hugging Face 适配器卡;只有那时才合并→GGUF / 可选的 local workstation-tower-th 标记。
# QLoRA 加载草图(4位基础 + LoRA)——适合 3090
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch

bnb = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

base_id = r"…/tower-lora/modelsTowerInstruct-7B-v0.2"
tok = AutoTokenizer.from_pretrained(base_id, use_fast=True)
model = AutoModelForCausalLM.from_pretrained(
    base_id,
    quantization_config=bnb,
    device_map="auto",
    torch_dtype=torch.bfloat16,
)
# 然后 get_peft_model(model, lora_config) 和 Trainer / 自定义循环
# 我们已经使用的生产 MT 提示形状 (训练应该押韵)
def tower_prompt(en: str, lang_name: str = "Thai") -> str:
    return (
        f"将以下英文源文本翻译成 {lang_name}.n"
        f"英文: {en.strip()}n"
        f"{lang_name}:n"
    )

# 规则,直到 LoRA 胜出:
#   NL/ZH  -> 本地工作站塔 (Tower-Plus)
#   TH     -> 本地 Typhoon-translate
#   判断 / SEO -> 弗伦德 Grok (不是批量 MT)
# 装运门:永远不要相信感觉
def better_than_baseline(scores: dict) -> bool:
    # scores = {"tower": chrF, "lora": chrF, "typhoon": chrF}
    return scores["lora"] > scores["tower"] + 0.5  # 剩余利润待定
# 如果不比 baseline 好:保持 Typhoon 在生产中;LoRA 留在实验室

生产 MT 政策保持双轨制,直到评估结果另行规定:NL/ZH 使用 Tower,TH 使用 Typhoon,判断使用 Frontier Grok — 不用于批量翻译。

成功的表现

  • 在本地工作站上可复现的训练脚本和数据集模式。
  • 一个在我们的泰语测试集上击败库存 TowerInstruct 的适配器,而不破坏我们稍后添加的配对。
  • 一个 Hugging Face 卡片,其他人(和未来的我们)可以在相同的基础上使用 PEFT。
  • 没有浪漫:如果 Typhoon 仍然获胜,TH 生产将继续使用 Typhoon。
# 训练后 — 我们在磁盘上期望的内容
# adapters/en-th-r16/
#   adapter_config.json
#   adapter_model.safetensors
#   README.md   # 基础 ID、配对、r、数据大小、许可证、评估表

计算和操作

这是我们控制的金属上的托管托管和实验室计算 — 与混合编码代理和本地 Flux 拇指相同的理念。长时间会话仍然受益于导演模型上的仔细提示缓存会话连续性;LoRA 作业本身是一个有界 GPU 批处理,不是一个始终在线的 API。

在家庭资金方面,同样的诚实原则适用:虚拟信用和DutchBud / 金融科技轨道只有在国家符合承诺时才能发挥作用。翻译适配器只有在评估与卡片匹配时才会“出货”。

# 3090 上的一个繁重任务 - 不要同时运行 train + Flux + Ollama-14B
# (操作清单,不是诗歌)
# 1) 停止竞争 GPU 消费者
# 2) 训练 QLoRA
# 3) 写适配器
# 4) 释放 VRAM,恢复 Ollama 桌面插槽

状态 – 第一个实验室数据(测试,非生产)

第一个 QLoRA 适配器已上盘。训练集:110 个精选 EN→TH 对;留出:20 行未见数据。配方:TowerInstruct-7B-v0.2 基础,在 q/k/v/o 上排名 r=16,ChatML 提示,3 个时代,训练损失 ≈ 1.77 (~3.5 分钟后在单台桌面 3090 上加载权重)。

留出自动评分(sacrebleu 语料库 BLEU / chrF,贪婪解码,EOS 停止):

模型 BLEU chrF
基础 TowerInstruct-7B-v0.2 (4-bit) 2.06 14.54
基础 + EN→TH LoRA r16 2.88 16.22
Delta +0.82 +1.68

冷读:适配器以微弱优势击败了这个微小的留出集中的库存塔。绝对分数仍然很低 – 基础在我们的泰国语上表现不佳,110 行是一个管道证明,不是生产语料库。我们根据这些数据关闭家庭网站的泰国 MT。计划中的船闸仍然有效:LoRA 只有在留出集 + 人类审查在更大的黄金集上说时才会替换 Typhoon。

我们证明了:QLoRA 训练 → PEFT 适配器保存 → 在同一工作站堆栈上使用 BLEU/chrF 评估基础与适配器,在 HF 权重树本地化后脱机。下一个实验室步骤是更多的 EN→TH 黄金(以及谨慎的 Typhoon 草稿 + 编辑),而不是浪漫的声明。

进一步阅读:Unbabel · Hugging Face 上的 TowerInstruct-7B-v0.2.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注