> ## Documentation Index
> Fetch the complete documentation index at: https://www.krea.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Train a Custom Style

> 자신만의 데이터셋으로 커스텀 이미지 스타일을 학습하고, 큐레이션, 태깅, 반복 개선의 모범 사례를 참고해 일관된 결과물을 생성하세요.

export const HeroHeader = ({image, video, title, description}) => {
  return <div className="relative aspect-[2/1] h-[30vh] w-full rounded-lg overflow-hidden mb-8">
      {}
      {video && <video autoPlay muted loop playsInline className="absolute top-0 left-0 w-full h-full object-cover hidden md:block m-0" style={{
    zIndex: 1,
    objectPosition: "20% 20%"
  }}>
          <source src={video} type="video/webm" />
        </video>}

      {}
      <img src={image} alt="" className={`absolute top-0 left-0 m-0 w-full h-full object-cover ${video ? "md:hidden" : "block"}`} style={{
    zIndex: 1,
    objectPosition: "20% 20%"
  }} />

      {}
      <div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/30 to-black/10 flex flex-col justify-end p-8 dark:hidden" style={{
    zIndex: 2
  }}>
        <h1 className="text-4xl font-bold text-white m-0 drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]">
          {title}
        </h1>
        <p className="text-lg text-white/95 mt-2 drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]">
          {description}
        </p>
      </div>

      {}
      <div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20 hidden dark:flex flex-col justify-end p-8" style={{
    zIndex: 2
  }}>
        <h1 className="text-4xl font-bold text-white m-0 drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]">
          {title}
        </h1>
        <p className="text-lg text-white/95 mt-2 drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]">
          {description}
        </p>
      </div>
    </div>;
};

<HeroHeader image="https://s.krea.ai/docs-lora.webp" title="Train a Custom Style (LoRA)" description="자신의 이미지를 사용해 커스텀 스타일을 학습시켜 일관된 비주얼 미감의 AI 아트를 생성하세요." />

## 개요

LoRA(Low-Rank Adaptation)는 소량의 예시 이미지로 AI 모델에게 새로운 비주얼 스타일을 가르치는 파인튜닝 기법입니다. 기존 모델에 새로운 "스타일 가중치"를 주입하는 방식으로 동작해 학습이 빠르고 효율적입니다.

이 가이드는 전체 워크플로우를 안내합니다:

<Steps>
  <Step title="학습 이미지 준비" icon="images">
    원하는 스타일을 대표하는 고품질 이미지를 선별해 업로드합니다
  </Step>

  <Step title="학습 작업 제출" icon="play">
    이미지 URL과 구성 정보를 담아 `/styles/train`에 POST 요청을 보냅니다
  </Step>

  <Step title="진행 상황 모니터링" icon="clock">
    반환된 `job_id`를 사용해 학습 작업 상태를 추적합니다
  </Step>

  <Step title="학습한 스타일로 생성" icon="sparkles">
    학습된 스타일을 이미지 생성에 적용합니다
  </Step>
</Steps>

***

## 학습 이미지 준비

### 데이터셋 큐레이션

학습 이미지의 품질은 결과에 직접적인 영향을 줍니다. 학습 유형에 따라 요구 사항이 다릅니다:

| 유형            | 활용 사례           | 팁                   |
| ------------- | --------------- | ------------------- |
| **Style**     | 예술적 스타일, 비주얼 미감 | 다양한 주제에서 일관된 스타일 유지 |
| **Character** | 개인 유사도, 일관된 캐릭터 | 다양한 포즈, 표정, 조명      |
| **Object**    | 특정 사물, 제품       | 여러 각도, 일관된 사물       |

### 이미지는 몇 장이 필요할까요?

품질이 수량보다 훨씬 중요합니다. 훌륭한 이미지 소수가 평범한 이미지 다수보다 좋은 결과를 냅니다.

