92 lines
6.0 KiB
Python
92 lines
6.0 KiB
Python
"""Deploy an isolated VDN adapter, preserving the existing production services."""
|
|
import json, math, pathlib, subprocess, time
|
|
root=pathlib.Path('/home/ps/huobao-vdn')
|
|
existing=set(subprocess.check_output(['docker','ps','-a','--format','{{.Names}}'],text=True).splitlines())
|
|
if {'huobao-vdn-normalizer','huobao-vdn-bridge'} & existing:
|
|
raise RuntimeError('VDN already deployed: inspect and back up existing services before changing files')
|
|
root.mkdir(exist_ok=True)
|
|
root.chmod(0o700)
|
|
def run(*args):
|
|
return subprocess.check_output(args,text=True)
|
|
name='canvas-h3-prompt-normalizer-healthy-20261026'
|
|
old=json.loads(run('docker','inspect',name))[0]
|
|
config=json.loads(pathlib.Path('/home/ps/huobao-model-bridge/config.json').read_text())
|
|
env=dict(x.split('=',1) for x in old['Config']['Env'])
|
|
for f in ('app.py','workflow.py'):
|
|
(root/f).write_text(run('docker','exec',name,'cat','/app/'+f))
|
|
app=(root/'app.py').read_text()
|
|
anchor=' response = await client.get(f"{provider.base_url}/queue", headers=provider_headers(provider))'
|
|
assert app.count(anchor)>=1
|
|
app=app.replace(anchor, ''' capabilities = await client.get(f"{provider.base_url}/object_info/ApplyVDNH3", headers=provider_headers(provider))
|
|
capabilities.raise_for_status()
|
|
if 'ApplyVDNH3' not in capabilities.json():
|
|
return None
|
|
'''+anchor,1)
|
|
anchor=' response.raise_for_status()\n payload = response.json()\n finally:'
|
|
assert app.count(anchor)==1
|
|
app=app.replace(anchor, ''' if response.status_code == 400:
|
|
rejected = response.json()
|
|
issues = []
|
|
for node, info in (rejected.get('node_errors') or {}).items():
|
|
for error in info.get('errors', []):
|
|
issues.append(str(node) + ': ' + str(error.get('message', '')) + ': ' + str(error.get('details', ''))[:300])
|
|
if not issues:
|
|
issues = [str(rejected.get('error', 'Workflow validation failed'))[:600]]
|
|
raise HTTPException(status_code=400, detail='; '.join(issues)[:1800])
|
|
'''+anchor)
|
|
(root/'app.py').write_text(app)
|
|
workflow=(root/'workflow.py').read_text()
|
|
anchor=' count = max(1, min(int(request.get("batch_size") or 1), 4))'
|
|
assert workflow.count(anchor)==1
|
|
workflow=workflow.replace(anchor, ''' if spec.key == 'minimax_h3_vdn_hd':
|
|
width, height = int(request['width']), int(request['height'])
|
|
if (width, height) not in {(2560,1440),(1440,2560),(3840,2160),(2160,3840)}:
|
|
raise ValueError('VDN HD requires exact 2K or 4K dimensions')
|
|
_patch_node(workflow, '8', {'width': math.ceil(width / 32) * 32, 'height': math.ceil(height / 32) * 32,
|
|
'length': round(float(request.get('duration', 5)) * 24) + 1})
|
|
# SelfLift performs low-resolution and high-resolution diffusion stages.
|
|
# Decode at the requested area; crop alignment padding instead of pixel upscaling.
|
|
_patch_node(workflow, '12', {'highres_tiling': width * height > 2560 * 1440})
|
|
'''+anchor)
|
|
(root/'workflow.py').write_text(workflow)
|
|
workflows=root/'workflows'; workflows.mkdir(exist_ok=True)
|
|
graph=json.loads((root/'source-graph.json').read_text())
|
|
graph['8']['inputs']['prompt']='A quiet cinematic mountain landscape. No dialogue. No text.'
|
|
graph['8']['inputs'].update(width=2560,height=1440,length=97)
|
|
graph.pop('15', None)
|
|
graph['16']['inputs']['images']=['13',0]
|
|
graph['16']['inputs']['filename_prefix']='huobao_vdn/HD'
|
|
(workflows/'vdn_hd.json').write_text(json.dumps(graph,ensure_ascii=False))
|
|
spec={'key':'minimax_h3_vdn_hd','name':'MiniMax H3 VDN 高清重生成','mode':'image','file':'vdn_hd.json',
|
|
'prompt_node':'8','prompt_input':'prompt','seed_node':'12','seed_input':'seed','save_node':'16','save_prefix':'huobao_vdn/HD',
|
|
'reference_node':'8','reference_input_prefix':'ref_images.ref_image_',
|
|
'width_node':'8','height_node':'8','width_input':'width','height_input':'height','enabled':True}
|
|
(workflows/'manifest.json').write_text(json.dumps({'version':1,'workflows':[spec]}))
|
|
state=root/'state'; state.mkdir(exist_ok=True)
|
|
private=root/'normalizer.env'
|
|
private.write_text('\n'.join(k+'='+v for k,v in env.items() if k not in {'PATH','PYTHON_VERSION','PYTHON_SHA256','GPG_KEY','LANG'}))
|
|
private.chmod(0o600)
|
|
exists=run('docker','ps','-a','--format','{{.Names}}').splitlines()
|
|
if 'huobao-vdn-normalizer' in exists: raise RuntimeError('VDN already deployed: inspect before changing it')
|
|
args=['docker','run','-d','--name','huobao-vdn-normalizer','--restart','unless-stopped','--network','open-ai-canvas_default',
|
|
'--env-file',str(private),'-v',str(root/'app.py')+':/app/app.py:ro','-v',str(root/'workflow.py')+':/app/workflow.py:ro',
|
|
'-v',str(workflows)+':/app/workflows:ro','-v',str(state)+':/var/lib/h3-audio-validation']
|
|
for m in old['Mounts']:
|
|
if m['Destination'].startswith('/run/'):
|
|
args+=['-v',m['Source']+':'+m['Destination']+':ro']
|
|
args+=[old['Image']]+old['Config']['Cmd']
|
|
print('normalizer',run(*args).strip()[:12])
|
|
run('docker','network','connect','zq-platform-network','huobao-vdn-normalizer')
|
|
broot=root/'bridge'; broot.mkdir(exist_ok=True)
|
|
bridge_config={'token':config['token'],'h3':dict(config['h3'],url='http://huobao-vdn-normalizer:8105'),
|
|
'state_dir':'/state','public_url':'http://192.168.110.111:18794'}
|
|
(broot/'config.json').write_text(json.dumps(bridge_config)); (broot/'config.json').chmod(0o600)
|
|
(broot/'bridge.py').write_text((root/'bridge.py').read_text())
|
|
bstate=root/'bridge-state'; bstate.mkdir(exist_ok=True)
|
|
oldbridge=json.loads(run('docker','inspect','huobao-model-bridge'))[0]
|
|
print('bridge',run('docker','run','-d','--name','huobao-vdn-bridge','--restart','unless-stopped',
|
|
'--network','open-ai-canvas_default','--user','1000:1000','--read-only','--tmpfs','/tmp:rw,noexec,nosuid,size=64m',
|
|
'-p','192.168.110.111:18794:8080','-v',str(broot)+':/bridge:ro','-v',str(bstate)+':/state',
|
|
'-w','/bridge','--entrypoint','python',oldbridge['Image'],*oldbridge['Config']['Cmd']).strip()[:12])
|
|
print('deployed isolated VDN services; original services unchanged')
|