mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 17:24:32 +02:00
fix(caption): safetensors-only downloads, model load fixes, UI default, prefill tests
- Add use_safetensors=True to all 16 model from_pretrained calls to avoid downloading redundant .bin files alongside safetensors - Add device property to JoyTag VisionModel so move_model can relocate it to CUDA (fixes 'ViT object has no attribute device') - Fix Pix2Struct dtype mismatch by casting float inputs to model dtype while preserving integer tensor types - Patch AutoConfig.register with exist_ok=True during Ovis loading to handle duplicate aimv2 registration on model reload - Detect Qwen VL fine-tune architecture from config model_type instead of repo name, fixing ToriiGate and similar third-party fine-tunes - Change UI default task from Short Caption to Normal Caption, and preserve it on model switch instead of resetting to Use Prompt - Add dual-prefill testing across 5 VQA test methods using a shared _check_prefill helper - Fix pre-existing ruff W605 in strip_think_xml_tags docstring
This commit is contained in:
@@ -44,6 +44,9 @@ OCR_TEST_IMAGE = 'models/Reference/HiDream-ai--HiDream-I1-Fast.jpg'
|
||||
# Bracket test image (must produce tags with parentheses, e.g. pokemon_(creature))
|
||||
BRACKET_TEST_IMAGE = 'models/Reference/SDXL-Flash_Mini.jpg'
|
||||
|
||||
# Custom prefill text used for dual-prefill verification across tests
|
||||
CUSTOM_PREFILL = "Vlado is the best, and I'm looking at his robot which"
|
||||
|
||||
|
||||
class CaptionAPITest:
|
||||
"""Test harness for Caption API endpoints."""
|
||||
@@ -257,6 +260,20 @@ class CaptionAPITest:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _check_prefill(self, base_request: dict, test_label: str):
|
||||
"""Re-run a VQA request with custom prefill and verify it appears in output."""
|
||||
req = {**base_request, 'prefill': CUSTOM_PREFILL, 'keep_prefill': True}
|
||||
data = self.post('/sdapi/v1/vqa', req)
|
||||
if 'error' in data:
|
||||
self.log_skip(f"{test_label} prefill: API error")
|
||||
elif data.get('answer') and not self.is_error_answer(data['answer']):
|
||||
if data['answer'].startswith(CUSTOM_PREFILL):
|
||||
self.log_pass(f"{test_label} prefill: output starts with custom prefill")
|
||||
else:
|
||||
self.log_fail(f"{test_label} prefill: expected '{CUSTOM_PREFILL[:30]}...' but got '{data['answer'][:30]}...'")
|
||||
else:
|
||||
self.log_fail(f"{test_label} prefill: empty/error")
|
||||
|
||||
def get_model_family(self, model_name):
|
||||
"""Determine model family from model name."""
|
||||
name_lower = model_name.lower()
|
||||
@@ -1138,6 +1155,9 @@ class CaptionAPITest:
|
||||
if results['Long Caption'] < results['Normal Caption']:
|
||||
self.log_info(f"NOTE: Long ({results['Long Caption']}) < Normal ({results['Normal Caption']}); LLM may interpret length prompts differently per run")
|
||||
|
||||
# Dual prefill: re-run 'Normal Caption' with custom prefill
|
||||
self._check_prefill({'image': self.image_b64, 'question': 'Normal Caption'}, "different_prompts")
|
||||
|
||||
# =========================================================================
|
||||
# TEST: POST /sdapi/v1/vqa - Annotated Image
|
||||
# =========================================================================
|
||||
@@ -1256,6 +1276,9 @@ class CaptionAPITest:
|
||||
else:
|
||||
self.log_fail("Custom system prompt returned empty answer")
|
||||
|
||||
# Dual prefill: re-run with custom system prompt + prefill
|
||||
self._check_prefill({'image': self.image_b64, 'question': 'describe the image', 'system': custom_system}, "system_prompt")
|
||||
|
||||
# =========================================================================
|
||||
# TEST: POST /sdapi/v1/vqa - Invalid Inputs
|
||||
# =========================================================================
|
||||
@@ -1328,6 +1351,9 @@ class CaptionAPITest:
|
||||
else:
|
||||
self.log_skip("Detection prompt may require specific model")
|
||||
|
||||
# Dual prefill: re-run 'Use Prompt' with custom prefill
|
||||
self._check_prefill({'image': self.image_b64, 'question': 'Use Prompt', 'prompt': custom_prompt}, "prompt_field")
|
||||
|
||||
# =========================================================================
|
||||
# TEST: POST /sdapi/v1/vqa - Generation Parameters
|
||||
# =========================================================================
|
||||
@@ -1434,6 +1460,9 @@ class CaptionAPITest:
|
||||
else:
|
||||
self.log_fail("top_k/top_p returned empty/error")
|
||||
|
||||
# Dual prefill: re-run temp=0 request with custom prefill
|
||||
self._check_prefill({'image': self.image_b64, 'question': 'describe the image briefly', 'temperature': 0.0}, "generation_params")
|
||||
|
||||
# =========================================================================
|
||||
# TEST: POST /sdapi/v1/vqa - Sampling Controls
|
||||
# =========================================================================
|
||||
@@ -1500,6 +1529,9 @@ class CaptionAPITest:
|
||||
else:
|
||||
self.log_fail("num_beams=4 returned empty/error")
|
||||
|
||||
# Dual prefill: re-run greedy request with custom prefill
|
||||
self._check_prefill({'image': self.image_b64, 'question': 'describe the image', 'do_sample': False}, "sampling")
|
||||
|
||||
# =========================================================================
|
||||
# TEST: POST /sdapi/v1/vqa - Thinking Mode
|
||||
# =========================================================================
|
||||
|
||||
Reference in New Issue
Block a user