Instructions to use ACCC1380/realstyle2_anima with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use ACCC1380/realstyle2_anima with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("circlestone-labs/Anima", dtype=torch.bfloat16, device_map="cuda") pipe.load_lora_weights("ACCC1380/realstyle2_anima") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- Draw Things
- DiffusionBee
Download scripts/package_upload.py from ACCC1380/realstyle2_anima: direct link, hf CLI and curl.
- Browser
- Download file 8.06 kB
-
https://huggingface.co/ACCC1380/realstyle2_anima/resolve/main/scripts/package_upload.py
- Command line
-
hf download hf://ACCC1380/realstyle2_anima/scripts/package_upload.py
-
curl -L -o package_upload.py https://huggingface.co/ACCC1380/realstyle2_anima/resolve/main/scripts/package_upload.py
8.06 kB
| """Validate completed training and upload artifacts without training images.""" | |
| import hashlib | |
| import json | |
| import os | |
| import shutil | |
| import subprocess | |
| import time | |
| import zipfile | |
| from pathlib import Path | |
| import torch | |
| import toml | |
| from huggingface_hub import HfApi | |
| from safetensors import safe_open | |
| ROOT = Path('/data/realstyle2') | |
| OUT = ROOT / 'output' | |
| UPLOAD = ROOT / 'upload' | |
| REPO = 'ACCC1380/realstyle2_anima' | |
| config = toml.load(ROOT / 'configs/train.toml') | |
| final = OUT / 'realstyle2_anima.safetensors' | |
| assert final.is_file(), 'Final checkpoint missing' | |
| torch.set_num_threads(4) | |
| with safe_open(final, framework='pt') as model: | |
| metadata = model.metadata() | |
| epochs = int(metadata['ss_epoch']) | |
| steps = int(metadata['ss_steps']) | |
| for key in model.keys(): | |
| assert torch.isfinite(model.get_tensor(key)).all(), f'Non-finite tensor: {key}' | |
| assert epochs in {30, 35, 40}, f'Unexpected epoch count: {epochs}' | |
| numbered_final = OUT / f'realstyle2_anima-{epochs:06d}.safetensors' | |
| if not numbered_final.exists(): | |
| shutil.copyfile(final, numbered_final) | |
| checks = [] | |
| for epoch in range(1, epochs + 1): | |
| path = OUT / f'realstyle2_anima-{epoch:06d}.safetensors' | |
| assert path.is_file(), f'Missing epoch {epoch}' | |
| with safe_open(path, framework='pt') as checkpoint: | |
| meta = checkpoint.metadata() | |
| assert int(meta['ss_epoch']) == epoch | |
| assert checkpoint.keys() | |
| for key in checkpoint.keys(): | |
| assert torch.isfinite(checkpoint.get_tensor(key)).all(), f'Non-finite tensor at epoch {epoch}: {key}' | |
| checks.append({'file': path.name, 'epoch': epoch, 'steps': int(meta['ss_steps']), | |
| 'bytes': path.stat().st_size, 'sha256': hashlib.file_digest(path.open('rb'), 'sha256').hexdigest()}) | |
| summary = {'status': 'training_complete', 'epochs': epochs, 'steps': steps, | |
| 'batch_size': config['train_batch_size'], 'gradient_checkpointing': config['gradient_checkpointing'], | |
| 'optimizer': config['optimizer_type'], 'learning_rate': config['learning_rate'], | |
| 'scheduler': config['lr_scheduler'], 'rank': config['network_dim'], 'alpha': config['network_alpha'], | |
| 'source_requested': 'ACCC1380/realstyle2', 'source_actual': 'ACCC1380/realskin2', | |
| 'destination': REPO, 'checkpoints': checks, 'final_metadata': metadata, | |
| 'trainer_commit': subprocess.check_output(['git', '-C', '/data/lora-scripts-next', 'rev-parse', 'HEAD'], text=True).strip()} | |
| (ROOT / 'metadata/training_summary.json').write_text(json.dumps(summary, indent=2)) | |
| (ROOT / 'metadata/environment.txt').write_text(subprocess.check_output(['/data/venv-training/bin/pip', 'freeze'], text=True)) | |
| for folder in ['configs', 'scripts', 'metadata']: | |
| shutil.copytree(ROOT / folder, UPLOAD / folder, dirs_exist_ok=True) | |
| shutil.copytree(ROOT / 'logs', UPLOAD / 'logs', dirs_exist_ok=True) | |
| for path in OUT.glob('*.safetensors'): | |
| dest = UPLOAD / path.name | |
| if not dest.exists(): | |
| shutil.copyfile(path, dest) | |
| for state in OUT.glob('*state'): | |
| if state.is_dir(): | |
| shutil.copytree(state, UPLOAD / 'resume_state' / state.name, dirs_exist_ok=True) | |
| with zipfile.ZipFile(UPLOAD / 'training_data_without_images.zip', 'w', zipfile.ZIP_DEFLATED, compresslevel=1) as archive: | |
| for folder in ['dataset', 'configs', 'scripts', 'metadata']: | |
| for path in sorted((ROOT / folder).rglob('*')): | |
| if path.is_file() and path.suffix.lower() not in {'.png', '.jpg', '.jpeg', '.webp', '.bmp', '.gif', '.pyc'}: | |
| archive.write(path, path.relative_to(ROOT)) | |
| with zipfile.ZipFile(UPLOAD / 'lora_scripts_next_source.zip', 'w', zipfile.ZIP_DEFLATED, compresslevel=1) as archive: | |
| source = Path('/data/lora-scripts-next') | |
| for path in sorted(source.rglob('*')): | |
| relative = path.relative_to(source) | |
| if path.is_file() and not any(p in {'.git', '__pycache__', 'node_modules', 'huggingface', 'logs'} for p in relative.parts): | |
| archive.write(path, relative) | |
| stats = json.loads((ROOT / 'metadata/tag_summary.json').read_text()) | |
| card = f'''--- | |
| base_model: circlestone-labs/Anima | |
| library_name: diffusers | |
| tags: | |
| - lora | |
| - anima | |
| - text-to-image | |
| - style | |
| --- | |
| # realstyle2 Anima LoRA | |
| 基于本地 `anima-base-v1.0.safetensors`,使用 lora-scripts-next 标准 Anima 后端训练。 | |
| **数据来源说明:** 请求中的 `ACCC1380/realstyle2` 在执行时不存在(model/dataset 均返回 404)。根据同账号仓库,将其视为名称笔误,实际使用 `ACCC1380/realskin2` 的 `realskin2.zip`(revision `fda57fa984e9cf9cbb964929a6a8431b59976a28`)。未经用户再次确认,因为用户明确要求无人值守完成。 | |
| - 数据:{stats['images']} 张图片,1 repeat;训练集图片未上传至本仓库。 | |
| - 打标:PixAI Tagger v1.0,平均 {stats['mean_tags']:.1f} 个标签/图;阈值详见 `metadata/tagger_settings.json`。 | |
| - 触发词:`realstyle2`。 | |
| - 完成:{epochs} epochs,{steps} steps,每轮均保存。`realstyle2_anima.safetensors` 为最终权重,与第 {epochs} 轮相同。 | |
| - Batch size:{config['train_batch_size']};梯度检查点关闭;gradient accumulation 1。 | |
| - AdamW,learning rate 1e-4,constant,无 warmup。 | |
| - LoRA rank 32 / alpha 16;BF16;1024 分桶;冻结文本编码器;缓存 latents 和文本编码。 | |
| - timestep sampling sigmoid,flow shift 1.0,uniform loss weighting。 | |
| - 所有 epoch 权重均检查 tensor 有限值和 epoch 元数据。未进行人工生成效果评测。 | |
| ## 文件 | |
| `realstyle2_tags.zip`:与原图同名的 caption TXT。 | |
| `training_data_without_images.zip`:caption、latent/text encoder 缓存、配置、脚本、元数据,排除训练图片。 | |
| `lora_scripts_next_source.zip`:所用训练器源码快照;依赖见 `metadata/environment.txt`。 | |
| `resume_state/`:训练恢复状态;`logs/`:完整日志及 TensorBoard 数据;`metadata/training_summary.json`:训练参数、基础模型元数据和各轮 SHA256。 | |
| 所有本地任务文件位于 `/data/realstyle2`;训练器位于 `/data/lora-scripts-next`。原有基础模型从 `/marimo` 读取。 | |
| ''' | |
| (UPLOAD / 'README.md').write_text(card) | |
| for path in UPLOAD.rglob('*'): | |
| assert not (path.is_file() and path.suffix.lower() in {'.png', '.jpg', '.jpeg', '.webp', '.bmp', '.gif'}), f'Unexpected image: {path}' | |
| api = HfApi() | |
| for attempt in range(1, 7): | |
| try: | |
| print(f'Upload attempt {attempt}: {REPO}', flush=True) | |
| commit = api.upload_folder(repo_id=REPO, folder_path=UPLOAD, | |
| commit_message=f'Add {epochs}-epoch Anima LoRA, PixAI captions and training artifacts (no dataset images)', | |
| ignore_patterns=['.cache/**', '*.pyc']) | |
| expected = {p.relative_to(UPLOAD).as_posix(): p.stat().st_size for p in UPLOAD.rglob('*') if p.is_file() and '.cache' not in p.parts} | |
| info = api.repo_info(REPO, files_metadata=True) | |
| remote = {p.rfilename: p for p in info.siblings} | |
| for name, size in expected.items(): | |
| assert name in remote, f'Missing upload: {name}' | |
| assert remote[name].size == size, f'Size mismatch: {name}' | |
| for check in checks: | |
| lfs = remote[check['file']].lfs | |
| if lfs: | |
| assert lfs.sha256 == check['sha256'], f'Hash mismatch: {check["file"]}' | |
| receipt = {'status': 'complete', 'repo': REPO, 'commit': commit.oid, | |
| 'url': commit.commit_url, 'verified_files': len(expected), | |
| 'bytes': sum(expected.values()), 'epochs': epochs, 'steps': steps, | |
| 'verified_at': time.time()} | |
| (ROOT / 'upload_receipt.json').write_text(json.dumps(receipt, indent=2)) | |
| api.upload_file(repo_id=REPO, path_or_fileobj=ROOT / 'upload_receipt.json', path_in_repo='upload_receipt.json', commit_message='Record verified upload receipt') | |
| print(json.dumps(receipt), flush=True) | |
| break | |
| except Exception as exc: | |
| print(f'Upload failed {type(exc).__name__}: {exc}', flush=True) | |
| if attempt == 6: | |
| raise | |
| time.sleep(30) | |