Puker_Judge

Puker_Judge 是基于 HuggingFaceTB/SmolVLM2-2.2B-Instruct 微调的两阶段扑克牌拼接候选判断模型。

本仓库发布的是两个 PEFT LoRA adapter,而不是重复上传两份基础模型:

  • binary_adapter/:判断一张已经拼好的候选牌面是 VALID 还是 INVALID
  • rank_adapter/:从同一组碎片产生的 2–4 个几何可行候选中选择图案最连贯的一个。
  • processor/:训练时使用的 SmolVLM2 processor 和 tokenizer。

第二阶段由第一阶段权重初始化后继续训练,但推理时不要同时叠加两个 adapter。做单候选判断时加载 binary_adapter,做多候选选择时加载 rank_adapter

能做什么

这两个模型只负责视觉判断,不负责枚举几何拼法,也不直接输出机械臂坐标:

  1. CV/几何算法检测碎片并枚举能够填满目标矩形的候选拼法;
  2. 候选只有一个时,可用 binary_adapter 判断其图案是否合理;
  3. 候选有 2–4 个时,用 rank_adapter 选择最佳候选;
  4. 候选超过4个时,先去重或使用 binary_adapter 逐张筛选到 Top-4,再交给 rank_adapter

安装

BF16:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

在 Linux x86-64 NVIDIA GPU 上使用 bitsandbytes INT4:

pip install -r requirements-int4.txt

INT4主要建议用于 rank_adapter。实测中,rank adapter 在Joker三候选顺序 轮换上保持了BF16的判断;但 binary adapter 的一个测试集VALID样本在INT4下翻转 成了INVALID。因此单候选二分类默认应使用BF16,除非已经在自己的数据上重新验证 INT4准确率。

输入图像规范

单候选二分类

输入一张透视矫正后的完整候选牌面:

  • 推荐规范尺寸:600×360 像素,对应物理尺寸比例 100:60
  • 牌面应紧密裁剪,尽量删除桌面、机械臂、阴影和大面积背景;
  • 所有碎片必须位于同一个目标矩形内;
  • 整张牌旋转180°仍视为同一个正确答案;
  • 不要添加候选编号或多选题边框。

多候选排序 board

模型实际接收的是一张包含所有选项的 board,而不是多张独立图片。

  • board:1280×820
  • 固定2列×2行布局;
  • 选项数必须是 2、3或4,不能超过4;
  • 每个候选先规范化为 600×360
  • 标签必须为连续数字 1, 2, 3, 4,放在候选图外部;
  • 少于4个选项时,未使用的格子保持空白;
  • 所有候选必须来自同一张牌、同一组碎片,并且在几何上都可行;
  • 各候选应使用相同的裁剪、尺度、背景和成像处理,避免让模型利用无关差异。

infer_rank.py 可以接收2–4张候选图并自动生成符合训练格式的 board。

Prompt

建议保持训练时的英文 prompt,不要随意改写。

二分类 prompt

Judge whether this geometrically assembled playing card has coherent rank, suit, border, portrait, symbols, and continuous artwork. A whole-card 180-degree rotation is valid. Answer VALID or INVALID only.

输出只能是:

VALID

或:

INVALID

多候选排序 prompt

下面的 {labels} 要根据选项数生成,例如3个候选就是 1, 2, 3

All displayed candidates are geometrically valid reconstructions made from the same playing-card pieces. Select the candidate whose rank, suit, outer border, portrait, symbols, and line artwork form one coherent original playing card. A whole-card 180-degree rotation is equivalent. The available labels are {labels}. Answer with one label only.

输出只能是一个候选编号。

使用方法

单独判断一个候选的正误

BF16:

python infer_binary.py candidate.jpg

INT4 NF4(实验性,binary默认推荐BF16):

python infer_binary.py candidate.jpg --int4

输出示例:

{
  "prediction": "VALID",
  "raw_output": "VALID",
  "quantization": "int4-nf4"
}

从2–4张候选图中选择

脚本会自动生成 candidate_board.jpg

python infer_rank.py \
  candidate_1.jpg \
  candidate_2.jpg \
  candidate_3.jpg \
  --board-output candidate_board.jpg \
  --int4

输出示例:

{
  "selected_label": 2,
  "selected_file": "/path/to/candidate_2.jpg",
  "candidate_count": 3
}

如果已经自行生成了 board:

python infer_rank.py \
  --board-image candidate_board.jpg \
  --candidate-count 3 \
  --int4

直接用 Transformers + PEFT 加载

from pathlib import Path

import torch
from huggingface_hub import snapshot_download
from peft import PeftModel
from transformers import AutoModelForImageTextToText, AutoProcessor

repo_dir = Path(snapshot_download("TuWaveGod/Puker_Judge"))
processor = AutoProcessor.from_pretrained(repo_dir / "processor")
base = AutoModelForImageTextToText.from_pretrained(
    "HuggingFaceTB/SmolVLM2-2.2B-Instruct",
    torch_dtype=torch.bfloat16,
).to("cuda")
model = PeftModel.from_pretrained(
    base,
    repo_dir / "rank_adapter",
).eval()

训练信息

  • 基础模型:SmolVLM2-2.2B-Instruct;
  • LoRA:rank 16,alpha 32,dropout 0.05;
  • 最大图像长边:1280;
  • 最大文本长度:2048;
  • rank训练场景:18,000;
  • rank验证/测试场景:各1,000;
  • binary训练样本:33,300;
  • binary验证/测试样本:各1,850;
  • 使用52张标准扑克牌资产,不包含大小王;
  • 训练样本包括普通随机、偏心平行四边形、中心双切、全等对称和近似对称困难样本。

已做的实拍检查

模型曾在训练集外的 Joker 实拍候选上进行顺序轮换检查。正确候选分别位于 1、2、3号位置时,rank adapter 的原始生成结果分别为1、2、3。使用 bitsandbytes INT4 NF4 后结果仍保持一致。该结果只是一组定性检查,不应视为完整 统计评测。

限制

  • rank adapter 只训练过最多4个选项,禁止直接构造超过4项的大型 board;
  • binary adapter 对INT4量化更敏感,单候选判断默认使用BF16;
  • board内不存在正确答案时,模型仍会被迫选择一个编号;
  • 透视畸变、反光、遮挡、碎片间隙或候选缩放不一致可能影响判断;
  • 模型不保证识别所有未见过的牌面和印刷风格;
  • 输出是视觉判断,不是几何证明,也不是机械臂控制策略;
  • 建议将正确候选轮换到不同board位置重复2–3次,并对原始生成编号投票,以减小位置偏置。

License

本模型基于 Apache-2.0 许可的 SmolVLM2-2.2B-Instruct。扑克牌源图和训练数据不包含在本仓库中。

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for TuWaveGod/Puker_Judge