--- license: apache-2.0 base_model: HuggingFaceTB/SmolVLM2-2.2B-Instruct library_name: peft pipeline_tag: image-text-to-text tags: - smolvlm2 - peft - lora - visual-ranking - playing-card - puzzle language: - en --- # Puker_Judge `Puker_Judge` 是基于 [`HuggingFaceTB/SmolVLM2-2.2B-Instruct`](https://huggingface.co/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: ```bash python -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` 在 Linux x86-64 NVIDIA GPU 上使用 bitsandbytes INT4: ```bash 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 ```text 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. ``` 输出只能是: ```text VALID ``` 或: ```text INVALID ``` ### 多候选排序 prompt 下面的 `{labels}` 要根据选项数生成,例如3个候选就是 `1, 2, 3`: ```text 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: ```bash python infer_binary.py candidate.jpg ``` INT4 NF4(实验性,binary默认推荐BF16): ```bash python infer_binary.py candidate.jpg --int4 ``` 输出示例: ```json { "prediction": "VALID", "raw_output": "VALID", "quantization": "int4-nf4" } ``` ### 从2–4张候选图中选择 脚本会自动生成 `candidate_board.jpg`: ```bash python infer_rank.py \ candidate_1.jpg \ candidate_2.jpg \ candidate_3.jpg \ --board-output candidate_board.jpg \ --int4 ``` 输出示例: ```json { "selected_label": 2, "selected_file": "/path/to/candidate_2.jpg", "candidate_count": 3 } ``` 如果已经自行生成了 board: ```bash python infer_rank.py \ --board-image candidate_board.jpg \ --candidate-count 3 \ --int4 ``` ## 直接用 Transformers + PEFT 加载 ```python 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。扑克牌源图和训练数据不包含在本仓库中。