Transformers documentation
개요
개요
Transformers는 모델의 속도, 비용 효율성, 접근성을 높이기 위해 다양한 추론 최적화 기법을 제공합니다. 옵션에는 메모리 트래픽을 줄이는 대안적 어텐션 메커니즘, 실행 속도를 높이는 코드 컴파일, 처리량을 개선하는 최적화 커널 등이 있습니다. 이러한 기법을 조합하여 최대 성능을 달성할 수 있습니다.
디바이스 설정 및 하드웨어별 구성에 대해서는 Hardware 가이드를 참고하세요. 아래 최적화를 적용하기 전에 해당 하드웨어에서 지원되는 기법을 확인하세요.
사용자의 Transformers 추론 워크로드에 적합한 최적화 방법을 선택하도록 돕습니다. 먼저 모델 로딩, 긴 입력 처리, 긴 시퀀스 생성, 동시 요청 처리 중 어떤 단계에서 메모리 또는 속도가 문제가 되는지 파악합니다. 아래에 해당하는 가이드를 사용하고, 변경 사항을 권장하기 전에 사용자의 모델 및 하드웨어에 대한 지원 여부를 확인합니다.
- 모델 및 리비전, 라이브러리 버전, GPU 및 사용 가능한 VRAM, CPU RAM, 입력 길이, 생성 제한, 배치 크기, 동시 요청 수를 확인하세요. 누락된 세부 사항이 추천 사항에 영향을 줄 수 있는 경우 후속 질문을 하고, 가정을 명시하세요.
- 문제가 발생하는 지점을 기준으로 조사할 대상을 선택하세요. 로드 시 메모리는 모델 가중치 및 로드 설정을, 생성 시퀀스가 증가함에 따라 발생하는 KV 캐시는, 긴 입력에 대한 어텐션 할당은, 동시 요청에 대한 요청별 상태 및 스케줄링을 각각 확인하세요. 가중치 양자화와 KV 캐시 양자화는 별개의 설정으로 취급하세요.
- 한 번에 하나의 변경 사항만 권장합니다. 모델과 하드웨어의 호환성을 확인한 후, 동일한 대표 워크로드에서 피크 GPU 메모리, 지연 시간 또는 처리량, 출력 품질을 측정하세요. 입력 길이, 생성 길이 또는 동시성 감소는 워크로드 트레이드오프로 설명하세요.
- 제안된 구성, 이를 뒷받침하는 문서, 예상되는 트레이드오프, 미해결된 호환성 문제, 그리고 검증 절차를 보고하십시오. 측정값과 추정값을 구분하십시오. 워크로드를 실행할 수 없는 경우, 적합성과 성능이 검증되지 않았다고 명시하십시오.
메모리와 속도는 밀접하게 관련되어 있지만 동일한 개념은 아닙니다. 메모리 사용량을 줄이면 모델이 “빠르게” 동작합니다. 이는 이동해야 할 데이터가 줄어들기 때문입니다. 순수한 속도 최적화는 항상 메모리를 줄이지 않으며, 오히려 사용량이 증가할 수도 있습니다. 사용 사례와 하드웨어에 따라 적절한 최적화 방법을 선택하세요.
아래 표를 참고하여 최적화 기법을 선택하세요.
| 기법 | 속도 | 메모리 |
|---|---|---|
| 컴파일 | ✅ | |
| Attention 백엔드 | ✅ | ✅ |
| 커널 | ✅ | ✅ |
| 양자화 | ✅ | ✅ |
| 캐싱 | ✅ | ✅ |
| 병렬성 | ✅ | |
| 연속 배치 처리 | ✅ |
이 가이드는 Transformers 최적화에 대한 빠른 시작을 안내합니다.
컴파일
torch.compile는 Python 오버헤드를 줄이고, 연산을 융합하며, 사용자의 shape과 하드웨어에 맞게 튜닝된 커널을 생성합니다. 첫 번째 실행은 워밍업 역할을 하고, 이후 실행은 더 빠른 컴파일된 경로를 사용합니다.
torch.compile이 자동으로 트리거되도록 generate()에 고정 크기 캐시를 전달합니다.
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]모든 단계마다 모델이 다시 컴파일되는 것을 방지하려면 generate() 외부에서
torch.compile(model)을 호출하지 마세요.
Attention 백엔드
대안 attention backends는 메모리 트래픽을 줄입니다. 예를 들어, FlashAttention은 attention 계산을 타일링하여 큰 중간 텐서를 피함으로써 메모리 사용량을 줄입니다.
attn_implementation을 from_pretrained()에서 설정하여 최적화된 attention 백엔드를 로드합니다.
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", attn_implementation="flash_attention_2")커널
Kernels은 연산을 융합하여 처리량을 높이고 메모리 사용량을 줄입니다. Kernels 라이브러리는 Hub에서 최적화된 컴퓨트 커널을 유연하고 버전 안전성을 보장하는 방식으로 로드합니다.
…
import torch
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)양자화
Quantization은 모든 파라미터의 크기를 줄여 메모리 사용량을 낮추고, 더 많은 연산을 수행할 수 있어 속도를 높입니다.
quantization_config 인수에 양자화 설정을 전달합니다. from_pretrained()에서 각 양자화 백엔드는 서로 다른 인수를 가진 고유한 설정을 사용합니다. 아래 예제는 bitsandbytes 백엔드를 사용하여 모델을 4-bit로 양자화하고 계산 dtype을 설정합니다.
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은 모든 토큰마다 재계산하는 대신 과거의 key와 value를 재사용하여 생성 속도를 높입니다. 과거 key와 value를 저장하는 데 드는 메모리 비용을 상쇄하고 줄이기 위해, Transformers는 캐시를 CPU로 오프로딩하는 기능을 지원합니다. GPU에는 현재 레이어만 유지됩니다.
generate()에서 cache_implementation 인수를 사용하여 캐시 전략을 설정합니다.
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은 모델을 여러 디바이스에 분산하여, 단일 디바이스에 맞지 않는 큰 모델도 빠르게 실행할 수 있게 합니다. 이 방식은 샤딩 오버헤드와 결과를 동기화하기 위한 통신으로 인해 더 많은 메모리를 사용합니다.
Tensor parallelism은 모델 레이어를 여러 디바이스에 분할합니다. DistributedConfig(tp_size=N)로 디바이스 수를 설정하고 from_pretrained()에 전달하여 활성화합니다.
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는 동적 스케줄링과 chunked prefill을 통해 GPU를 지속적으로 활용하여 처리량을 극대화합니다. Serving 애플리케이션은 이를 사용하여 여러 수신 요청을 동시에 처리합니다.
generate_batch()를 사용하여 연속 배치 처리를 활성화합니다.
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}")