# 개요

Transformers는 모델의 속도, 비용 효율성, 접근성을 높이기 위해 다양한 추론 최적화 기법을 제공합니다. 옵션에는 메모리 트래픽을 줄이는 대안적 어텐션 메커니즘, 실행 속도를 높이는 코드 컴파일, 처리량을 개선하는 최적화 커널 등이 있습니다. 이러한 기법을 조합하여 최대 성능을 달성할 수 있습니다.

디바이스 설정 및 하드웨어별 구성에 대해서는 [Hardware](./hardware) 가이드를 참고하세요. 아래 최적화를 적용하기 전에 해당 하드웨어에서 지원되는 기법을 확인하세요.

> [!NOTE]
> 메모리와 속도는 밀접하게 관련되어 있지만 동일하지는 않습니다. 메모리 사용량을 줄이면 데이터를 이동해야 할 양이 감소하므로 모델이 "더 빨라집니다". 순수한 속도 최적화는 항상 메모리를 줄이지는 않으며, 오히려 사용량이 증가할 수도 있습니다. 사용 사례와 하드웨어에 따라 적절한 최적화 방법을 선택하세요.

아래 표를 참고하여 최적화 기법을 선택하세요.

| 기법 | 속도 | 메모리 |
|---|:---:|:---:|
| [컴파일](#compilation) | ✅ | |
| [Attention 백엔드](#attention-backends) | ✅ | ✅ |
| [커널](#kernels) | ✅ | ✅ |
| [양자화](#quantization) | ✅ | ✅ |
| [캐싱](#caching) | ✅ | ✅ |
| [병렬성](#parallelism) | ✅ | |
| [연속 배치 처리](#continuous-batching) | ✅ | |

이 가이드는 Transformers 최적화에 대한 빠른 시작을 안내합니다.

## 컴파일

[torch.compile](./perf_torch_compile)는 Python 오버헤드를 줄이고, 연산을 융합하며, 사용자의 shape과 하드웨어에 맞게 튜닝된 커널을 생성합니다. 첫 번째 실행은 워밍업 역할을 하고, 이후 실행은 더 빠른 컴파일된 경로를 사용합니다.

`torch.compile`이 자동으로 트리거되도록 [generate()](/docs/transformers/main/ko/main_classes/text_generation#transformers.GenerationMixin.generate)에 [고정 크기 캐시](./kv_cache#fixed-size-cache)를 전달합니다.

```py
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", dtype=torch.float16, device_map="auto")
input = tokenizer("The French Bread Law states", return_tensors="pt").to(model.device)

output = model.generate(**input, do_sample=False, max_new_tokens=20, cache_implementation="static")
tokenizer.batch_decode(output, skip_special_tokens=True)[0]
```

> [!WARNING]
> 모든 단계마다 모델이 다시 컴파일되는 것을 방지하려면 [generate()](/docs/transformers/main/ko/main_classes/text_generation#transformers.GenerationMixin.generate) 외부에서 `torch.compile(model)`을 호출하지 마세요.

## Attention 백엔드

대안 [attention backends](./attention_interface)는 메모리 트래픽을 줄입니다. 예를 들어, FlashAttention은 attention 계산을 타일링하여 큰 중간 텐서를 피함으로써 메모리 사용량을 줄입니다.

`attn_implementation`을 [from_pretrained()](/docs/transformers/main/ko/main_classes/model#transformers.PreTrainedModel.from_pretrained)에서 설정하여 최적화된 attention 백엔드를 로드합니다.

```py
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", attn_implementation="flash_attention_2")
```

## 커널

Kernels은 연산을 융합하여 처리량을 높이고 메모리 사용량을 줄입니다. [Kernels](https://huggingface.co/docs/kernels/en/index) 라이브러리는 [Hub](https://huggingface.co/kernels-community)에서 최적화된 컴퓨트 커널을 유연하고 버전 안전성을 보장하는 방식으로 로드합니다.

…

```py
import torch
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)
```

## 양자화

[Quantization](./quantization/overview)은 모든 파라미터의 크기를 줄여 메모리 사용량을 낮추고, 더 많은 연산을 수행할 수 있어 속도를 높입니다.

`quantization_config` 인수에 양자화 설정을 전달합니다. [from_pretrained()](/docs/transformers/main/ko/main_classes/model#transformers.PreTrainedModel.from_pretrained)에서 각 양자화 백엔드는 서로 다른 인수를 가진 고유한 설정을 사용합니다. 아래 예제는 [bitsandbytes](./quantization/bitsandbytes) 백엔드를 사용하여 모델을 4-bit로 양자화하고 계산 dtype을 설정합니다.

```py
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)

model = AutoModelForCausalLM.from_pretrained(
    "allenai/Olmo-3-7B-Think", quantization_config=bnb_config
)
```

## 캐싱

[Caching](./kv_cache)은 모든 토큰마다 키와 값을 다시 계산하는 대신 과거의 키와 값을 재사용하여 생성 속도를 높입니다. 과거 키와 값을 저장하는 데 드는 메모리 비용을 상쇄하고 줄이기 위해, Transformers는 캐시를 CPU로 오프로딩하는 기능을 지원합니다. GPU에는 현재 레이어만 유지됩니다.

[generate()](/docs/transformers/main/ko/main_classes/text_generation#transformers.GenerationMixin.generate)에서 `cache_implementation` 인수를 사용하여 캐시 전략을 설정합니다.

```py
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)
inputs = tokenizer("The Le Décret Pain states that a baguette must,", return_tensors="pt")
outputs = model.generate(**inputs, do_sample=False, max_new_tokens=50, cache_implementation="offloaded")
```

## 병렬성

[Parallelism](./perf_infer_gpu_multi)은 모델을 여러 디바이스에 분산하여, 단일 디바이스에 맞지 않는 큰 모델도 빠르게 실행할 수 있게 합니다. 이 방식은 샤딩 오버헤드와 결과를 동기화하기 위한 통신으로 인해 더 많은 메모리를 사용합니다.

[Tensor parallelism](./perf_infer_gpu_multi)은 모델 레이어를 여러 디바이스에 분할합니다. `DistributedConfig(tp_size=N)`로 디바이스 수를 설정하고 [from_pretrained()](/docs/transformers/main/ko/main_classes/model#transformers.PreTrainedModel.from_pretrained)에 전달하여 활성화합니다.

```py
from transformers import AutoModelForCausalLM, DistributedConfig

distributed_config = DistributedConfig(tp_size=4)
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Meta-Llama-3-8B-Instruct",
    distributed_config=distributed_config,
)
print(model._tp_plan)
```

## 연속 배치

[Continuous batching](./continuous_batching)는 동적 스케줄링과 chunked prefill을 통해 GPU를 지속적으로 활용하여 처리량을 극대화합니다. [Serving](./serve-cli/serving) 애플리케이션은 이를 사용하여 여러 수신 요청을 동시에 처리합니다.

[generate_batch()](/docs/transformers/main/ko/main_classes/text_generation#transformers.ContinuousMixin.generate_batch)를 사용하여 연속 배치 처리를 활성화합니다.

```py
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import ContinuousBatchingConfig, GenerationConfig

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen3-0.6B",
    attn_implementation="sdpa",
    device_map="auto",
    torch_dtype=torch.bfloat16,
)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")

prompts = [
    "The Le Décret Pain states that a baguette must",
    "Explain gravity in one sentence.",
    "Name the capital of France.",
]
inputs = [tokenizer.encode(p) for p in prompts]

generation_config = GenerationConfig(
    max_new_tokens=32,
    eos_token_id=tokenizer.eos_token_id,
    pad_token_id=tokenizer.pad_token_id,
    do_sample=False,
)
continuous_batching_config = ContinuousBatchingConfig(max_batch_tokens=512)

outputs = model.generate_batch(
    inputs=inputs,
    generation_config=generation_config,
    continuous_batching_config=continuous_batching_config,
)

for request_id, output in outputs.items():
    text = tokenizer.decode(output.generated_tokens, skip_special_tokens=True)
    print(f"[{request_id}] {text}")
```

