From 74d733080006461cf87d734e1f253dd32b126346 Mon Sep 17 00:00:00 2001 From: Lucas Armand Date: Tue, 25 Nov 2025 15:45:25 -0800 Subject: [PATCH] add wan and ace workers --- workers/ace/worker.py | 188 +++++++++++++++++++++++++++ workers/wan/worker.py | 291 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 479 insertions(+) create mode 100644 workers/ace/worker.py create mode 100644 workers/wan/worker.py diff --git a/workers/ace/worker.py b/workers/ace/worker.py new file mode 100644 index 0000000..deb5ef0 --- /dev/null +++ b/workers/ace/worker.py @@ -0,0 +1,188 @@ +import random +import sys + +from vastai import Worker, WorkerConfig, HandlerConfig, LogActionConfig, BenchmarkConfig + +# ComyUI model configuration +MODEL_SERVER_URL = 'http://127.0.0.1' +MODEL_SERVER_PORT = 18288 +MODEL_LOG_FILE = '/var/log/portal/comfyui.log' +MODEL_HEALTHCHECK_ENDPOINT = "/health" + +# ComyUI-specific log messages +MODEL_LOAD_LOG_MSG = [ + "To see the GUI go to: " +] + +MODEL_ERROR_LOG_MSGS = [ + "MetadataIncompleteBuffer", + "Value not in list: ", + "[ERROR] Provisioning Script failed" +] + +MODEL_INFO_LOG_MSGS = [ + '"message":"Downloading' +] + +benchmark_lyrics = [ + "[verse]\nGuardian cloaked in twilight hue\nShadows melt where he breaks through\nEchoes swirl in mystic flight\nHooded hero owns the night\n\n[verse]\nThrough the chaos shapes arise\nFeral whispers, glowing eyes\nOrcs and creatures side by side\nMarch within the inky tide\n\n[chorus]\nRise above the fear and gloom\nLet your courage fully bloom\nIn the darkness stand your ground\nHear the night proclaim your sound", + "[verse]\nMorning sun on fields of gold\nGentle stories unfold\nEvery breeze a quiet song\nWhere the peaceful hearts belong\n\n[verse]\nLanterns glow at stable doors\nRustling leaves on orchard floors\nSimple joys in every hand\nLife grows soft in fertile land\n\n[chorus]\nLet the day drift slow and free\nRoot your soul where you can be\nIn this haven warm and bright\nFeel the earth breathe pure delight", + "[verse]\nLittle feet on dusty ground\nChasing dreams without a sound\nSoccer ball in morning light\nHopes take wing in youthful flight\n\n[verse]\nChrome reflections paint the day\nSwagger in the steps that play\nCopper tones in shining air\nChildhood gleaming everywhere\n\n[chorus]\nKick the world with boundless cheer\nHold the magic close and near\nIn each moment bold and true\nLet the sky belong to you", + "[verse]\nSunset bleeds across the street\nGilded calm in summer heat\nLow-rise towers rimmed with fire\nDreams ignite as lights climb higher\n\n[verse]\nFootsteps scatter through the haze\nFutures shimmer in the blaze\nEvery window tells a tale\nFloating through a tangerine veil\n\n[chorus]\nLet the neon softly glow\nLet your restless heartbeat slow\nIn this city forged in light\nCarry hope into the night", + "[verse]\nOcean breathes in rolling arcs\nSprays of diamond, glowing sparks\nWaves unfold a perfect line\nNature’s rhythm feels divine\n\n[verse]\nSun above in golden sweep\nPaints the rise of every deep\nShimmer drifting through the blue\nWorld reborn in every view\n\n[chorus]\nLet the tide pull you along\nHear the water’s ancient song\nIn the cresting waves you’ll find\nQuiet peace for heart and mind", + "[verse]\nGlass aglow with swirling light\nFruits and mints in colors bright\nIcy whispers clink and chime\nFlowing forms suspend in time\n\n[verse]\nCreamy spirals drift within\nGentle currents slowly spin\nWarm reflections lingering sweet\nMixing flavors at your feet\n\n[chorus]\nSip the glow and let it rise\nTaste the sunset in disguise\nIn this moment clear and true\nLet the warmth flow into you", + "[verse]\nEngines rumble down the lane\nCopper clouds of steam and rain\nOilpunk dreams in metal shine\nRider drifting down the line\n\n[verse]\nLeather jacket, steady glare\nStories sparking in the air\nMagazine lights frame his face\nKing of roads in timeless grace\n\n[chorus]\nThrottle up beyond the bend\nFeel the force of steel ascend\nRide the night and hold on tight\nClaim the world in streaks of light", + "[verse]\nCut-out shapes in swirling play\nTextures dance in bold array\nCats in denim, grinning wide\nStrut across the patterned tide\n\n[verse]\nPosters hum with neon glow\nSurreal scenes begin to grow\nColors crisp as folded art\nPatchwork beating like a heart\n\n[chorus]\nLet the collage come alive\nWatch the vibrant pieces thrive\nIn this joyful, crafted space\nEvery shape finds its own place", + "[verse]\nTiny world in crystal glass\nAncient tales behind the mass\nVillage lights in winter gleam\nFrozen in a mystic dream\n\n[verse]\nLantern beams in swirling air\nSoft enchantment everywhere\nShadows drift with gentle grace\nMagic sealed within the space\n\n[chorus]\nHold the sphere and you will see\nEchoes of a memory\nIn the glow of fragile light\nLives a realm of pure delight", + "[verse]\nArmor hums with power bright\nChopping sparks in jungle night\nMecha spirits shift and scream\nThrough the ferns like shattered beams\n\n[verse]\nAxes blaze in glowing arcs\nLighting up the shadowed marks\nNature roars in trembling air\nClash of steel and cosmic flare\n\n[chorus]\nRaise the fire, strike the ground\nLet your legend shake the sound\nIn the wild where echoes roam\nForge the fight and carve your home", + "[verse]\nCrowds ignite in vibrant flare\nBeats explode through smoky air\nDJ robes replaced with flame\nPope on decks in holy frame\n\n[verse]\nLeather gleams in blinding light\nTurntables spin with sacred might\nChoirs echo in the bass\nHeaven pulses through the place\n\n[chorus]\nLift the roof and shake the floor\nSacred rhythm evermore\nLet the music take control\nFeel the blessing in your soul", +] + + +def parse_request(json_msg): + return {"input" : json_msg} + +benchmark_dataset = [ + { + "input": { + "request_id": "", + "workflow_json": { + "14": { + "inputs": { + "tags": "funk, pop, soul, rock, melodic, guitar, drums, bass, keyboard, percussion, 105 BPM, energetic, upbeat, groovy, vibrant, dynamic", + "lyrics": lyrics, + "lyrics_strength": 0.99, + "clip": ["40", 1] + }, + "class_type": "TextEncodeAceStepAudio", + "_meta": { + "title": "TextEncodeAceStepAudio" + } + }, + "17": { + "inputs": { + "seconds": 180, + "batch_size": 1 + }, + "class_type": "EmptyAceStepLatentAudio", + "_meta": { + "title": "EmptyAceStepLatentAudio" + } + }, + "18": { + "inputs": { + "samples": ["52", 0], + "vae": ["40", 2] + }, + "class_type": "VAEDecodeAudio", + "_meta": { + "title": "VAE Decode Audio" + } + }, + "40": { + "inputs": { + "ckpt_name": "ace_step_v1_3.5b.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "44": { + "inputs": { + "conditioning": ["14", 0] + }, + "class_type": "ConditioningZeroOut", + "_meta": { + "title": "ConditioningZeroOut" + } + }, + "49": { + "inputs": { + "model": ["51", 0], + "operation": ["50", 0] + }, + "class_type": "LatentApplyOperationCFG", + "_meta": { + "title": "LatentApplyOperationCFG" + } + }, + "50": { + "inputs": { + "multiplier": 1.15 + }, + "class_type": "LatentOperationTonemapReinhard", + "_meta": { + "title": "LatentOperationTonemapReinhard" + } + }, + "51": { + "inputs": { + "shift": 6, + "model": ["40", 0] + }, + "class_type": "ModelSamplingSD3", + "_meta": { + "title": "ModelSamplingSD3" + } + }, + "52": { + "inputs": { + "seed": "__RANDOM_INT__", + "steps": 65, + "cfg": 4, + "sampler_name": "er_sde", + "scheduler": "linear_quadratic", + "denoise": 1, + "model": ["49", 0], + "positive": ["14", 0], + "negative": ["44", 0], + "latent_image": ["17", 0] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "59": { + "inputs": { + "filename_prefix": "audio/ComfyUI", + "quality": "V0", + "audioUI": "", + "audio": ["18", 0] + }, + "class_type": "SaveAudioMP3", + "_meta": { + "title": "Save Audio (MP3)" + } + } + } + } + } for lyrics in benchmark_lyrics +] + +worker_config = WorkerConfig( + model_server_url=MODEL_SERVER_URL, + model_server_port=MODEL_SERVER_PORT, + model_log_file=MODEL_LOG_FILE, + model_healthcheck_url=MODEL_HEALTHCHECK_ENDPOINT, + handlers=[ + HandlerConfig( + route="/generate/sync", + allow_parallel_requests=False, + max_queue_time=10.0, + request_parser=parse_request, + benchmark_config=BenchmarkConfig( + dataset=benchmark_dataset, + runs=1 + ) + ) + ], + log_action_config=LogActionConfig( + on_load=MODEL_LOAD_LOG_MSG, + on_error=MODEL_ERROR_LOG_MSGS, + on_info=MODEL_INFO_LOG_MSGS + ) +) + +Worker(worker_config).run() \ No newline at end of file diff --git a/workers/wan/worker.py b/workers/wan/worker.py new file mode 100644 index 0000000..6d81469 --- /dev/null +++ b/workers/wan/worker.py @@ -0,0 +1,291 @@ +import random +import sys + +from vastai import Worker, WorkerConfig, HandlerConfig, LogActionConfig, BenchmarkConfig + +# ComyUI model configuration +MODEL_SERVER_URL = 'http://127.0.0.1' +MODEL_SERVER_PORT = 18288 +MODEL_LOG_FILE = '/var/log/portal/comfyui.log' +MODEL_HEALTHCHECK_ENDPOINT = "/health" + +# ComyUI-specific log messages +MODEL_LOAD_LOG_MSG = [ + "To see the GUI go to: " +] + +MODEL_ERROR_LOG_MSGS = [ + "MetadataIncompleteBuffer", + "Value not in list: ", + "[ERROR] Provisioning Script failed" +] + +MODEL_INFO_LOG_MSGS = [ + '"message":"Downloading' +] + +benchmark_prompts = [ + "Cartoon hoodie hero; orc, anime cat, bunny; black goo; buff; vector on white.", + "Cozy farming-game scene with fine details.", + "2D vector child with soccer ball; airbrush chrome; swagger; antique copper.", + "Realistic futuristic downtown of low buildings at sunset.", + "Perfect wave front view; sunny seascape; ultra-detailed water; artful feel.", + "Clear cup with ice, fruit, mint; creamy swirls; fluid-sim CGI; warm glow.", + "Male biker with backpack on motorcycle; oilpunk; award-worthy magazine cover.", + "Collage for textile; surreal cartoon cat in cap/jeans before poster; crisp.", + "Medieval village inside glass sphere; volumetric light; macro focus.", + "Iron Man with glowing axe; mecha sci-fi; jungle scene; dynamic light.", + "Pope Francis DJ in leather jacket, mixing on giant console; dramatic.", +] + +def parse_request(json_msg): + return {"input" : json_msg} + +benchmark_dataset = [ + { + "input": { + "workflow_json": { + "90": { + "inputs": { + "clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors", + "type": "wan", + "device": "default" + }, + "class_type": "CLIPLoader", + "_meta": { + "title": "Load CLIP" + } + }, + "91": { + "inputs": { + "text": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走,裸露,NSFW", + "clip": [ + "90", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Negative Prompt)" + } + }, + "92": { + "inputs": { + "vae_name": "wan_2.1_vae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "93": { + "inputs": { + "shift": 8.000000000000002, + "model": [ + "101", + 0 + ] + }, + "class_type": "ModelSamplingSD3", + "_meta": { + "title": "ModelSamplingSD3" + } + }, + "94": { + "inputs": { + "shift": 8, + "model": [ + "102", + 0 + ] + }, + "class_type": "ModelSamplingSD3", + "_meta": { + "title": "ModelSamplingSD3" + } + }, + "95": { + "inputs": { + "add_noise": "disable", + "noise_seed": 0, + "steps": 20, + "cfg": 3.5, + "sampler_name": "euler", + "scheduler": "simple", + "start_at_step": 10, + "end_at_step": 10000, + "return_with_leftover_noise": "disable", + "model": [ + "94", + 0 + ], + "positive": [ + "99", + 0 + ], + "negative": [ + "91", + 0 + ], + "latent_image": [ + "96", + 0 + ] + }, + "class_type": "KSamplerAdvanced", + "_meta": { + "title": "KSampler (Advanced)" + } + }, + "96": { + "inputs": { + "add_noise": "enable", + "noise_seed": "__RANDOM_INT__", + "steps": 20, + "cfg": 3.5, + "sampler_name": "euler", + "scheduler": "simple", + "start_at_step": 0, + "end_at_step": 10, + "return_with_leftover_noise": "enable", + "model": [ + "93", + 0 + ], + "positive": [ + "99", + 0 + ], + "negative": [ + "91", + 0 + ], + "latent_image": [ + "104", + 0 + ] + }, + "class_type": "KSamplerAdvanced", + "_meta": { + "title": "KSampler (Advanced)" + } + }, + "97": { + "inputs": { + "samples": [ + "95", + 0 + ], + "vae": [ + "92", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "98": { + "inputs": { + "filename_prefix": "video/ComfyUI", + "format": "auto", + "codec": "auto", + "video": [ + "100", + 0 + ] + }, + "class_type": "SaveVideo", + "_meta": { + "title": "Save Video" + } + }, + "99": { + "inputs": { + "text":prompt, + "clip": [ + "90", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Positive Prompt)" + } + }, + "100": { + "inputs": { + "fps": 16, + "images": [ + "97", + 0 + ] + }, + "class_type": "CreateVideo", + "_meta": { + "title": "Create Video" + } + }, + "101": { + "inputs": { + "unet_name": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "102": { + "inputs": { + "unet_name": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "104": { + "inputs": { + "width": 640, + "height": 640, + "length": 81, + "batch_size": 1 + }, + "class_type": "EmptyHunyuanLatentVideo", + "_meta": { + "title": "EmptyHunyuanLatentVideo" + } + } + } + } + } for prompt in benchmark_prompts +] + +worker_config = WorkerConfig( + model_server_url=MODEL_SERVER_URL, + model_server_port=MODEL_SERVER_PORT, + model_log_file=MODEL_LOG_FILE, + model_healthcheck_url=MODEL_HEALTHCHECK_ENDPOINT, + handlers=[ + HandlerConfig( + route="/generate/sync", + allow_parallel_requests=False, + max_queue_time=10.0, + request_parser=parse_request, + benchmark_config=BenchmarkConfig( + dataset=benchmark_dataset, + runs=1 + ) + ) + ], + log_action_config=LogActionConfig( + on_load=MODEL_LOAD_LOG_MSG, + on_error=MODEL_ERROR_LOG_MSGS, + on_info=MODEL_INFO_LOG_MSGS + ) +) + +Worker(worker_config).run() \ No newline at end of file