From d1b2f260aa3587098ee2e791b7e2b53beee77a17 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Wed, 16 Jul 2025 14:32:16 +0800 Subject: [PATCH] first commit --- README.md | 0 app/hdimage.py | 98 ++++++++++++++++++++++++++++++++++ build.sh | 3 ++ conf/config.json | 48 +++++++++++++++++ hdimage.spec | 44 +++++++++++++++ install.sh | 14 +++++ requirements.txt | 6 +++ wwwroot/v1/docs.md | 14 +++++ wwwroot/v1/generate/index.dspy | 20 +++++++ 9 files changed, 247 insertions(+) create mode 100644 README.md create mode 100644 app/hdimage.py create mode 100755 build.sh create mode 100644 conf/config.json create mode 100644 hdimage.spec create mode 100644 install.sh create mode 100644 requirements.txt create mode 100644 wwwroot/v1/docs.md create mode 100644 wwwroot/v1/generate/index.dspy diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/app/hdimage.py b/app/hdimage.py new file mode 100644 index 0000000..f9f195c --- /dev/null +++ b/app/hdimage.py @@ -0,0 +1,98 @@ +import asyncio +import os +import io +import base64 +from PIL import Image +from appPublic.hf import hf_socks5proxy +from appPublic.log import debug +from appPublic.worker import awaitify +from appPublic.folderUtils import _mkdir, temp_file +from appPublic.jsonConfig import getConfig +from ahserver.filestorage import FileStorage +from ahserver.webapp import webapp +from ahserver.serverenv import ServerEnv +from ahserver.filestorage import FileStorage + +import torch +import transformers +from transformers import PreTrainedTokenizerFast, LlamaForCausalLM +from diffusers import HiDreamImagePipeline + +hf_socks5proxy() + +def pil_image_to_base64_str(img: Image.Image, format="PNG") -> str: + buffer = io.BytesIO() + img.save(buffer, format=format) + img_bytes = buffer.getvalue() + base64_str = base64.b64encode(img_bytes).decode('utf-8') + return base64_str + +class HDImage: + def __init__(self): + config = getConfig() + tokenizer_4 = PreTrainedTokenizerFast.from_pretrained(f"{config.llama_model_path}/Llama-3.1-8B-Instruct", + device_map="balanced" + ) + text_encoder_4 = LlamaForCausalLM.from_pretrained( + f"{config.llama_model_path}/Llama-3.1-8B-Instruct", + output_hidden_states=True, + device_map="balanced", + output_attentions=True, + torch_dtype=torch.bfloat16, + ) + + pipe = HiDreamImagePipeline.from_pretrained( + f"{config.hidream_model_path}/HiDream-I1-Full", # "HiDream-ai/HiDream-I1-Dev" | "HiDream-ai/HiDream-I1-Fast" + device_map="balanced", + tokenizer_4=tokenizer_4, + text_encoder_4=text_encoder_4, + torch_dtype=torch.bfloat16, + ) + + # pipe = pipe.to('cuda') + self.pipe = pipe + self.fs = FileStorage() + self.defaultv = { + "width":1024, + "height":1024, + "guidance_scale":5.0, + "num_inference_steps":50 + } + self.lock = asyncio.Lock() + + + def _generate(self, prompt, kw): + image = self.pipe( + prompt, + generator=torch.Generator("cuda").manual_seed(0), + **kw + ).images[0] + return pil_image_to_base64_str(image) + fn=self.fs._name2path('generated.png') + pth = self.fs.webpath(fn) + debug(f'{fn=}, {pth=}, {dir(image)},{type(image)}') + _mkdir(os.path.dirname(fn)) + image.save(fn) + return pth + + async def generate(self, prompt, width=None, height=None, + guidance_scale=None, + num_inference_steps=None): + kw = { + "width" : self.defaultv['width'] if width is None else width, + "height" : self.defaultv['height'] if height is None else height, + "guidance_scale" : self.defaultv['guidance_scale'] if guidance_scale is None else guidance_scale, + "num_inference_steps" : self.defaultv['num_inference_steps'] if num_inference_steps is None else num_inference_steps + } + async with self.lock: + f = awaitify(self._generate) + return await f(prompt, kw) + +def init(): + hd_image = HDImage() + g = ServerEnv() + g.hd_image = hd_image + +if __name__ == '__main__': + webapp(init) + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..2238689 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/bash + +pyinstaller -y --clean hdimage.spec diff --git a/conf/config.json b/conf/config.json new file mode 100644 index 0000000..ae2ace8 --- /dev/null +++ b/conf/config.json @@ -0,0 +1,48 @@ +{ + "device" : "cuda", + "llama_model_path":"/share/models/meta-llama", + "hidream_model_path":"/share/models/HiDream-ai", + "logger":{ + "name":"hdimage", + "levelname":"info", + "logfile":"$[workdir]$/logs/hdimage.log" + }, + "filesroot":"$[workdir]$/files", + "website":{ + "paths":[ + ["$[workdir]$/wwwroot",""] + ], + "client_max_size":10000, + "host":"0.0.0.0", + "port":9901, + "coding":"utf-8", + "indexes":[ + "index.html", + "index.tmpl", + "index.ui", + "index.dspy", + "index.md" + ], + "startswiths":[ + { + "leading":"/idfile", + "registerfunction":"idFileDownload" + } + ], + "processors":[ + [".dspy","dspy"], + [".md","md"] + ], + "session_max_time":3000, + "session_issue_time":2500, + "session_redis_notuse":{ + "url":"redis://127.0.0.1:6379" + } + }, + "langMapping":{ + "zh-Hans-CN":"zh-cn", + "zh-CN":"zh-cn", + "en-us":"en", + "en-US":"en" + } +} diff --git a/hdimage.spec b/hdimage.spec new file mode 100644 index 0000000..bca603a --- /dev/null +++ b/hdimage.spec @@ -0,0 +1,44 @@ +# -*- mode: python ; coding: utf-8 -*- +from PyInstaller.utils.hooks import collect_submodules + + +a = Analysis( + ['app/hdimage.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=collect_submodules("transformers") + + collect_submodules("diffusers") + + collect_submodules("safetensors") + + collect_submodules("huggingface_hub") + + collect_submodules("torch"), + + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, + optimize=0, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='hdimage', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..a8570d3 --- /dev/null +++ b/install.sh @@ -0,0 +1,14 @@ + +curdir=$(pwd) +echo $curdir +python3 -m venv $curdir/py3 +# $curdir/py3/bin/pip install git+https://github.com/HiDream-ai/HiDream-I1.git +$curdir/py3/bin/pip install -U flash-attn --no-build-isolation +# $curdir/py3/bin/pip install git+https://github.com/huggingface/diffusers.git +$curdir/py3/bin/pip install git+https://git.kaiyuancloud.cn/yumoqing/apppublic +$curdir/py3/bin/pip install git+https://git.kaiyuancloud.cn/yumoqing/sqlor +$curdir/py3/bin/pip install git+https://git.kaiyuancloud.cn/yumoqing/ahserver +$curdir/py3/bin/pip install packaging +$curdir/py3/bin/pip install wheel +$curdir/py3/bin/pip install SentencePiece +$curdir/py3/bin/pip install flash-attn diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..061b7b7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +torch>=2.5.1 +torchvision>=0.20.1 +diffusers>=0.32.1 +transformers>=4.47.1 +einops>=0.7.0 +accelerate>=1.2.1 diff --git a/wwwroot/v1/docs.md b/wwwroot/v1/docs.md new file mode 100644 index 0000000..c45cb5d --- /dev/null +++ b/wwwroot/v1/docs.md @@ -0,0 +1,14 @@ +# mdimage API + +## generate +功能:按照提示此生成图片 + +### url +/v1/generate + +## method +GET + +### 入参 +* prompt:提示词 + diff --git a/wwwroot/v1/generate/index.dspy b/wwwroot/v1/generate/index.dspy new file mode 100644 index 0000000..88b56e7 --- /dev/null +++ b/wwwroot/v1/generate/index.dspy @@ -0,0 +1,20 @@ +debug(f'{params_kw=}') +prompt = params_kw.prompt +try: + b64imgs = await hd_image.generate(prompt, num_inference_steps=20) + d = { + 'status':'ok', + "data":[ + { + "image":b64imgs + } + ] + } + debug(f'return data {d=}') + return d +except Exceoption as e: + exception(f'{e=}, {format_exc()}') + return { + 'status':'error', + 'message':'server error' + }