Instructions to use TuWaveGod/Puker_Judge with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use TuWaveGod/Puker_Judge with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
| 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。扑克牌源图和训练数据不包含在本仓库中。 | |