Text-to-Image
Diffusers
Safetensors
English
MOSSImagePipeline
moss-image
16gb
structured-pruning
alpha
Instructions to use AiArtLab/mossling with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use AiArtLab/mossling 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/mossling", 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: 4,398 Bytes
3467e0f | 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 | #!/usr/bin/env python3
"""Отфильтровать готовый датасет (`make_dataset.py`) в новый, не пересчитывая латенты.
Латенты VAE — самая дорогая часть нарезки (часы GPU), а фильтр работает по тексту капшена.
Поэтому здесь ничего не кодируется заново: читаем arrow-файлы, отбрасываем строки
по правилам из `train.py` (FILTER_RULES) и пишем урезанный датасет в `--save`.
Структуру сохраняем один-в-один: каждый исходный `chunk_*/sub_*` даёт один новый
`chunk_*/sub_*` (только без отброшенных строк). Поэтому группы уже однородны по размеру
картинки — `make_dataset.py` писал их именно так, — и батчи в `train.py` остаются
одинаковыми по HxW. Никакой перегруппировки и, значит, никаких копий латентов в RAM.
Запуск:
python3 src/filter_dataset.py --src src/work/ds_testg_full --save src/work/ds_testg_filtered
python3 src/filter_dataset.py --src ... --save ... --filter views,text,multi,long
"""
import argparse
import os
import shutil
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import filters as F # noqa: E402 (правила отбраковки капшенов)
import train as T # noqa: E402 (только find_dataset_chunks — как train.py ищет чанки)
def parse_args():
p = argparse.ArgumentParser(description="Датасет -> отфильтрованный датасет (без пересчёта латентов)")
p.add_argument("--src", required=True, help="папка с готовым датасетом (chunk_*/sub_*)")
p.add_argument("--save", required=True, help="куда сохранить отфильтрованный")
p.add_argument("--filter", default="all",
help=f"группы через запятую ({', '.join(F.FILTER_GROUPS)}) или 'all'")
return p.parse_args()
def main():
args = parse_args()
groups = tuple(g.strip() for g in args.filter.split(",") if g.strip())
if "all" in groups:
groups = F.FILTER_GROUPS
bad = [g for g in groups if g not in F.FILTER_GROUPS]
if bad:
raise SystemExit(f"--filter: неизвестные группы {bad}; есть {list(F.FILTER_GROUPS)}")
from datasets import load_from_disk
srcs = sorted(p for p in T.find_dataset_chunks(args.src) if p.startswith(
os.path.join(args.src, "chunk_")))
if not srcs:
raise SystemExit(f"в {args.src} нет чанков chunk_*/sub_*")
print(f"группы: {', '.join(groups)}", flush=True)
os.makedirs(args.save, exist_ok=True)
dropped = {g: 0 for g in F.FILTER_GROUPS}
total = kept = 0
for src in srcs:
ds = load_from_disk(src)
keep = [i for i, text in enumerate(ds["text"])
if not _is_musor(text, groups, dropped)]
total += len(ds)
if not keep:
print(f" {os.path.relpath(src, args.src)}: 0 из {len(ds)} — группа пустая", flush=True)
continue
rel = os.path.relpath(src, args.src)
dst = os.path.join(args.save, rel)
if os.path.isdir(dst):
shutil.rmtree(dst) # пересборка с нуля
os.makedirs(os.path.dirname(dst), exist_ok=True)
ds.select(keep).save_to_disk(dst)
open(os.path.join(os.path.dirname(dst), ".done"), "w").close()
kept += len(keep)
print(f" {rel}: {len(keep)} из {len(ds)}", flush=True)
total_dropped = total - kept
print(f"\nвсего {total}, отброшено {total_dropped} "
f"({total_dropped / max(total, 1):.1%}), осталось {kept}", flush=True)
for g, c in dropped.items():
if c:
print(f" {g:8} {c:6d} {c / max(total, 1):5.1%}", flush=True)
print(f"готово -> {args.save}", flush=True)
def _is_musor(text, groups, dropped):
reason = F.filter_reason(text, groups)
if reason is not None:
dropped[reason] += 1
return reason is not None
if __name__ == "__main__":
main()
|