Files
neverbiasu-ComfyUI-Dashscope/node.py
T

186 lines
5.2 KiB
Python

import os
import random
import string
from dashscope import Generation, MultiModalConversation
import torchvision.transforms as transforms
def generate_random_image_name():
random_number = "".join(random.choices(string.ascii_letters + string.digits, k=10))
return f"image_{random_number}.png"
def get_image_url(image):
image = image.squeeze(0)
image = image.permute(2, 0, 1)
image = transforms.ToPILImage()(image)
image_name = generate_random_image_name()
image.save(image_name)
return image_name
def get_model_versions(model_type):
model_versions = []
current_group = None
model_versions_file = f"model_versions/{model_type}.txt"
with open(model_versions_file, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if line.startswith("[") and line.endswith("]"):
current_group = line[1:-1]
continue
model_versions.append(line)
return model_versions
class DashscopeLLMLoader:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
model_versions = get_model_versions("llm")
return {
"required": {
"model_version": (
model_versions,
{
"default": (
model_versions[0] if model_versions else "qwen-max-latest"
)
},
),
}
}
FUNCTION = "select_model"
OUTPUT_NODE = True
RETURN_TYPES = ("STRING",)
CATEGORY = "dashscope"
def select_model(self, model_version) -> tuple[str]:
print("Selected model version:", model_version)
if not model_version:
raise ValueError("Model version cannot be empty")
return (model_version,)
class DashscopeVLMLoader:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
model_versions = get_model_versions()
return {
"required": {
"model_version": (
model_versions,
{
"default": (
model_versions[0]
if model_versions
else "qwen-vl-max-latest"
)
},
),
}
}
FUNCTION = "select_model"
OUTPUT_NODE = True
RETURN_TYPES = ("STRING",)
CATEGORY = "dashscope"
def select_model(self, model_version) -> tuple[str]:
print("Selected model version: ", model_version)
if not model_version:
raise ValueError("Model version cannot be empty")
return (model_version,)
class DashscopeModelCaller:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"model_version": ("STRING", {"default": None}),
"system_prompt": (
"STRING",
{"default": "You are a helpful assistant."},
),
"user_prompt": ("STRING", {"default": ""}),
},
"optional": {
"image": ("IMAGE", {"default": None}),
},
}
FUNCTION = "call_model"
OUTPUT_NODE = True
RETURN_TYPES = ("STRING",)
CATEGORY = "dashscope"
def call_model(
self, model_version, system_prompt, user_prompt, image
) -> tuple[str]:
if not model_version:
raise ValueError("Model version cannot be empty")
if not system_prompt:
raise ValueError("System prompt cannot be empty")
if not user_prompt:
raise ValueError("User prompt cannot be empty")
api_key = os.getenv("DASHSCOPE_API_KEY")
if not api_key:
raise ValueError("DASHSCOPE_API_KEY environment variable is not set")
if image is None:
print("Call the LLM model")
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
]
response = Generation.call(
api_key=api_key,
model=model_version,
messages=messages,
result_format="message",
)
else:
print("Call the VLM model")
image_url = get_image_url(image)
messages = [
{"role": "system", "content": system_prompt},
{
"role": "user",
"content": [
{"image": image_url},
{"text": user_prompt},
],
},
]
response = MultiModalConversation.call(
api_key=api_key,
model=model_version,
messages=messages,
result_format="message",
)
if response is None:
raise ValueError("API call returned None")
message_content = response.output.choices[0].message.content[0]["text"]
return (message_content,)