Stable Diffusion Checkpoint คืออะไร — คู่มือฉบับสมบูรณ์
Stable Diffusion Checkpoint คือไฟล์ model weights ที่เก็บ parameters ทั้งหมดของ Stable Diffusion model ซึ่งกำหนดว่า model จะสร้างภาพแบบไหน Checkpoint แต่ละตัวถูก train ด้วย dataset ที่ต่างกัน ทำให้ได้ style และความสามารถที่แตกต่าง เช่น realistic photography, anime, fantasy art หรือ architectural visualization การเลือก checkpoint ที่เหมาะสมเป็นขั้นตอนสำคัญที่สุดในการสร้างภาพคุณภาพสูง บทความนี้อธิบายทุกอย่างเกี่ยวกับ checkpoints พร้อม Python tools สำหรับจัดการ
Checkpoint Fundamentals
# checkpoint_basics.py — Checkpoint fundamentals
import json
class CheckpointBasics:
TYPES = {
"base_model": {
"name": "Base Model Checkpoint",
"description": "Model หลักที่ train จาก scratch — SD 1.5, SDXL 1.0, SD 3.0",
"size": "SD 1.5: ~4GB, SDXL: ~6.5GB",
"use": "ใช้เป็น foundation สำหรับ fine-tune หรือใช้ตรงๆ",
},
"fine_tuned": {
"name": "Fine-tuned Checkpoint",
"description": "Base model ที่ train เพิ่มด้วย specific dataset — Realistic Vision, DreamShaper",
"size": "เท่า base model (~4-7GB)",
"use": "สร้างภาพ style เฉพาะทาง — realistic, anime, fantasy",
},
"merged": {
"name": "Merged Checkpoint",
"description": "รวม 2+ checkpoints เข้าด้วยกัน — ได้ style ผสม",
"size": "เท่า base model",
"use": "ผสม style — เช่น realistic + anime = semi-realistic",
},
"pruned": {
"name": "Pruned Checkpoint",
"description": "ตัด training data ออก เหลือเฉพาะ inference weights — ไฟล์เล็กลง",
"size": "SD 1.5: ~2GB (pruned) vs ~4GB (full)",
"use": "เหมือน full แต่เล็กกว่า — แนะนำสำหรับ inference",
},
}
FORMATS = {
"safetensors": {
"name": ".safetensors",
"description": "Format ใหม่ ปลอดภัย — ไม่มี arbitrary code execution risk",
"recommended": True,
},
"ckpt": {
"name": ".ckpt (pickle)",
"description": "Format เก่า — มี security risk (pickle deserialization)",
"recommended": False,
},
"diffusers": {
"name": "Diffusers format (folder)",
"description": "HuggingFace Diffusers — แยก components เป็น files ย่อย",
"recommended": True,
},
}
def show_types(self):
print("=== Checkpoint Types ===\n")
for key, t in self.TYPES.items():
print(f"[{t['name']}]")
print(f" {t['description']}")
print(f" Size: {t['size']}")
print()
def show_formats(self):
print("=== File Formats ===")
for key, f in self.FORMATS.items():
rec = "✅ Recommended" if f['recommended'] else "⚠️ Not recommended"
print(f" [{f['name']}] {f['description']} — {rec}")
basics = CheckpointBasics()
basics.show_types()
basics.show_formats()
Popular Checkpoints
# popular.py — Popular Stable Diffusion checkpoints
import json
class PopularCheckpoints:
SD15 = {
"realistic_vision": {
"name": "Realistic Vision V6.0",
"style": "Photorealistic — ภาพเหมือนจริงมาก",
"base": "SD 1.5",
"best_for": "Portrait, landscape, product photography",
},
"dreamshaper": {
"name": "DreamShaper V8",
"style": "Versatile — ทำได้หลาย style (realistic, fantasy, anime)",
"base": "SD 1.5",
"best_for": "General purpose, concept art, illustrations",
},
"deliberate": {
"name": "Deliberate V5",
"style": "Artistic — สีสดใส องค์ประกอบดี",
"base": "SD 1.5",
"best_for": "Digital art, portraits, fantasy",
},
"anything_v5": {
"name": "Anything V5",
"style": "Anime — anime/manga style คุณภาพสูง",
"base": "SD 1.5",
"best_for": "Anime characters, manga illustrations",
},
}
SDXL = {
"juggernaut_xl": {
"name": "Juggernaut XL V9",
"style": "Photorealistic — คุณภาพสูงสุดสำหรับ SDXL",
"base": "SDXL 1.0",
"best_for": "Photorealism, portraits, landscapes",
},
"dreamshaperxl": {
"name": "DreamShaper XL",
"style": "Versatile — all-purpose SDXL model",
"base": "SDXL 1.0",
"best_for": "General purpose, digital art",
},
"animagine_xl": {
"name": "Animagine XL V3.1",
"style": "Anime — best anime model สำหรับ SDXL",
"base": "SDXL 1.0",
"best_for": "Anime, manga, light novel illustrations",
},
}
def show_sd15(self):
print("=== SD 1.5 Checkpoints ===\n")
for key, cp in self.SD15.items():
print(f"[{cp['name']}]")
print(f" Style: {cp['style']}")
print(f" Best for: {cp['best_for']}")
print()
def show_sdxl(self):
print("=== SDXL Checkpoints ===")
for key, cp in self.SDXL.items():
print(f"[{cp['name']}]")
print(f" Style: {cp['style']}")
print(f" Best for: {cp['best_for']}")
print()
popular = PopularCheckpoints()
popular.show_sd15()
popular.show_sdxl()
Python Checkpoint Manager
# manager.py — Python checkpoint management
import json
class CheckpointManager:
CODE = """
# ckpt_manager.py — Manage Stable Diffusion checkpoints
import os
import json
import hashlib
from pathlib import Path
from datetime import datetime
class SDCheckpointManager:
def __init__(self, models_dir="./models/Stable-diffusion"):
self.models_dir = Path(models_dir)
self.models_dir.mkdir(parents=True, exist_ok=True)
def list_checkpoints(self):
'''List all checkpoints'''
checkpoints = []
for ext in ['*.safetensors', '*.ckpt']:
for f in self.models_dir.glob(ext):
stat = f.stat()
checkpoints.append({
'name': f.stem,
'filename': f.name,
'format': f.suffix,
'size_gb': round(stat.st_size / (1024**3), 2),
'modified': datetime.fromtimestamp(stat.st_mtime).isoformat(),
})
return sorted(checkpoints, key=lambda x: x['name'])
def get_hash(self, filename, algorithm='sha256'):
'''Calculate file hash for verification'''
filepath = self.models_dir / filename
h = hashlib.new(algorithm)
with open(filepath, 'rb') as f:
while chunk := f.read(8192):
h.update(chunk)
return h.hexdigest()[:10] # Short hash like CivitAI uses
def check_vram_requirement(self, filename):
'''Estimate VRAM requirement'''
size_gb = (self.models_dir / filename).stat().st_size / (1024**3)
if size_gb < 3:
return {'model_type': 'SD 1.5 pruned', 'min_vram': '4GB', 'recommended': '6GB+'}
elif size_gb < 5:
return {'model_type': 'SD 1.5 full', 'min_vram': '4GB', 'recommended': '8GB+'}
elif size_gb < 8:
return {'model_type': 'SDXL', 'min_vram': '6GB', 'recommended': '12GB+'}
else:
return {'model_type': 'Large model', 'min_vram': '8GB+', 'recommended': '16GB+'}
def download_from_civitai(self, model_id, version_id=None):
'''Download checkpoint from CivitAI'''
import requests
url = f"https://civitai.com/api/v1/models/{model_id}"
resp = requests.get(url)
model_info = resp.json()
version = model_info['modelVersions'][0] if not version_id else next(
v for v in model_info['modelVersions'] if v['id'] == version_id
)
download_url = version['files'][0]['downloadUrl']
filename = version['files'][0]['name']
print(f"Downloading {filename}...")
resp = requests.get(download_url, stream=True)
filepath = self.models_dir / filename
with open(filepath, 'wb') as f:
for chunk in resp.iter_content(chunk_size=8192):
f.write(chunk)
return {'filename': filename, 'path': str(filepath)}
def generate_report(self):
'''Generate checkpoint inventory report'''
checkpoints = self.list_checkpoints()
total_size = sum(c['size_gb'] for c in checkpoints)
return {
'total_checkpoints': len(checkpoints),
'total_size_gb': round(total_size, 2),
'formats': {
'.safetensors': sum(1 for c in checkpoints if c['format'] == '.safetensors'),
'.ckpt': sum(1 for c in checkpoints if c['format'] == '.ckpt'),
},
'checkpoints': checkpoints,
}
# mgr = SDCheckpointManager("./models/Stable-diffusion")
# print(json.dumps(mgr.generate_report(), indent=2))
"""
def show_code(self):
print("=== Checkpoint Manager ===")
print(self.CODE[:600])
mgr = CheckpointManager()
mgr.show_code()
Checkpoint Merging
# merging.py — Checkpoint merging techniques
import json
class CheckpointMerging:
METHODS = {
"weighted_sum": {
"name": "Weighted Sum (WS)",
"formula": "Output = A × (1 - alpha) + B × alpha",
"description": "ผสม 2 models ด้วย weight ratio — alpha 0.5 = 50/50",
"use_case": "ผสม style 2 models เช่น realistic + artistic",
},
"add_difference": {
"name": "Add Difference",
"formula": "Output = A + (B - C) × alpha",
"description": "เพิ่ม 'ความแตกต่าง' ระหว่าง B กับ C เข้าไปใน A",
"use_case": "เพิ่ม specific feature จาก model หนึ่งไปอีก model",
},
"block_merge": {
"name": "Block Merge (MBW)",
"formula": "แต่ละ block ของ U-Net ใช้ alpha ต่างกัน",
"description": "ปรับ weight ratio ระดับ layer — ละเอียดที่สุด",
"use_case": "ผสมเฉพาะ style (early blocks) หรือ details (late blocks)",
},
}
TIPS = [
"เริ่มจาก alpha = 0.3 แล้วปรับ — ไม่ต้อง 50/50 เสมอ",
"ใช้ .safetensors format — เร็วกว่า .ckpt ในการ merge",
"Test ด้วย prompt เดิม เปรียบเทียบ output",
"Block merge: IN blocks = composition, OUT blocks = details/style",
"Merge 2 models เท่านั้น — merge 3+ จะสูญเสีย coherence",
]
def show_methods(self):
print("=== Merging Methods ===\n")
for key, method in self.METHODS.items():
print(f"[{method['name']}]")
print(f" Formula: {method['formula']}")
print(f" {method['description']}")
print()
def show_tips(self):
print("=== Merging Tips ===")
for tip in self.TIPS:
print(f" • {tip}")
merge = CheckpointMerging()
merge.show_methods()
merge.show_tips()
LoRA vs Checkpoint
# lora_vs_ckpt.py — LoRA vs Checkpoint comparison
import json
class LoRAvsCheckpoint:
COMPARISON = {
"checkpoint": {
"name": "Checkpoint (Full Model)",
"size": "2-7 GB",
"training": "หลายชั่วโมง-วัน, GPU RAM เยอะ (12GB+)",
"quality": "สูงสุด — ปรับ model ทั้งหมด",
"flexibility": "ใช้เดี่ยวๆ — ไม่ต้อง base model",
"stacking": "ไม่ได้ — ใช้ได้ทีละ 1 checkpoint",
},
"lora": {
"name": "LoRA (Low-Rank Adaptation)",
"size": "10-200 MB",
"training": "นาที-ชั่วโมง, GPU RAM น้อยกว่า (6GB+)",
"quality": "ดี — ปรับ specific aspects (style, character, concept)",
"flexibility": "ต้องใช้กับ base checkpoint",
"stacking": "ได้ — ใช้หลาย LoRA พร้อมกัน (style + character + pose)",
},
}
WHEN_TO_USE = {
"checkpoint": [
"ต้องการเปลี่ยน style ทั้ง model (realistic → anime)",
"ต้องการคุณภาพสูงสุด",
"มี GPU แรงและเวลา train",
],
"lora": [
"ต้องการ specific character/style/concept",
"ต้องการ mix & match หลาย styles",
"GPU/VRAM จำกัด",
"ต้องการ train เร็ว",
],
}
def show_comparison(self):
print("=== Checkpoint vs LoRA ===\n")
for key in ['checkpoint', 'lora']:
item = self.COMPARISON[key]
print(f"[{item['name']}]")
for k, v in item.items():
if k != 'name':
print(f" {k}: {v}")
print()
def show_when(self):
print("=== When to Use ===")
for key, reasons in self.WHEN_TO_USE.items():
print(f"\n Use {key} when:")
for r in reasons:
print(f" • {r}")
comp = LoRAvsCheckpoint()
comp.show_comparison()
comp.show_when()
FAQ - คำถามที่พบบ่อย
Q: ดาวน์โหลด checkpoint ที่ไหน?
A: CivitAI (civitai.com): แหล่งใหญ่ที่สุด — filter ตาม style, base model, rating HuggingFace: official models + community models — ใช้กับ Diffusers library GitHub: บาง models host บน GitHub releases เลือก: ดู rating, downloads, sample images, license ก่อนดาวน์โหลด ระวัง: ใช้ .safetensors เท่านั้น — .ckpt มี security risk
Q: SD 1.5 กับ SDXL อันไหนดีกว่า?
A: SDXL: คุณภาพสูงกว่า, resolution สูงกว่า (1024x1024 vs 512x512), ต้อง VRAM 6GB+ SD 1.5: เร็วกว่า, VRAM น้อยกว่า (4GB), ecosystem ใหญ่กว่า (LoRA, ControlNet) แนะนำ SDXL: ถ้ามี GPU 8GB+ → คุณภาพดีกว่าชัดเจน แนะนำ SD 1.5: ถ้า GPU 4-6GB หรือต้องการ speed + LoRA variety
Q: Pruned กับ Full checkpoint ต่างกันอย่างไร?
A: Full: มี training data + optimizer states → ไฟล์ใหญ่, ใช้สำหรับ continue training Pruned: เหลือเฉพาะ inference weights → ไฟล์เล็กลง 50%, สร้างภาพเหมือนกันเป๊ะ สำหรับใช้งาน: ใช้ pruned เสมอ — เล็กกว่า, โหลดเร็วกว่า, output เหมือนกัน สำหรับ train/merge: ใช้ full — มี data ครบสำหรับ fine-tuning
Q: VRAM ไม่พอ ทำยังไง?
A: Optimizations: --medvram หรือ --lowvram flag ใน Automatic1111 xFormers: ลด VRAM usage 30-50% — --xformers flag FP16: ใช้ half precision — ลด VRAM ลงครึ่ง (default ใน UI ส่วนใหญ่) Tiled VAE: แบ่ง decode เป็นส่วนๆ — ลด VRAM สำหรับ high-res SD 1.5 pruned + --medvram: ใช้ได้บน 4GB VRAM สุดท้าย: ใช้ CPU inference (ช้าแต่ไม่ต้อง GPU) หรือ cloud GPU (RunPod, Vast.ai)
