Text-to-Image
Diffusers
Safetensors
flow-matching
pyramidal-unet
256x256
ettin-150m
from-scratch
ra
udit
Instructions to use AiArtLab/Ra with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use AiArtLab/Ra with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("AiArtLab/Ra", dtype=torch.bfloat16, device_map="cuda") 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
File size: 3,413 Bytes
b4f5f26 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | """Сборка набора из папки «картинка + .txt»: бакеты (кратны --multiple) и центр-кроп.
python3 src/make_dataset.py --src ~/dataset/butterflies/butterfly \
--out ~/dataset/butterflies_256 --long-side 256 --eval-n 30
"""
from __future__ import annotations
import argparse
import csv
import math
import random
from pathlib import Path
from PIL import Image, ImageOps
BUCKETS = {}
def buckets(long_side: int, multiple: int = 16) -> dict:
L = long_side
def r16(x): return max(multiple, int(round(x / multiple)) * multiple)
return {
"1:1": (L, L),
"4:3": (L, r16(L * 3 / 4)),
"3:4": (r16(L * 3 / 4), L),
"3:2": (L, r16(L * 2 / 3)),
"2:3": (r16(L * 2 / 3), L),
"16:9": (L, r16(L * 9 / 16)),
"9:16": (r16(L * 9 / 16), L),
}
def plan_size(w, h, max_upscale=1.4):
ratio = w / h
label, (tw, th) = min(BUCKETS.items(), key=lambda kv: abs(math.log(ratio / (kv[1][0] / kv[1][1]))))
if ratio > tw / th:
cw, ch = round(h * tw / th), h
else:
cw, ch = w, round(w * th / tw)
cw, ch = min(cw, w), min(ch, h)
if cw * max_upscale < tw or ch * max_upscale < th:
return None
return label, tw, th, cw, ch
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--src", required=True)
ap.add_argument("--out", required=True)
ap.add_argument("--long-side", type=int, default=256)
ap.add_argument("--eval-n", type=int, default=30)
ap.add_argument("--max-upscale", type=float, default=1.4)
ap.add_argument("--multiple", type=int, default=64,
help="кратность сторон: три даунсэмпла тела требуют латент, кратный 8")
ap.add_argument("--seed", type=int, default=0)
args = ap.parse_args()
global BUCKETS
BUCKETS = buckets(args.long_side, args.multiple)
src, out = Path(args.src), Path(args.out)
for sub in ("train", "eval"):
(out / sub).mkdir(parents=True, exist_ok=True)
pairs = []
for img in sorted(list(src.glob("*.png")) + list(src.glob("*.jpg"))):
txt = img.with_suffix(".txt")
if txt.exists():
pairs.append((img, txt))
random.Random(args.seed).shuffle(pairs)
print(f"пар: {len(pairs)}")
rows, kept = [], 0
for i, (img, txt) in enumerate(pairs):
im = ImageOps.exif_transpose(Image.open(img)).convert("RGB")
plan = plan_size(im.width, im.height, args.max_upscale)
if plan is None:
continue
label, tw, th, cw, ch = plan
left, top = (im.width - cw) // 2, (im.height - ch) // 2
im = im.crop((left, top, left + cw, top + ch)).resize((tw, th), Image.LANCZOS)
split = "eval" if i < args.eval_n else "train"
name = f"{img.stem}"
im.save(out / split / f"{name}.jpg", quality=95)
(out / split / f"{name}.txt").write_text(txt.read_text().strip() + "\n")
rows.append({"split": split, "name": name, "w": tw, "h": th, "bucket": label})
kept += 1
with open(out / "index.csv", "w", newline="") as fh:
w = csv.DictWriter(fh, fieldnames=["split", "name", "w", "h", "bucket"])
w.writeheader(); w.writerows(rows)
print(f"готово: {kept} (train {kept-args.eval_n}, eval {args.eval_n}) -> {out}")
if __name__ == "__main__":
main()
|