Skip to content
Ottavia-LucaPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LLM_lab · 轻量大模型微调与本地翻译部署

基于 Qwen3-0.6B 的中英选词翻译实验,覆盖数据准备、LoRA/QLoRA 监督微调、验证选模、GGUF 量化及 CPU/CUDA 本地服务。模型通过兼容 OpenAI 的 HTTP 接口为 Translator 桌面应用提供翻译。

本仓库负责模型与评测流程;桌面应用由独立的 Translator 项目维护。本项目是小规模实验原型,仍有词义和语言识别错误,尚不能替代成熟翻译服务。

项目流程

词条与双向样例 → 分组划分与数据检查 → 原模型基线
                                      ↓
                         BF16 LoRA / NF4 QLoRA
                                      ↓
                         验证集选模 → 固定测试
                                      ↓
                     合并浮点权重 → BF16 GGUF
                                      ↓
                           Q8_0 / Q4_K_M
                                      ↓
                    CPU / CUDA 质量复测与 API 测速
                                      ↓
                            Translator 桌面应用
  • 数据与训练:词条分组隔离、跨集合去重、聊天模板、仅答案参与 loss、EOS 与 padding 检查。
  • 方案对照:固定主要训练超参数,对比 LoRA/QLoRA 和不同训练步数;根据验证集选择 checkpoint。
  • 部署评测:比较量化体积、翻译质量、CPU/GPU 生成速度及完整请求延迟,保留原始响应与运行参数。

实验结果

以下为本机已完成的实验,不同表格对应不同测量口径。

微调效果

同一固定测试集、提示与 BF16 推理设置:

模型 chrF2 参考匹配率 JSON Schema 合法率
原始 Qwen3-0.6B 38.88 0.00% 100%
LoRA checkpoint-100 73.17 58.06% 100%
QLoRA checkpoint-80 59.14 41.94% 100%

训练预算相同的100步实验中,QLoRA 峰值张量显存为 1.04 GiB,BF16 LoRA 为 1.64 GiB,降低约 36%;训练耗时分别为135.09秒和100.90秒。张量显存不等于整张GPU的总占用。这是单次对照,不代表所有模型和训练配置。

量化与后端复测

部署模型来自验证阶段选定的 LoRA100,不是 QLoRA adapter。

GGUF 格式 文件体积 CPU 测试 chrF2 CUDA 测试 chrF2
BF16 1142.68 MiB 73.17 未测
Q8_0 609.82 MiB 73.17 未测
Q4_K_M 378.33 MiB 72.33 69.00

Q4_K_M 比 BF16 文件小约 67%。CUDA 复测确认29/29层卸载到GPU;CPU/GPU有一条测试输出不同:fine-tuning 在CPU上译为“微调”,在GPU上复制原文。不能把后端切换视为答案完全等价。

常驻服务性能

同一Q4_K_M模型,20个开发输入各重复3轮;每端排除一次预热、单并发顺序请求、关闭跨请求前缀缓存,并启用JSON输出约束。

指标 CPU 4线程 CUDA
生成速度中位数 79.59 token/s 301.89 token/s
完整请求延迟中位数 496.12 ms 57.61 ms
完整请求延迟 P95 557.56 ms 69.40 ms

本轮GPU中位请求延迟降低约 88.4%。生成速度来自llama.cpp内部decode计时;完整请求延迟包含HTTP往返,不包含模型启动。两者不是同一指标,也不是首token延迟或并发吞吐量。

测试硬件:Intel i7-13700H、RTX 4060 Laptop 8GB。每个后端仅测一个会话,输出为短JSON,中位输出长度13 token;不代表长文本性能。CPU/GPU有两条开发输入输出不同,GPU均有退化,不能据此声称效果提升。详见API对照和token速度统计。

输出协议

{"type": "en", "translation": "配置"}

type表示原文语言:ch为中文、en为英文、other为其他语言或仅数字符号。中文译成英文,英文译成简体中文;缩写和不明代码保留原样,不展开全称。

完整system prompt、严格JSON解析、数据校验和评分实现见 scripts/translation.py。提示约定不保证模型始终遵守,例如other识别仍有失败案例。

快速启动本地服务

前提:已完成下方构建,并已有Q4 GGUF文件。 Git仓库不包含模型、虚拟环境、基座缓存或llama.cpp工具;新克隆不能直接运行本节命令,需先准备环境并生成或另行取得模型产物。

CPU服务:

tools/llama.cpp/build-cpu/bin/llama-server \
  --model outputs/gguf/qwen3-0.6b-translator-q4_k_m.gguf \
  --host 127.0.0.1 --port 8081 --ctx-size 512 --parallel 1 \
  --threads 4 --threads-batch 4 --jinja --reasoning off --perf

或者停止CPU服务后,在同一端口启动CUDA服务:

tools/llama.cpp/build-cuda/bin/llama-server \
  --model outputs/gguf/qwen3-0.6b-translator-q4_k_m.gguf \
  --host 127.0.0.1 --port 8081 --ctx-size 512 --parallel 1 \
  --threads 4 --threads-batch 4 --gpu-layers 99 \
  --jinja --reasoning off --verbosity 4 --perf \
  > outputs/translator-gpu-server.log 2>&1

保持服务终端运行,在另一个终端检查:

curl http://127.0.0.1:8081/health

返回{"status":"ok"}后即可连接。接口为http://127.0.0.1:8081/v1/chat/completions。Translator选择本地后端即可调用;独立客户端需发送本仓库的system prompt、关闭思考,设置温度0、最多256新token。服务仅监听本机。

复现环境

以下命令从仓库根目录执行。训练需要支持BF16的NVIDIA GPU;CPU推理无需GPU。

Python环境与基座缓存

已验证的训练环境为Python 3.12、PyTorch 2.7.1+cu128、Transformers 4.56.2、PEFT 0.17.1、TRL 0.23.1、bitsandbytes 0.47.0。完整依赖见 requirements.lock.txt。

uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python "torch==2.7.1" --index-url https://download.pytorch.org/whl/cu128
uv pip install --python .venv/bin/python -r requirements.lock.txt
uv pip check --python .venv/bin/python
source .venv/bin/activate

python -c 'from huggingface_hub import snapshot_download; snapshot_download("Qwen/Qwen3-0.6B", revision="c1899de289a04d12100db370d81485cdf75e47ca", cache_dir=".cache/huggingface/hub")'

首次下载需要网络;训练与评测使用固定revision的本地缓存。

llama.cpp构建

mkdir -p tools outputs/gguf
git clone https://github.com/ggml-org/llama.cpp.git tools/llama.cpp
git -C tools/llama.cpp checkout ecdd29e8b2076bb85da9e9ca7ee3d84264375bd1

cmake -S tools/llama.cpp -B tools/llama.cpp/build-cpu \
  -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=OFF \
  -DLLAMA_BUILD_TESTS=OFF -DLLAMA_OPENSSL=OFF
cmake --build tools/llama.cpp/build-cpu \
  --target llama-quantize llama-completion llama-server -j 4

GPU版本需要独立安装CUDA Toolkit,nvidia-smi可用不代表已安装nvcc。以下为本机CUDA 12.4与GCC13的构建配置:

nvcc --version
g++-13 --version

cmake -S tools/llama.cpp -B tools/llama.cpp/build-cuda \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_C_COMPILER=/usr/bin/gcc-13 \
  -DCMAKE_CXX_COMPILER=/usr/bin/g++-13 \
  -DCMAKE_CUDA_HOST_COMPILER=/usr/bin/g++-13 \
  -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=89 \
  -DLLAMA_BUILD_TESTS=OFF -DLLAMA_OPENSSL=OFF
cmake --build tools/llama.cpp/build-cuda \
  --target llama-completion llama-server -j 2

架构89对应本机RTX4060;其他GPU、CUDA与编译器组合需调整。已有失败构建缓存时,重新配置可加--fresh。CPU与CUDA构建目录相互独立。

数据、训练与选模

当前数据为 data/lexicon-v3,源词条位于 data/lexicon-source/entries-v3.jsonl。

划分 词条组 样本数
训练 141 307
验证 16 32
测试 16 31
开发 10 20

同一词条及双向样例留在同一划分。已有固定数据无需重新生成,生成脚本默认拒绝覆盖。

先运行离线检查,不启动模型训练:

python scripts/check_translation.py
python scripts/train_lora.py --self-check
python scripts/merge_adapter.py --self-check
python scripts/benchmark_gguf.py --self-check
python scripts/benchmark_translation_api.py --self-check

其中数据检查覆盖开发/训练/验证集的重复、答案loss mask和EOS,不读取测试集。训练配置为rank8、alpha16、all-linear、dropout0、batch1、梯度累积4、学习率1e-4、seed42、上下文512;QLoRA使用NF4、double quant和BF16计算。

python scripts/train_lora.py --max-steps 100
python scripts/train_lora.py --qlora --max-steps 100

训练完成会打印新产物目录,每20步保存候选。下面路径是本次实验的历史产物,不随Git分发,重跑时须替换为实际输出:

LORA_RUN=outputs/translation-lora-r8-tune-20261014T154325724789Z
python scripts/evaluate_translation.py --dataset validation \
  --adapter "$LORA_RUN/checkpoint-100"

选模依次比较Schema合法率、chrF2、语言标签正确率,同分选较早步数。项目比较过训练步数与LoRA/QLoRA方案,未进行学习率或rank的系统搜索。最终选择LoRA100、QLoRA80;部署使用LoRA100。冻结选择后测试:

