多模态微调实战(06):全量训练的后台、断点与监控
演示集跑通后,才进入全量。全量意味着:时间以「天」计、必须可中断、必须可续训、必须能看懂进度。这一篇讲长时训练的运维细节。 这是「多模态微调实战」的第 06 篇。从「几十分钟」跨到「数天」,运维方式要随之升级。 一、规模与时间预期 项目 量级 训练样本 约 37 万 验证样本 约 4 万 epoch 3(可调) 单卡 16GB 常见要数天;具体取决于分辨率、I/O、实现细节 显存 约 9~11GB 量级(冻结 ViT + LoRA) 不要相信「一定 30 小时」这种绝对数字;以你机器上稳定后的 s/it 估算: 1剩余小时 ≈ 剩余 step × 每 step 秒数 / 3600 二、启动方式:前台 vs 后台前台适合调试: 1bash script/train_lora_full.sh 关掉终端,训练一般也会停。 后台(推荐)1bash script/train_lora_full_bg.sh 典型实现要点: nohup ... & 写入日志; 记录 PID; 提供 status / stop 子命令。 ...
YOLO 目标检测实战(04):验证与预测
目标:用训练得到的 best.pt 做一次正式 val,再在样例图上 predict,确认微调权重确实可用、加载路径无误。 这是「YOLO 目标检测实战」的第 04 篇。完整目录见 00 · 系列导读。 一、前置条件 已有 runs/train/coco128/weights/best.pt(见 03 · 短训); 本地数据 yaml 仍在:data/datasets/coco128.local.yaml。 二、执行容器内: 1bash scripts/03_val_test.sh 脚本分两步。 1. Val1234567yolo detect val \ model=/workspace/runs/train/coco128/weights/best.pt \ data=/workspace/data/datasets/coco128.local.yaml \ device=0 \ project=/workspace/runs/val \ name=coco128 \ exist_ok=True 输出目录示例: 1234runs/val/coco12...
多模态微调实战(05):微调前后的评测对比
没有评测的微调,只是「loss 在下降」。对 OCR,建议至少同时看三个指标:完全匹配、字符级准确率、编辑距离。这一篇讲怎么把基座和 LoRA 摆到同一把尺子下对比。 这是「多模态微调实战」的第 05 篇。评测是决定「要不要投入全量训练时间」的依据。 一、评测原则 同一验证集、同一提示词、同一解码参数; 先评基座,再评 LoRA(或合并后模型); 指标脚本与业务规则一致(是否忽略空格、大小写等要事先约定)。 二、指标定义 指标 含义 Exact Match 预测字符串与标签完全一致的比例 Character Accuracy 基于编辑距离的字符级正确率均值 Avg Edit Distance 平均 Levenshtein 距离(越小越好) 伪代码直觉: 12exact = mean(pred == label)char_acc = mean(1 - edit_distance(pred, label) / max(len(label), 1)) 三、推荐流程3.1 基座推理用 swift infer(或封装脚本)对验证 JSONL 批量推理,输出...
RustInPractice TUI(05):多窗口与桌面行为
多窗口 UI 的核心不是同时创建多个窗口,而是让前后层级、点击激活、拖动和关闭都由 Desktop 统一维护。desktop_showcase 用三个重叠的非模态窗口展示这一点。 对应 turbo-vision/desktop_showcase。截图来自实际运行状态,最晚加入的窗口位于最前。 建立层级窗口依次加入 Desktop,后加入的窗口在初始状态位于前方。每个窗口的文本 View 只关心客户区,窗口移动、激活和关闭交给框架。 12345678910app.desktop.add(Box::new(make_window( Rect::new(4, 2, 44, 12), "Window 1 - Background", "Non-modal window.",)));app.desktop.add(Box::new(make_window( Rect::new(32, 4, 74, 15), "Window 3 - Foreground", "Topmost ...
RustInPractice TUI(04):列表、焦点与选择反馈
列表控件把“当前选择”从一串散落的按键判断中抽离出来。ListBox 负责导航和滚动,应用只在收到选择命令时读取选中项并决定下一步。 对应 turbo-vision/list_widgets。截图展示了可用方向键、翻页键和 Enter 操作的初始列表。 数据与选择命令列表由控件持有项目,并在 Enter 确认时发出专用命令。这样事件循环不需要自行维护索引。 1234567const CMD_LIST_SELECT: u16 = 101;let mut listbox = ListBoxBuilder::new() .bounds(Rect::new(4, 3, 36, 16)) .on_select_command(CMD_LIST_SELECT) .build();listbox.set_items(vec!["Rust".into(), "C++".into(), "Python".into()]); 事件顺序绘制时需要同时画 Desktop、ListBox 与状态栏。收到普通键盘事件后...
RustInPractice TUI(03):菜单、状态栏与命令路由
菜单、快捷键和状态栏不应各自执行业务逻辑。它们都应转成统一命令,再由一个边界明确的分发点处理。menu_status 演示了这条链路。 对应 turbo-vision/menu_status。启动时的 About 对话框展示了菜单和状态栏都已绘制。 定义命令内置命令如 CM_NEW、CM_OPEN 和 CM_QUIT 可直接使用;应用自己的命令应避开内置范围。 12345678const CMD_ABOUT: u16 = 100;let help_menu = SubMenu::new( "~H~elp", Menu::from_items(vec![MenuItem::with_shortcut( "~A~bout", CMD_ABOUT, 0, "F1", 0, )]),); 单一分发点事件循环先把 Ctrl-N、Ctrl-O、Alt-X 映射为 Command 事件,再依次交给菜单栏和状态栏处理,最后只在 handle_command 中改变应用状态或打开对话框。 123...
RustInPractice TUI(02):模态表单与 UI 状态
表单的难点不是画两个输入框,而是让输入状态在控件和提交逻辑之间保持一致。dialog_form 用模态 Dialog 暂时接管事件循环,并用共享数据保存输入。 对应 turbo-vision/dialog_form。截图中的姓名和邮箱均为 demo 固定示例数据。 状态归属InputLine 接收 Rc<RefCell<String>>。Rc 允许输入框和提交代码共同持有同一份字符串,RefCell 把借用检查放到运行时。这个组合只适合单线程 UI 状态;跨线程更新应使用消息通道或同步原语。 12345678let name_data = Rc::new(RefCell::new(String::from("Alice")));dialog.add(Box::new( InputLineBuilder::new() .bounds(Rect::new(14, 3, 44, 3)) .max_length(28) .data(Rc::clone(&name_data)) ...
RustInPractice TUI(01):终端窗口与事件循环
终端 UI 不是把 println! 拼成界面,而是维护一组 View,并在绘制、输入和命令之间循环。这个番外使用 turbo-vision 的 Rust 实现,从一个可关闭的窗口开始。 对应 turbo-vision/hello_window。以下截图来自 Docker 中实际运行的 100x30 终端帧。 最小结构Application::new() 初始化终端和 Desktop。窗口由 WindowBuilder 创建,再向其中加入 Label 和 Button。Rect::new(x1, y1, x2, y2) 使用的是两个对角点,不是宽高。 1234567891011let mut app = Application::new()?;let mut window = WindowBuilder::new() .bounds(Rect::new(15, 5, 65, 16)) .title("Hello Turbo Vision") .build();window.add(Box::new(LabelBuilder::new...
YOLO 目标检测实战(03):COCO128 短训
目标:在 COCO128(128 张训练图)上对 s 档模型做一次短训,走通完整训练流水线。这一阶段指标不是重点——数据集太小,数字本来就会抖——可复现和产物路径清晰才是要拿到手的东西。 这是「YOLO 目标检测实战」的第 03 篇。完整目录见 00 · 系列导读。 一、数据配置训练使用本地 yaml:data/datasets/coco128.local.yaml。要点: path 固定为容器内 /workspace/data/datasets/coco128; train / val 均指向 images/train2017(COCO128 官方小集常见写法); 含 COCO 80 类 names;去掉会触发联网下载的 download 字段。 这样即使训练时断网,也不会再去拉 zip。 二、执行容器内(GPU 空闲): 1bash scripts/02_train_coco128.sh 默认超参(可按显存调整): 参数 默认值 imgsz 640 epochs 5 batch 16 workers 4 device 0 ...
多模态微调实战(04):小规模 LoRA 试跑,先证明流程可用
在上全量之前,先用 两千级样本 把 LoRA 跑通。这一步的目标不是刷榜,而是回答三个问题:命令能不能跑完?显存是否稳定?验证指标有没有「方向正确」的提升? 这是「多模态微调实战」的第 04 篇。先小后大的「小」,就在这一篇。 一、训练命令骨架核心是 swift sft。下面是一组在约 16GB 单卡上验证过的参数思路: 1234567891011121314151617181920212223242526272829303132PYTORCH_ALLOC_CONF=expandable_segments:True \IMAGE_MAX_TOKEN_NUM=512 \MAX_PIXELS=802816 \CUDA_VISIBLE_DEVICES=0 \swift sft \ --model /workspace/model/Qwen3-VL-4B-Instruct \ --dataset /workspace/dataset/ocr_plate/train.jsonl \ --val_dataset /workspace/dataset/ocr_plate/val....