| 데이터셋 크기     | 가이드                             |
| ----------- | ------------------------------- |
| **5장**      | 최소한의 시작. 단순하고 일관된 스타일에 적합할 수 있음 |
| **10\~30장** | 권장. 품질과 커버리지의 균형이 가장 좋음         |
| **50장 이상**  | 스타일 변화가 크지 않다면 효용이 급감           |

<Warning>
  **품질 > 수량**

  품질이 높은 15장이 낮은 품질의 50장보다 나은 결과를 냅니다. 다음을 우선하세요:

  * 고해상도 (최소 1024x1024)
  * 모든 이미지에서 일관된 스타일
  * 워터마크, 텍스트 오버레이, 압축 아티팩트 없음
  * 스타일 일관성을 유지하면서 주제는 다양하게
</Warning>

<Info>
  **예시 데이터셋**

  * **캐릭터 학습**: 다양한 포즈, 표정, 조명 환경에서의 특정 인물 사진. 이미지에 다른 인물을 포함하지 마세요.
  * **스타일 학습**: 일관된 스타일의 아트워크 컬렉션. 예를 들어, [The Metropolitan Museum of Art Ukiyo-E Dataset](https://www.kaggle.com/datasets/kengoichiki/the-metropolitan-museum-of-art-ukiyoe-dataset)은 예술 스타일 학습에 이상적인 일본 우키요에 판화를 제공합니다.
</Info>

### 이미지 업로드

학습 전에 이미지를 업로드해 호스팅 URL을 확보하세요. `/assets` 엔드포인트를 사용합니다:

<CodeGroup>
  ```python Python theme={null}
  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")
  ```

  ```bash cURL theme={null}
  # Upload a single image
  curl -X POST https://api.krea.ai/assets \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -F "file=@/path/to/image.jpg" \
    -F "description=Training image"

  # Response: {"id": "...", "image_url": "https://..."}
  ```
</CodeGroup>

<Tip>
  반환된 `image_url` 값을 저장해 두세요 — 학습 엔드포인트에 전달해야 합니다.
</Tip>

***

## 스타일 학습하기

### 기본 학습 예제

이미지 URL을 제출해 학습을 시작하세요:

<CodeGroup>
  ```python Python theme={null}
  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']}")
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.krea.ai/styles/train \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Ukiyo-E Style",
      "urls": [
        "https://krea.ai/assets/img1.jpg",
        "https://krea.ai/assets/img2.jpg",
        "https://krea.ai/assets/img3.jpg"
      ],
      "model": "flux_dev",
      "type": "Style",
      "max_train_steps": 500
    }'
  ```
</CodeGroup>

### 학습 유형

`type` 파라미터는 사용 사례에 맞게 최적화된 지능형 기본값을 설정합니다:

| 유형          | 적합한 용도          |
| ----------- | --------------- |
| `Style`     | 예술적 스타일, 비주얼 미감 |
| `Character` | 개인 유사도, 일관된 캐릭터 |
| `Object`    | 특정 사물, 제품       |
| `Default`   | 일반적인 학습         |

### 파라미터

#### 필수 파라미터

<ParamField path="name" type="string" required>
  커스텀 스타일을 설명하는 이름입니다.

  **예시:** `"Ukiyo-E Style"`, `"Product Photos"`
</ParamField>

<ParamField path="urls" type="array" required>
  학습에 사용할 이미지 URL 배열입니다. 더 나은 결과를 위해 이미지를 여러 장 포함하세요.
</ParamField>

#### 선택 파라미터

<ParamField path="model" type="string" default="flux_dev">
  학습 베이스 모델:

  **이미지 모델:**

  * `flux_dev` - 고품질, 다재다능
  * `flux_schnell` - BFL의 실시간 모델
  * `qwen` - Alibaba의 모델
  * `z-image` - Alibaba의 효율적인 이미지 모델
  * `wan22` - 이미지 생성 전용

  **영상 모델:**

  * `wan` - Alibaba의 영상 모델
</ParamField>

<ParamField path="type" type="string" default="Default">
  학습 카테고리: `Style`, `Object`, `Character`, 또는 `Default`
</ParamField>

<ParamField path="trigger_word" type="string">
  프롬프트에서 이 스타일을 활성화하는 커스텀 단어입니다. 지정하지 않으면 스타일 이름을 사용합니다.

  <Tip>일반 프롬프트에 잘 나타나지 않는 고유한 트리거 단어를 선택하세요. 여러 단어일 경우 언더스코어를 사용하세요: `ukiyo_style`</Tip>
</ParamField>

<Accordion title="고급 파라미터" icon="sliders">
  <ParamField path="learning_rate" type="number">
    학습 강도를 제어합니다. 값이 높을수록 학습은 빠르지만 과적합할 수 있습니다.

    **권장 범위:** 0.0001 - 0.001
  </ParamField>

  <ParamField path="max_train_steps" type="integer">
    최대 학습 반복 수. 범위: 1-2000
  </ParamField>

  <ParamField path="batch_size" type="integer">
    동시에 처리되는 이미지 수. 배치가 클수록 학습이 빠르지만 메모리를 더 사용합니다.
  </ParamField>
</Accordion>

### 고급 파라미터 튜닝

`type` 필드가 설정하는 기본값으로 시작하세요 — 대부분의 경우 잘 작동합니다. 특정 문제가 나타날 때만 조정하세요:

<AccordionGroup>
  <Accordion title="Learning Rate" icon="gauge">
    모델이 학습 이미지에 얼마나 적극적으로 적응할지를 제어합니다.

    | 값                     | 언제 사용할까                   |
    | --------------------- | ------------------------- |
    | **0.0001** (낮음)       | 과적합 문제, 복잡한 스타일, 소규모 데이터셋 |
    | **0.0003** (기본값)      | 대부분의 경우                   |
    | **0.0005-0.001** (높음) | 빠른 학습이 필요할 때              |

    **조정이 필요한 신호:**

    * 결과가 학습 이미지와 동일해 보임 → 값을 낮추세요
    * 학습 후에도 스타일 반영이 약함 → 값을 조금 올리세요
  </Accordion>

  <Accordion title="Training Steps" icon="shoe-prints">
    모델이 이미지를 얼마나 오래 학습할지 결정합니다.

    | 데이터셋 크기 | 권장 스텝 수     |
    | ------- | ----------- |
    | 5-10장   | 300-500 스텝  |
    | 15-30장  | 500-800 스텝  |
    | 50장 이상  | 800-1500 스텝 |

    **조정이 필요한 신호:**

    * 결과가 너무 경직되어 프롬프트를 무시함 → 스텝 수를 줄이세요
    * 스타일 반영이 약함 → 스텝 수를 늘리세요
    * 생성 이미지가 학습 데이터와 완전히 똑같음 → 스텝 수를 줄이세요 (과적합)
  </Accordion>
</AccordionGroup>

<Tip>
  **반복적 튜닝**

  첫 학습 시도가 원하는 결과를 내지 못하면:

  1. 먼저 `max_train_steps`를 조정하세요 (가장 흔한 해결 방법)
  2. 스텝만으로 해결되지 않으면 `learning_rate`를 시도하세요
</Tip>

### 응답 형식

```json theme={null}
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "queued",
  "created_at": "2024-01-15T10:30:00Z"
}
```

***

## 학습 진행 상황 모니터링

학습에는 보통 5-15분이 소요됩니다. Jobs API를 폴링해 상태를 확인하세요:

<CodeGroup>
  ```python Python theme={null}
  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)
  ```

  ```bash cURL theme={null}
  # Check job status (repeat until completed)
  curl -X GET https://api.krea.ai/jobs/YOUR_JOB_ID \
    -H "Authorization: Bearer YOUR_API_TOKEN"
  ```
</CodeGroup>

<Accordion title="작업 상태 값" icon="diagram-project">
  학습 작업은 다음 상태를 거칩니다:

  1. **queued** - 큐에서 대기 중
  2. **processing** - 학습 진행 중
  3. **completed** - 학습이 성공적으로 완료됨
  4. **failed** - 학습 중 오류 발생
  5. **cancelled** - 작업이 수동으로 취소됨
</Accordion>

***

## 학습한 스타일 사용하기

학습이 완료되면 `styles` 파라미터를 사용해 이미지 생성에 스타일을 적용하세요:

<Warning>
  **앱과 API 사이의 스타일 소유권**

  API와 Krea 웹앱은 워크스페이스 안에서 별도의 사용자 정체성으로 동작합니다. 스타일은 이를 만든 사용자에게 비공개이므로 다음과 같습니다:

  * **앱에서 학습한 스타일**은 공유되지 않는 한 API로 접근할 수 없습니다
  * **API에서 학습한 스타일**은 공유되지 않는 한 앱에서 접근할 수 없습니다

  워크스페이스에 스타일을 공유하려면(양방향 모두 가능):

  ```bash theme={null}
  curl -X POST https://api.krea.ai/styles/YOUR_STYLE_ID/share/workspace \
    -H "Authorization: Bearer YOUR_API_TOKEN"
  ```
</Warning>

<CodeGroup>
  ```python Python theme={null}
  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)
  ```

  ```bash cURL theme={null}
  # Generate with style
  curl -X POST https://api.krea.ai/generate/image/krea/krea-2/medium \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "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": "w29t6pvy0",
          "strength": 0.95
        }
      ]
    }'

  # Then poll /jobs/{job_id} for the result
  ```
</CodeGroup>

### 스타일 강도

`strength` 파라미터(0.0-1.0)는 스타일이 얼마나 강하게 적용될지를 제어합니다:

| 강도       | 효과                            |
| -------- | ----------------------------- |
| 0.5-0.7  | 은은한 영향, 프롬프트 유연성 유지           |
| 0.8-0.9  | 강한 스타일 적용, 권장 시작점             |
| 0.95-1.0 | 최대 스타일 준수, 프롬프트 반응성이 저하될 수 있음 |

<Tip>
  `0.8` 강도로 시작한 뒤 결과에 따라 조정하세요. 값이 낮을수록 더 큰 창의적 자유를 얻고, 값이 높을수록 스타일을 더 엄격히 강제합니다.
</Tip>

### 여러 스타일 결합하기

`styles` 배열에 여러 스타일을 추가해 함께 적용할 수 있습니다:

```python theme={null}
"styles": [
    {"id": "style-id-1", "strength": 0.6},
    {"id": "style-id-2", "strength": 0.4}
]
```

***

## 모범 사례

<AccordionGroup>
  <Accordion title="이미지 선정" icon="images">
    * 최적의 결과를 위해 보유한 고품질 이미지를 가능한 한 많이 사용하세요
    * 모든 학습 이미지에서 일관된 스타일을 유지하세요
    * 스타일 일관성을 유지하면서 주제는 다양하게 포함하세요
    * 워터마크, 텍스트 오버레이, 아티팩트는 피하세요
    * 최소 1024x1024 해상도의 이미지를 사용하세요
  </Accordion>

  <Accordion title="학습 구성" icon="sliders">
    * `type` 필드로 설정되는 기본 파라미터부터 시작하세요
    * 스타일 학습: 500-1000 스텝이 대부분 충분합니다
    * 낮은 러닝레이트(0.0001-0.0003)는 과적합을 방지합니다
    * 스타일이 약하면 스텝을 늘리세요
    * 출력이 너무 경직되면 스텝을 줄이세요
  </Accordion>

  <Accordion title="트리거 단어" icon="wand-magic-sparkles">
    * 여러 스타일을 결합할 계획이라면 동일한 트리거 단어를 사용하세요
    * 스타일을 포함하면 트리거 단어가 프롬프트에 자동으로 삽입됩니다
    * 일반 프롬프트에 자주 등장하는 흔한 단어는 피하세요
    * 여러 단어인 경우 언더스코어를 사용하세요: `my_custom_style`
  </Accordion>
</AccordionGroup>
