diff --git a/nodes/qwenvl/video_node.py b/nodes/qwenvl/video_node.py index 36cd7be..d6b9620 100644 --- a/nodes/qwenvl/video_node.py +++ b/nodes/qwenvl/video_node.py @@ -1,6 +1,7 @@ # QwenVL Video Analyzer Node import os +import random import numpy as np import torch import gc @@ -67,6 +68,8 @@ class QwenVLVideoNode: "temperature": ("FLOAT", {"default": 0.7, "min": 0.1, "max": 1.0, "tooltip": "Sampling temperature (lower = more focused)"}), "keep_model_loaded": ("BOOLEAN", {"default": True, "tooltip": "Keep model in memory for faster subsequent runs"}), "use_flash_attention": ("BOOLEAN", {"default": False, "tooltip": "Use Flash Attention 2 for better speed and memory (requires flash-attn package)"}), + "seed": ("INT", {"default": -1, "min": -1, "max": 0xffffffffffffffff, "tooltip": "Random seed (-1 for random)"}), + "randomize_each_run": ("BOOLEAN", {"default": True, "tooltip": "Generate new seed each run when seed is -1"}), }, "optional": { "video": ("VIDEO,IMAGE", {"tooltip": "Connect VIDEO from LoadVideo node or IMAGE batch"}), @@ -490,10 +493,24 @@ class QwenVLVideoNode: temperature=0.7, keep_model_loaded=True, use_flash_attention=False, + seed=-1, + randomize_each_run=True, video=None, custom_prompt="", ): try: + # Handle seed for randomization + if randomize_each_run and seed == -1: + current_seed = random.randint(0, 0xffffffffffffffff) + elif seed == -1: + current_seed = 12345 + else: + current_seed = seed + + random.seed(current_seed) + torch.manual_seed(current_seed) + print(f"🎲 Using seed: {current_seed}") + # Determine video source and extract frames frames_pil = None frames_tensor = None diff --git a/nodes/qwenvl/vision_cloner.py b/nodes/qwenvl/vision_cloner.py index 46cd3dd..eb8d6e8 100644 --- a/nodes/qwenvl/vision_cloner.py +++ b/nodes/qwenvl/vision_cloner.py @@ -2,6 +2,7 @@ import os import json +import random import numpy as np import torch import gc @@ -40,6 +41,8 @@ class QwenVLVisionCloner: "keep_model_loaded": ("BOOLEAN", {"default": True}), "use_flash_attention": ("BOOLEAN", {"default": False}), "strip_quotes": ("BOOLEAN", {"default": False}), + "seed": ("INT", {"default": -1, "min": -1, "max": 0xffffffffffffffff}), + "randomize_each_run": ("BOOLEAN", {"default": True}), }, "optional": { "custom_prompt": ("STRING", {"multiline": True, "default": ""}) @@ -297,8 +300,20 @@ class QwenVLVisionCloner: def analyze_images(self, images, fade_percentage=15.0, qwen_model="Qwen3-VL-4B-Instruct", max_tokens=4096, temperature=0.7, keep_model_loaded=True, use_flash_attention=False, - strip_quotes=False, custom_prompt=""): + strip_quotes=False, seed=-1, randomize_each_run=True, custom_prompt=""): try: + # Handle seed for randomization + if randomize_each_run and seed == -1: + current_seed = random.randint(0, 0xffffffffffffffff) + elif seed == -1: + current_seed = 12345 + else: + current_seed = seed + + random.seed(current_seed) + torch.manual_seed(current_seed) + print(f"🎲 Using seed: {current_seed}") + default_prompt = """You must respond with ONLY valid JSON, nothing else. Analyze the image and output a JSON object: { diff --git a/nodes/qwenvl/vision_node.py b/nodes/qwenvl/vision_node.py index 1721163..34fd917 100644 --- a/nodes/qwenvl/vision_node.py +++ b/nodes/qwenvl/vision_node.py @@ -2,6 +2,7 @@ import os import base64 +import random import numpy as np from io import BytesIO from PIL import Image @@ -40,6 +41,8 @@ class QwenVLVisionNode: "temperature": ("FLOAT", {"default": 0.7, "min": 0.1, "max": 1.0}), "keep_model_loaded": ("BOOLEAN", {"default": True}), "use_flash_attention": ("BOOLEAN", {"default": False}), + "seed": ("INT", {"default": -1, "min": -1, "max": 0xffffffffffffffff}), + "randomize_each_run": ("BOOLEAN", {"default": True}), }, "optional": { "custom_base_prompt": ("STRING", {"multiline": True, "default": ""}), @@ -168,11 +171,25 @@ class QwenVLVisionNode: temperature=0.7, keep_model_loaded=True, use_flash_attention=False, + seed=-1, + randomize_each_run=True, custom_base_prompt="", custom_title="", override="", ): try: + # Handle seed for randomization + if randomize_each_run and seed == -1: + current_seed = random.randint(0, 0xffffffffffffffff) + elif seed == -1: + current_seed = 12345 + else: + current_seed = seed + + random.seed(current_seed) + torch.manual_seed(current_seed) + print(f"🎲 Using seed: {current_seed}") + # Build prompt if override: prompt_text = override diff --git a/nodes/qwenvl/zimage_vision.py b/nodes/qwenvl/zimage_vision.py index bff3d80..be95ef4 100644 --- a/nodes/qwenvl/zimage_vision.py +++ b/nodes/qwenvl/zimage_vision.py @@ -3,6 +3,7 @@ import json import re +import random import numpy as np import torch import gc @@ -68,6 +69,8 @@ class QwenVLZImageVision: "include_system_prompt": ("BOOLEAN", {"default": True}), "include_think_block": ("BOOLEAN", {"default": False}), "strip_quotes": ("BOOLEAN", {"default": False}), + "seed": ("INT", {"default": -1, "min": -1, "max": 0xffffffffffffffff}), + "randomize_each_run": ("BOOLEAN", {"default": True}), }, "optional": { "custom_analysis_prompt": ("STRING", {"multiline": True, "default": ""}), @@ -366,9 +369,21 @@ CRITICAL: Output ONLY the JSON object. No explanations, no markdown code blocks, def analyze_image(self, images, qwen_model="Qwen3-VL-4B-Instruct", prompt_file="(none)", system_prompt_file="(none)", user_mod_file="(none)", max_tokens=4096, temperature=0.5, keep_model_loaded=True, use_flash_attention=False, - include_system_prompt=True, include_think_block=True, strip_quotes=False, + include_system_prompt=True, include_think_block=True, strip_quotes=False, + seed=-1, randomize_each_run=True, custom_analysis_prompt="", user_modification="", custom_system_prompt=""): try: + # Handle seed for randomization + if randomize_each_run and seed == -1: + current_seed = random.randint(0, 0xffffffffffffffff) + elif seed == -1: + current_seed = 12345 + else: + current_seed = seed + + random.seed(current_seed) + torch.manual_seed(current_seed) + print(f"🎲 Using seed: {current_seed}") # Load model model, processor, tokenizer = self.load_model(qwen_model, keep_model_loaded, use_flash_attention)