diff --git a/README.md b/README.md index c6afd18..db6039f 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ Please try downgrading the ```protobuf``` dependency package to 3.20.3, or set e **If the dependency package error after updating, please double clicking ```repair_dependency.bat``` (for Official ComfyUI Protable) or ```repair_dependency_aki.bat``` (for ComfyUI-aki-v1.x) in the plugin folder to reinstall the dependency packages. +* Commit [DeepseekAPI V2](#DeepseekAPI V2) noee, supporting AliYun and VolcEngine API. * Commit [Collage](#Collage) node to collage images into one. * Commit [DeepSeekAPI](DeepSeekAPI) node, Use DeepSeek API for text inference. * Commit [SegmentAnythingUltraV3](#SegmentAnythingUltraV3) and [LoadSegmentAnythingModels](#LoadSegmentAnythingModels) nodes, Avoid duplicating model loading when using multiple SAM nodes. @@ -359,6 +360,21 @@ Outputs: * text: Output text of DeepSeek. * history: History of DeepSeek conversations. +### DeepSeekAPI V2 +On the basis of the [DeepSeekAPI](#DeepSeekAPI) node, DeepSeek API supporting AliYun and VolcEngine will be added, and these two Chinese cloud service providers will provide more stable API services. + +* On [VolcEngine](https://console.volcengine.com/ai/api/key/) Applying for the VolcEngine API key, there is a free quota of 500 thousand tokens. If you fill in my invitation code ```27RVS1QN``` when applying, you will receive an additional 3.75 million R1 model free tokens. + +* On [AliYun](https://bailian.console.aliyun.com/?apiKey=1#/api-key) Apply for AliYun API key. + +* Fill in the obtained API key into the fields ```volcengine_api_key``` and ```aliyun_api_key``` of ```api_key.ini```. This file is located in the root directory of the plugin, with a default name of ```api_key.ini.example```. Edit it and change the file extension to '.ini'. + +Add Options: +![image](image/deepseek_api_v2_node.jpg) + +* time_out: The timeout period is set to 300 seconds by default. + + ### ZhipuGLM4 Use the Zhipu API for text inference, supporting multi node context concatenation. Apply for an API key for free at [https://bigmodel.cn/usercenter/proj-mgmt/apikeys](https://bigmodel.cn/usercenter/proj-mgmt/apikeys), And fill it in ```api_key.ini```, this file is located in the root directory of the plug-in, and the default name is ```api_key.ini.example```. to use this file for the first time, you need to change the file suffix to ```.ini```. Open it using text editing software, fill in your API key after ```zhipu_api_key=``` and save it. diff --git a/README_CN.MD b/README_CN.MD index 8e3c20f..429f0ce 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -121,6 +121,7 @@ If this call came from a _pb2.py file, your generated code is out of date and mu ## 更新说明 **如果本插件更新后出现依赖包错误,请双击运行插件目录下的```install_requirements.bat```(官方便携包),或 ```install_requirements_aki.bat```(秋叶整合包) 重新安装依赖包。 +* 添加 [DeepseekAPI V2](#DeepseekAPI V2) 节点,支持阿里云和火山引擎的deepseek api。 * 添加 [Collage](#Collage) 节点,将多张图片拼合为一张大图。 * 添加 [DeepSeekAPI](DeepSeekAPI) 节点,使用DeepSeek API进行文本推理。 * 添加 [SegmentAnythingUltraV3](#SegmentAnythingUltraV3) 和 [LoadSegmentAnythingModels](#LoadSegmentAnythingModels)节点, 在使用多个SAM节点时避免重复加载模型。 @@ -335,6 +336,20 @@ JoyCaption2的extra_options参数节点。 * text: DeepSeek的输出。 * history: DeepSeek对话历史记录。 +### DeepSeekAPI V2 +在 [DeepSeekAPI](#DeepSeekAPI) 节点基础上增加支持阿里云和火山引擎的deepseek api,这两家中国云服务商将提供更稳定的api服务。 + +* 在 [火山引擎](https://console.volcengine.com/ai/api/key/) 申请火山引擎api key, 有50万tokens免费额度,如果在申请时填入我的邀请码 ```27RVS1QN```,将额外获得375万R1模型免费tokens。 + +* 在 [阿里云](https://bailian.console.aliyun.com/?apiKey=1#/api-key) 申请阿里云api key。 + +* 将获得的api key填到```api_key.ini```的```volcengine_api_key``` 和 ```aliyun_api_key``` 字段。 这个文件位于插件根目录下,默认名字是```api_key.ini.example```,请编辑后将文件后缀改为.ini。 + +增加选项: +![image](image/deepseek_api_v2_node.jpg) + +* time_out: 超时时间,默认为300秒。 + ### ZhipuGLM4 使用智谱API进行文本推理,支持多节点上下文串联。 diff --git a/api_key.ini.example b/api_key.ini.example index 64d504e..720382a 100644 --- a/api_key.ini.example +++ b/api_key.ini.example @@ -1,4 +1,6 @@ # LayerStyle api_key google_api_key= zhipu_api_key= -deepseek_api_key= \ No newline at end of file +deepseek_api_key= +volcengine_api_key= +aliyun_api_key= diff --git a/image/deepseek_api_v2_node.jpg b/image/deepseek_api_v2_node.jpg new file mode 100644 index 0000000..1be24e8 Binary files /dev/null and b/image/deepseek_api_v2_node.jpg differ diff --git a/py/deepseek.py b/py/deepseek.py index 714877e..5ab7297 100644 --- a/py/deepseek.py +++ b/py/deepseek.py @@ -2,10 +2,12 @@ import base64 import io import json import requests +from openai import base_url + from .imagefunc import * -deepseek_model_list = ['deepseek-chat'] +deepseek_model_list = ['deepseek-chat', 'deepseek-r1(aliyun)', 'deepseek-v3(aliyun)', 'deepseek-r1(volcengine)', 'deepseek-v3(volcengine)'] class LS_DeepSeek_API: @@ -74,11 +76,98 @@ class LS_DeepSeek_API: log(f"{self.NODE_NAME}: {model} response is:\n\033[1;36m{ret_message}\033[m") return (ret_message, {"messages": messages},) +class LS_DeepSeek_API_V2: + + def __init__(self): + self.NODE_NAME = 'DeepSeekAPI V2' + pass + + @classmethod + def INPUT_TYPES(self): + return { + "required": { + "model": (deepseek_model_list,), + "time_out": ("INT", {"default": 300, "min": 1, "max": 3600, "step": 1}), # 300s = 5min + "max_tokens": ("INT", {"default": 4096, "min": 1, "max": 8192, "step": 1}), + "temperature": ("FLOAT", {"default": 1, "min": 0, "max": 2, "step": 0.1}), + "top_p": ("FLOAT", {"default": 1, "min": 0, "max": 1, "step": 0.1}), + "presence_penalty": ("FLOAT", {"default": 0, "min": -2, "max": 2, "step": 0.1}), + "frequency_penalty": ("FLOAT", {"default": 0, "min": -2, "max": 2, "step": 0.1}), + "history_length": ("INT", {"default": 8, "min": 1, "max": 64, "step": 1}), + "system_prompt": ("STRING", {"default": "You are a helpful assistant.", "multiline": False}), + "user_prompt": ("STRING", {"default": "", "multiline": True}), + }, + "optional": { + "history": ("DEEPSEEK_HISTORY",), + } + } + + RETURN_TYPES = ("STRING", "DEEPSEEK_HISTORY",) + RETURN_NAMES = ("text", "history",) + FUNCTION = 'run_deepseek_api_v2' + CATEGORY = '😺dzNodes/LayerUtility' + + def run_deepseek_api_v2(self, model, time_out, max_tokens, temperature, top_p, presence_penalty, frequency_penalty, + history_length, system_prompt, user_prompt, history=None): + + if 'aliyun' in model: + api_key = get_api_key('aliyun_api_key') + base_url = 'https://dashscope.aliyuncs.com/compatible-mode/v1' + if 'r1' in model: + model_name = 'deepseek-r1' + else: + model_name = 'deepseek-v3' + elif 'volcengine' in model: + api_key = get_api_key('volcengine_api_key') + base_url = 'https://ark.cn-beijing.volces.com/api/v3' + if 'r1' in model: + model_name = 'deepseek-r1-250120' + else: + model_name = 'deepseek-v3-241226' + else: + api_key = get_api_key('deepseek_api_key') + base_url = "https://api.deepseek.com" + model_name = 'deepseek-chat' + + ret_text = "" + + if history is not None: + messages = history["messages"] + messages = messages[-history_length *2:] + else: + messages = [{"role": "system", "content": system_prompt}] + task = {"role": "user", "content": user_prompt} + messages.append(task) + + + from openai import OpenAI + client = OpenAI(api_key=api_key, base_url=base_url, timeout=time_out) + + + response = client.chat.completions.create( + model=model_name, + messages=messages, + frequency_penalty=frequency_penalty, + max_tokens=max_tokens, + presence_penalty=presence_penalty, + temperature=temperature, + top_p=top_p, + stream=False + ) + + ret_message = response.choices[0].message.content + messages.append({"role": "assistant", "content": ret_message}) + + log(f"{self.NODE_NAME}: {model} response is:\n\033[1;36m{ret_message}\033[m") + return (ret_message, {"messages": messages},) + NODE_CLASS_MAPPINGS = { "LayerUtility: DeepSeekAPI": LS_DeepSeek_API, + "LayerUtility: DeepSeekAPIV2": LS_DeepSeek_API_V2, } NODE_DISPLAY_NAME_MAPPINGS = { "LayerUtility: DeepSeekAPI": "LayerUtility: DeepSeek API", + "LayerUtility: DeepSeekAPIV2": "LayerUtility: DeepSeek API V2", } \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 93e35a4..7b278ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui_layerstyle_advance" description = "The nodes detached from ComfyUI Layer Style are mainly those with complex requirements for dependency packages." -version = "2.0.13" +version = "2.0.14" license = "MIT" dependencies = ["numpy", "matplotlib", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "blend_modes", "transformers", "diffusers", "loguru", "colour-science", "huggingface_hub", "segment_anything", "addict", "omegaconf", "yapf", "wget", "iopath", "mediapipe", "typer_config", "fastapi", "rich", "google-generativeai", "ultralytics", "transparent-background", "accelerate", "onnxruntime", "bitsandbytes", "peft", "protobuf", "hydra-core", "blind-watermark", "qrcode", "pyzbar", "psd-tools", "wandb", "zhipuai", "openai"]