python scripts/evaluate_translation.py --dataset test --final-test \
  --adapter "$LORA_RUN/checkpoint-100"

验证loss和自由生成指标分别记录;不根据测试集结果继续调参。

合并与量化

在原始浮点基座上合并adapter,使用FP32检查合并前后logits,再保存BF16完整权重;不直接把adapter合入NF4基座。

python scripts/merge_adapter.py --adapter "$LORA_RUN/checkpoint-100"

# 替换为上一步打印的新目录;此处为本次实验的历史目录。
MERGED_DIR=outputs/merged-20261014T161306200263Z
python scripts/check_merged.py --model "$MERGED_DIR"

使用独立CPU转换环境,避免改变训练环境依赖:

uv venv --python 3.12 .venv-gguf
uv pip install --python .venv-gguf/bin/python "torch==2.11.0" --index-url https://download.pytorch.org/whl/cpu
uv pip install --python .venv-gguf/bin/python -r docs/gguf-requirements.lock.txt
uv pip check --python .venv-gguf/bin/python

.venv-gguf/bin/python tools/llama.cpp/convert_hf_to_gguf.py \
  "$MERGED_DIR" \
  --outfile outputs/gguf/qwen3-0.6b-translator-bf16.gguf --outtype bf16

tools/llama.cpp/build-cpu/bin/llama-quantize \
  outputs/gguf/qwen3-0.6b-translator-bf16.gguf \
  outputs/gguf/qwen3-0.6b-translator-q8_0.gguf Q8_0

tools/llama.cpp/build-cpu/bin/llama-quantize \
  outputs/gguf/qwen3-0.6b-translator-bf16.gguf \
  outputs/gguf/qwen3-0.6b-translator-q4_k_m.gguf Q4_K_M

两种量化均从BF16源文件生成,不从Q8再次量化;已有产物无需重复转换。

质量评测与API测速

GGUF开发/验证评测默认使用CPU,GPU增加--gpu:

python scripts/evaluate_translation.py --dataset dev --gpu \
  --gguf outputs/gguf/qwen3-0.6b-translator-q4_k_m.gguf

python scripts/evaluate_translation.py --dataset validation \
  --gguf outputs/gguf/qwen3-0.6b-translator-q4_k_m.gguf

--gpu选择build-cuda并要求日志确认全部层卸载,否则报错。固定测试复测使用--dataset test --final-test;这仍是原测试集,不增加独立泛化证据。CLI每次重新加载模型,进程耗时不能当作常驻API延迟。

按“快速启动”启动服务后,使用已激活的Python环境测速:

# CPU服务运行时
python scripts/benchmark_translation_api.py --backend cpu --port 8081

# 换为GPU服务后;日志必须来自正在测试的服务
python scripts/benchmark_translation_api.py --backend gpu --port 8081 \
  --server-log outputs/translator-gpu-server.log

两条命令分开运行,保持模型、线程数、上下文和输入一致。若同时保留两端服务,将GPU服务及测速端口改为8082。脚本输出新结果目录,保存完整响应、请求延迟和引擎timings;生成速度可从response.timings.predicted_per_second统计。GPU模式检查启动日志,CPU后端标签由操作者确保。

目录与产物管理

scripts/                     数据准备、训练、评测、合并与API测速
data/lexicon-v3/              当前固定语料划分
data/lexicon-source/          各版本词条源数据
data/lexicon/、lexicon-v2/    历史翻译任务数据
docs/                        实验记录、结果摘要与依赖快照
requirements.lock.txt        训练环境依赖
outputs/                     adapter、完整模型、GGUF和原始评测(忽略)
.cache/                      基座缓存(忽略)
.venv/、.venv-gguf/           Python环境(忽略)
tools/llama.cpp/              固定版本外部工具(忽略)

Git保存代码、词条语料与docs中的结果摘要;模型和完整原始记录需另行备份。旧OPUS短句探索、已应用的Translator补丁和清理流水记录归档至本地outputs/cleanup-archive-20261018,不随Git发布。本仓库尚未提供可下载的微调权重,不能仅凭源码克隆恢复历史产物。

局限与实验记录

语料主要由助手编写,未经过独立专家审核。固定测试仅31条,分组隔离不能保证完全消除语义相近样例的影响;参考字符串匹配不等于语义准确率,chrF2也不能替代人工检查。当前仍存在多义词遗漏、术语错译和other识别错误。

量化和后端复测沿用原测试集,CPU/GPU输出也有差异。服务性能来自短输出单并发测试,尚未测量TTFT、并发吞吐量或GPU显存,也没有多seed训练和多会话性能复测。

历史记录描述的是当时实验状态,当前执行入口以本README为准。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages