LoRA(Low-Rank Adaptation,低秩适配)是一种微调技术,用一小组示例图像教会 AI 模型一种新的视觉风格。它通过向已有模型注入新的”风格权重”来实现,训练既快又高效。
本指南将带你完成完整的工作流:
准备训练图像
挑选并上传能代表你所需风格的高质量图像
提交训练任务
使用你的图像 URL 和配置向 /styles/train 发送 POST 请求
监控进度
使用返回的 job_id 跟踪训练任务状态
准备训练图像
筛选你的数据集
训练图像的质量直接影响结果。不同的训练类型有不同的要求:
| 类型 | 适用场景 | 建议 |
|---|
| Style | 艺术风格、视觉美学 | 在不同主题间保持风格一致 |
| Character | 人物形象、一致的角色 | 姿势、表情、光照多样 |
| Object | 特定物品、产品 | 多角度,物体一致 |
需要多少张图像?
质量远比数量重要。少量优秀的图像会胜过大量平庸的图像。
| 数据集大小 | 指导建议 |
|---|
| 5 张图像 | 最低可用。适合简单、一致的风格 |
| 10-30 张图像 | 推荐。质量和覆盖度的最佳平衡 |
| 50+ 张图像 | 收益递减,除非风格差异很大 |
质量 > 数量15 张高质量图像会比 50 张低质量图像产出更好的结果。优先考虑:
- 高分辨率(最少 1024x1024)
- 所有图像的风格保持一致
- 没有水印、文字覆盖或压缩伪影
- 主题多样但风格保持一致
上传图像
训练之前,先上传图像获取托管 URL。使用 /assets 端点:
import requests
import os
from dotenv import load_dotenv
import mimetypes
load_dotenv()
API_BASE = "https://api.krea.ai"
API_TOKEN = os.getenv("API_TOKEN")
image_dir = "training_images"
uploaded_urls = []
for filename in os.listdir(image_dir):
if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.webp')):
filepath = os.path.join(image_dir, filename)
mime_type, _ = mimetypes.guess_type(filepath)
with open(filepath, 'rb') as f:
response = requests.post(
f"{API_BASE}/assets",
headers={"Authorization": f"Bearer {API_TOKEN}"},
files={"file": (filename, f, mime_type)},
data={"description": f"Training image: {filename}"}
)
if response.ok:
data = response.json()
uploaded_urls.append(data["image_url"])
print(f"Uploaded: {filename}")
else:
print(f"Failed: {filename}")
print(f"\nUploaded {len(uploaded_urls)} images")
保存返回的 image_url 值——你将把这些值传递给训练端点。
训练你的风格
基础训练示例
提交你的图像 URL 开始训练:
import requests
import os
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.krea.ai"
API_TOKEN = os.getenv("API_TOKEN")
# Training URLs from the upload step
urls = [
"https://krea.ai/assets/img1.jpg",
"https://krea.ai/assets/img2.jpg",
"https://krea.ai/assets/img3.jpg",
# ... more images
]
response = requests.post(
f"{API_BASE}/styles/train",
headers={
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
},
json={
"name": "Ukiyo-E Style",
"urls": urls,
"model": "flux_dev",
"type": "Style",
"max_train_steps": 500
}
)
response.raise_for_status()
job = response.json()
print(f"Training started! Job ID: {job['job_id']}")
训练类型
type 参数会为你的使用场景设置针对性的智能默认值:
| 类型 | 最适合 |
|---|
Style | 艺术风格、视觉美学 |
Character | 人物形象、一致的角色 |
Object | 特定物品、产品 |
Default | 通用训练 |
必需参数
你的自定义风格的描述性名称。示例: "Ukiyo-E Style"、"Product Photos"
用于训练的图像 URL 数组。加入更多图像可获得更好的结果。
可选参数
用于训练的基础模型:图像模型:
flux_dev - 高质量、通用
flux_schnell - BFL 的实时模型
qwen - 阿里巴巴的模型
z-image - 阿里巴巴的高效图像模型
wan22 - 仅图像生成
视频模型:
训练类别:Style、Object、Character 或 Default
用于在提示词中激活此风格的自定义单词。未指定时使用风格名称。选择不会出现在常见提示词中的独特触发词。多词触发词使用下划线:ukiyo_style
控制训练强度。更高的值训练更快,但可能过拟合。推荐范围: 0.0001 - 0.001
同时处理的图像数量。较大的批次训练更快,但占用更多内存。
调整高级参数
先使用 type 字段所设置的默认值——它们适用于大多数情况。只有在遇到特定问题时才需要调整:
控制模型对训练图像的适应程度。| 值 | 何时使用 |
|---|
| 0.0001(较低) | 过拟合问题、复杂风格、小数据集 |
| 0.0003(默认) | 大多数场景 |
| 0.0005-0.001(较高) | 更快的训练 |
需要调整的信号:
- 输出看起来与训练图像一模一样 → 降低学习率
- 训练后风格影响很弱 → 稍微提高学习率
模型在你的图像上训练多久。| 数据集大小 | 推荐步数 |
|---|
| 5-10 张图像 | 300-500 步 |
| 15-30 张图像 | 500-800 步 |
| 50+ 张图像 | 800-1500 步 |
需要调整的信号:
- 输出过于僵硬,忽略提示词 → 减少步数
- 风格影响很弱 → 增加步数
- 生成的图像看起来完全和训练数据一样 → 减少步数(过拟合)
迭代式调优如果你的第一次训练没有产生想要的结果:
- 先调整
max_train_steps(最常见的修正)
- 如果单独调整步数无效,再尝试
learning_rate
响应格式
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"created_at": "2024-01-15T10:30:00Z"
}
监控训练进度
训练通常需要 5-15 分钟。轮询 Jobs API 检查状态:
import requests
import time
import os
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.krea.ai"
API_TOKEN = os.getenv("API_TOKEN")
job_id = "your-job-id"
while True:
response = requests.get(
f"{API_BASE}/jobs/{job_id}",
headers={"Authorization": f"Bearer {API_TOKEN}"}
)
job = response.json()
status = job["status"]
print(f"Status: {status}")
if status == "completed":
style_id = job["result"]["style_id"]
print(f"Training complete! Style ID: {style_id}")
break
elif status in ["failed", "cancelled"]:
print(f"Training {status}")
break
time.sleep(30)
训练任务会经历以下状态:
- queued - 在队列中等待
- processing - 正在训练
- completed - 训练成功完成
- failed - 训练遇到错误
- cancelled - 任务被手动取消
使用你训练好的风格
训练完成后,通过 styles 参数将你的风格应用于图像生成:
应用与 API 之间的风格所有权API 和 Krea 网页应用在你的工作区中作为不同的用户身份运行。风格对创建者而言是私有的,因此:
- 在应用中训练的风格 通过 API 无法访问,除非共享
- 通过 API 训练的风格 在应用中无法访问,除非共享
要将风格共享给你的工作区(双向都可以):curl -X POST https://api.krea.ai/styles/YOUR_STYLE_ID/share/workspace \
-H "Authorization: Bearer YOUR_API_TOKEN"
import requests
import time
import os
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.krea.ai"
API_TOKEN = os.getenv("API_TOKEN")
STYLE_ID = "w29t6pvy0"
response = requests.post(
f"{API_BASE}/generate/image/krea/krea-2/medium",
headers={
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
},
json={
"prompt": "An abstract, colorful, surreal composition of symmetry and balance. Swirling colors, imagery of trees and coalescing patterns converge. The lantern of light and death. It is as if the world was at once dark, and yet again lit.",
"aspect_ratio": "1:1",
"resolution": "1K",
"styles": [
{
"id": STYLE_ID,
"strength": 0.95
}
]
}
)
job = response.json()
job_id = job["job_id"]
print(f"Generation started! Job ID: {job_id}")
# Poll for completion
while True:
check = requests.get(
f"{API_BASE}/jobs/{job_id}",
headers={"Authorization": f"Bearer {API_TOKEN}"}
)
status_data = check.json()
if status_data["status"] == "completed":
image_url = status_data["result"]["urls"][0]
print(f"Image ready: {image_url}")
break
elif status_data["status"] == "failed":
print("Generation failed")
break
time.sleep(2)
风格强度
strength 参数(0.0-1.0)控制你的风格被应用的强度:
| 强度 | 效果 |
|---|
| 0.5-0.7 | 微妙的影响,保留提示词灵活性 |
| 0.8-0.9 | 强烈的风格应用,推荐起点 |
| 0.95-1.0 | 最大程度贴合风格,可能降低提示词响应能力 |
从 0.8 强度开始,然后根据结果调整。较低的值提供更多创作自由;较高的值则强制更严格的风格贴合。
组合多种风格
通过将多种风格添加到 styles 数组来应用多种风格:
"styles": [
{"id": "style-id-1", "strength": 0.6},
{"id": "style-id-2", "strength": 0.4}
]
最佳实践
- 尽可能使用足够多的高质量图像以获得最佳结果
- 确保所有训练图像的风格保持一致
- 主题保持多样性但风格保持一致
- 避免水印、文字覆盖或伪影
- 使用至少 1024x1024 分辨率的图像
- 使用
type 字段以默认参数开始
- 对于风格:500-1000 步通常足够
- 较低的学习率(0.0001-0.0003)可防止过拟合
- 如果风格不够强,则增加步数
- 如果输出过于僵硬,则减少步数
- 如果你打算组合多种风格,使用相同的触发词
- 当你使用某个风格时,触发词会自动注入到提示词中
- 避免常见词语,它们会出现在常规提示词里
- 多词触发词使用下划线:
my_custom_style