Buckets:
| #!/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.