ACCC1380/molab-moss / validate_moss.py
ACCC1380's picture
download
raw
4.64 kB
#!/usr/bin/env python3
"""Run Base, Base + sample LoRA, and SFT at 1024x1024 / 50 steps."""
import hashlib
import json
from pathlib import Path
import time
import subprocess
import numpy as np
from PIL import Image
import requests
ROOT = Path(__file__).resolve().parent
BASE_URL = 'http://127.0.0.1:8189'
def main():
subprocess.run(['bash', str(ROOT / 'restore-model-links.sh'), '--check'], check=True)
credentials = {}
for line in Path('/var/lib/comfyui-moss-admin/login.txt').read_text().splitlines():
key, value = line.split(': ', 1)
credentials[key.lower()] = value
session = requests.Session()
response = session.post(BASE_URL + '/login', data=credentials, timeout=30)
response.raise_for_status()
response = session.get(BASE_URL + '/object_info', timeout=60)
response.raise_for_status()
object_info = response.json()
missing = set()
workflow_dir = ROOT / 'ComfyUI/user/default/workflows/MOSS'
for path in workflow_dir.glob('*.json'):
workflow = json.loads(path.read_text())
subgraphs = workflow.get('definitions', {}).get('subgraphs', [])
local_types = {g['id'] for g in subgraphs} | {'MarkdownNote', 'Note'}
for graph in [workflow] + subgraphs:
for node in graph['nodes']:
if node['type'] not in object_info and node['type'] not in local_types:
missing.add(node['type'])
assert not missing, f'Missing workflow nodes: {missing}'
report = {'workflow_nodes_validated': True,
'model_paths': [f['path'] for f in json.loads((ROOT / 'moss-model-manifest.json').read_text())],
'runs': {}}
report_path = ROOT / 'moss-generation-validation.json'
for variant in ('base', 'base_lora', 'sft'):
name = 'MOSS-' + variant.replace('_', '-').upper() + '-BF16'
prompt = json.loads((ROOT / 'workflows' / (name + '_api.json')).read_text())
workflow = json.loads((workflow_dir / (name + '.json')).read_text())
start = time.monotonic()
response = session.post(BASE_URL + '/prompt', json={
'prompt': prompt, 'extra_data': {'extra_pnginfo': {'workflow': workflow}}
}, timeout=60)
if response.status_code != 200:
raise RuntimeError(response.text)
submitted = response.json()
assert not submitted.get('node_errors'), submitted
prompt_id = submitted['prompt_id']
print(f'{variant}: submitted {prompt_id}', flush=True)
while True:
response = session.get(BASE_URL + '/history/' + prompt_id, timeout=60)
response.raise_for_status()
history = response.json().get(prompt_id)
if history:
break
if time.monotonic() - start > 1800:
raise TimeoutError(variant)
time.sleep(5)
(ROOT / ('moss-' + variant + '-test-history.json')).write_text(json.dumps(history, indent=2) + '\n')
status = history['status']['status_str']
result = {'status': status, 'prompt_id': prompt_id,
'elapsed_seconds': round(time.monotonic() - start, 2),
'model': prompt['1']['inputs']['unet_name'],
'parameters': {'width': 1024, 'height': 1024, 'steps': 50,
'cfg': 3, 'sampler': 'euler', 'seed': 42}, 'images': []}
for output in history.get('outputs', {}).values():
for item in output.get('images', []):
image = ROOT / 'comfyui-output' / item['subfolder'] / item['filename']
with Image.open(image) as opened:
pixels = np.asarray(opened.convert('RGB'))
assert opened.size == (1024, 1024), opened.size
assert np.isfinite(pixels).all() and pixels.std() > 1, 'Invalid/blank image'
result['images'].append({'path': str(image.relative_to(ROOT)),
'sha256': hashlib.sha256(image.read_bytes()).hexdigest(),
'width': opened.width, 'height': opened.height,
'pixel_std': round(float(pixels.std()), 3)})
if status != 'success' or not result['images']:
result['status'] = 'failed'
report['runs'][variant] = result
report_path.write_text(json.dumps(report, indent=2) + '\n')
print(json.dumps(result), flush=True)
assert result['status'] == 'success', history['status']
print('All three generation runs passed.', flush=True)
if __name__ == '__main__':
main()

Xet Storage Details

Size:
4.64 kB
·
Xet hash:
bbd7230d92ad7c40696ad07e448edbff66d66a24cfe96866fb233beb30a40b62

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.