Transformers documentation

Dışa Aktarıcılar

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Dışa Aktarıcılar

Hedef çalışma zamanından bağımsız olarak herhangi bir PreTrainedModel nesnesini ONNX, ExecuTorch veya bağımsız bir PyTorch programına dışa aktarın.

exporter = DynamoExporter()  # or OnnxExporter, ExecutorchExporter
config = DynamoConfig(dynamic=True)
exported = exporter.export(model, inputs, config=config)

Dışa aktarıcılar, bir aşağı akış kütüphanesi yerine Transformers içinde yer aldığı için mimari değişiklikler, yeni dikkat kalıpları ve özel önbellek türleri, modelleme koduna eklendikleri anda dışa aktarma sırasında desteklenir.

Dışa aktarıcılar deneyseldir. Bu modüldeki yamaların çoğu, belirli üst akış hatalarının (Torch, ONNX Script, ONNX Runtime, ExecuTorch) etrafından dolaşmak için çalışır ve düzeltme üst akışa eklendiği anda kaldırılacaktır. API kararlılaşana kadar, yamaları test paketinde kullanılan sürümlere bağlı olarak ele alın. Üretim araçlarında bu sürümleri sabitleyin ve üst akış değişiklikleri geldikçe yeni yamaların ortaya çıkmasını, eski yamaların ise kaybolmasını bekleyin.

Dışa AktarıcıÇıktıÇalışma zamanı
DynamoExporterExportedProgramHerhangi bir PyTorch çalışma zamanı, AOT derleme
OnnxExporterONNXProgramHerhangi bir ONNX çalışma zamanı (ORT, TensorRT, OpenVINO)
ExecutorchExporterExecutorchProgramManagerMobil ve kenar cihazları (ExecuTorch)
OpenVINOExporteropenvino.ModelOpenVINO çalışma zamanı (Intel CPU/GPU/NPU)

AutoHfExporter bir yapılandırmadan doğru dışa aktarıcıyı seçer ve AutoExportConfig bir sözlükten doğru yapılandırma sınıfını seçer. İkisi de Transformers'taki aynı otomatik-sınıf desenini izler; bu, arka uç çağrı noktasında sabit kodlanmak yerine çalışma zamanında seçildiğinde faydalıdır.

from transformers.exporters import AutoExportConfig, AutoHfExporter

export_config_dict = {"export_format": "onnx", "dynamic": True}
config = AutoExportConfig.from_dict(export_config_dict)
exporter = AutoHfExporter.from_config(config)

onnx_program = exporter.export(model, inputs, config=config)

Kurulum

Dışa aktarmayı planladığınız arka uç için bağımlılıkları yükleyin.

Aşağıdaki sürümler, dışa aktarıcı test takımının sabitlendiği sürümlerdir. Daha yeni veya eski sürümler genellikle çalışır, ancak dışa aktarıcı yamaları belirli bir API yüzeyine yönelik olduğundan, üretim araçları için bu sürümleri sabitleyin ve HfExporter'ın sapma algıladığında bir uyarı kaydettiğini bekleyin.

Dynamo
ONNX
ExecuTorch XNNPACK
ExecuTorch MLX
OpenVINO
pip install transformers "torch==2.12.0"

Bir model dışa aktarın

Tüm dışa aktarıcılar aynı arayüzü paylaşır. Bir yapılandırma ile dışa aktarıcı oluşturun ve export() çağrısını yapın.

Dışa aktarıcı sınıfını değiştirerek çalışma zamanları arasında geçiş yapın.

Dynamo
ONNX
ExecuTorch
OpenVINO
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.exporters import DynamoExporter, DynamoConfig

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
inputs = tokenizer("Hello, world!", return_tensors="pt")

exporter = DynamoExporter()
config = DynamoConfig(dynamic=True)
exported = exporter.export(model, inputs, config=config)

# run the exported graph directly
outputs = exported.module()(**inputs)

Dinamik şekiller

dynamic=True parametresinin geçirilmesi, dışa aktarılan grafiğin çalışma zamanında yeniden izleme yapmadan herhangi bir boyutta girdileri kabul etmesi için her tensör boyutunu dinamik olarak işaretler.

Hangi boyutların dinamik olacağına dair ince taneli kontrol için, bunun yerine doğrudan torch.export.export'a iletilen açık dynamic_shapes parametresini geçirin.

Dynamo
ONNX
ExecuTorch
OpenVINO
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.exporters import DynamoExporter, DynamoConfig

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
inputs = tokenizer(["Hello, world!", "Hi"], padding=True, return_tensors="pt")

batch = torch.export.Dim("batch", min=1, max=32)
seq = torch.export.Dim("seq", min=1, max=2048)

exporter = DynamoExporter()
config = DynamoConfig(
    dynamic_shapes={"input_ids": {0: batch, 1: seq}, "attention_mask": {0: batch, 1: seq}},
    # Emit data-dependent shape guards as runtime asserts instead of failing the export when a
    # guard wouldn't hold across the explicit symbolic range. Most LLMs need this under fine-grained
    # ``Dim(min=, max=)`` bounds. Not needed with ``dynamic=True`` / ``Dim.AUTO``, where torch.export
    # infers shape relations instead of verifying them against user-stated bounds.
    prefer_deferred_runtime_asserts_over_guards=True,
)
exported = exporter.export(model, inputs, config=config)

Üretken modeller

Otonom regresif üretimde, modelin forward fonksiyonu, prefill adımı (tam istem, KV önbelleği yok) ile decode adımı (tek token, dolu KV önbelleği) arasında farklı şekillere sahiptir. Dışa aktarıcılar, her iki aşamayı ayırıp her birini dışa aktaran ~HfExporter.export_for_generation yöntemini sunar.

Çok modlu üretken modellerde, prefill ayrıca bir görüntü veya ses kodlayıcıya, dil modeline ve lm_head bileşenine ayrılır. Kodlayıcı ve dil modelinin keşfi, get_encoder() (modality="image" veya "audio") ve get_decoder() erişimcilerini kullandığından, bu bileşenleri kullanan herhangi bir yeni mimari hazır olarak çalışır.

Bir projeksiyon bileşeni yalnızca model, bir öznitelik adı altında (multi_modal_projector, connector, embed_vision, embed_audio) bir projeksiyon açığa çıkardığında görünür. Aşağıdaki Qwen2-VL, projeksiyonunu görme kulesine (vision tower) dahil eder, bu nedenle bileşen sözlüğünde ayrı bir multi_modal_projector anahtarı yoktur. Yeni mimariler, listeyi büyütmek yerine projeksiyon özniteliklerini bu adlardan biriyle hizalamalıdır.

Dynamo
ONNX
ExecuTorch
OpenVINO
from transformers import AutoModelForImageTextToText, AutoProcessor
from transformers.exporters import DynamoExporter, DynamoConfig

model = AutoModelForImageTextToText.from_pretrained("Qwen/Qwen2-VL-2B-Instruct")
processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-2B-Instruct")
messages = [{"role": "user", "content": [{"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"}, {"type": "text", "text": "Describe this image."}]}]
text = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
inputs = processor(text=text, images=messages[0]["content"][0]["url"], return_tensors="pt").to(model.device)

exporter = DynamoExporter()
config = DynamoConfig(dynamic=True)
components = exporter.export_for_generation(model, inputs, config=config)
# components = {"image_encoder": ExportedProgram, "language_model": ExportedProgram, "lm_head": ExportedProgram, "decode": ExportedProgram}

Dışa aktarılan bileşenler bağımsız grafiklerdir, çalışmaya hazır bir çıkarım hattı değildir. Çağıran taraf, her kodlayıcıyı çalıştırmaktan, gömme projeksiyonlarını uygulamaktan ve üretim döngüsünü koordine etmekten sorumludur.

export_for_generation nasıl çalışır

decompose_for_generation() model.generate(**inputs, max_new_tokens=2) komutunu bir kez çalıştırır ve gerçek prefill ile decode kwargs'larını yakalamak için model.forward fonksiyonuna hook ekler (model çok modluysa, her encoder/projector/language model alt modülüne eklenen hook'lar aracılığıyla alt modül bazlı kwargs'ları da yakalar). Bu sayede, model bazlı yapıştırıcı kodlara (glue code) gerek kalmadan, yalnızca decoder'lı, SSM, encoder-decoder ve çok modlu modeller dahil olmak üzere herhangi bir mimari için çalışır. export_for_generation bunun üzerine kurulu tek satırlık bir işlemdir.

Capture, modeli inputs üzerinde aceleci (eager) olarak çalıştırır; bu nedenle kısa bir istem, tek bir küçük görsel veya birkaç ses çerçevesi gibi küçük ama temsilci değerler geçirin. Dışa aktarılan program bu boyutlara bağlı değildir (dinamik şekiller yine de akar), ancak daha küçük capture girdileri decompose_for_generation işlemini daha ucuz hale getirir ve sembolik şekil çıkarımını yönetilebilir tutar.

decompose_for_generation fonksiyonunu doğrudan çağırarak, ayrıştırma ve dışa aktarma işlemleri arasında müdahale edebilirsiniz; örneğin doğrulama için bir eager forward çalıştırabilir, bir alt modülün girdilerini değiştirebilir veya bir aşamayı atlayabilirsiniz.

from transformers.exporters.utils import decompose_for_generation

components = decompose_for_generation(model, inputs)
# {"image_encoder": (submodel, fwd_kwargs), "language_model": (...), ..., "decode": (...)}

exported = {}
for name, (submodel, subinputs) in components.items():
    eager_outputs = submodel(**subinputs)  # sanity-check the eager forward before exporting
    exported[name] = exporter.export(submodel, subinputs, config=config)

Çoklu jeton çözme

Varsayılan olarak decode bileşeni tek jeton adımdır — KV önbelleğine karşı bir sorgu jetonu — bu nedenle torch.export, sorgu dizisi eksenini 1'e özelleştirir. Bunun yerine decode bileşenini çoklu jeton olarak yakalamak için multi_token_decode=True parametresini iletin: decompose_for_generation() fonksiyonu, iki ardışık decode adımını (yakalama max_new_tokens=3 ile yapılır) tek bir ileri geçişte birleştirir, böylece bu eksen sembolik olarak kalır. Tek bir grafik, her sorgu uzunluğunu karşılar — tek jeton (sıradan çözümleme), birden fazla jetonun aynı anda işlenmesi (geçmişten devam, örneğin spekülatif jetonların bir bölümünün kabulü) ve önbellek boşken düz bir ön işleme (prefill).

Dynamo
ONNX
ExecuTorch
from transformers.exporters import DynamoExporter, DynamoConfig

exporter = DynamoExporter()
config = DynamoConfig(dynamic=True)
components = exporter.export_for_generation(model, inputs, config=config, multi_token_decode=True)
# components["decode"] now accepts a variable number of query tokens

Sorgu ekseni yalnızca dinamik şekilli bir dışa aktarmada (dynamic=True) sembolik kalır; statik bir dışa aktarma, bu ekseni yakalanan uzunlukta dondurarak sabit çoklu-jetonlu bir grafik oluşturur. Bu, aşağıdaki statik KV önbelleğiyle birleşir — birleştirilmiş çözümleme, her adımın jetonlarını sabit boyutlu önbelleğe yerinde yazar ve önbellek, jetonların nereye yerleştirileceğini içsel olarak yönetir.

Statik KV önbelleği

Bu bölümdeki ExecuTorch örnekleri, kopyasız güncellemeler ve çözümleme döngüsü dahil olmak üzere, yalnızca XNNPACK içindir. MLX dışa aktarıcısı StaticCache öğesini reddeder; MLX ile DynamicCache kullanın.

generate() varsayılan olarak bir DynamicCache büyütür ve dizi uzadıkça yeniden tahsis eder — bu, dışa aktarılmış bir grafik için hareketli bir hedeftir. statik bir önbellek, bir kez tahsis edilen ve her adımda geçerli konuma yerinde yazılan sabit boyutlu bir tampondur. çoklu jeton çözme ile birleştirildiğinde, üretimi tek bir dışa aktarılmış grafiğe indirger: decode grafiği, sabit boyutlu bir önbellek ve değişken sayıda sorgu jetonu alır, böylece tek bir grafik hem istemi (boş önbellek → prefill) hem de üretilen her jetonu (dolu önbellek → decode) karşılar. GenerationConfig içinde cache_implementation="static" (ve bir max_cache_len) ile multi_token_decode=True parametresini ileterek dışa aktarın:

Dynamo
ONNX
ExecuTorch XNNPACK
from transformers import GenerationConfig
from transformers.exporters import DynamoExporter, DynamoConfig

exporter = DynamoExporter()
gen_config = GenerationConfig(cache_implementation="static", max_cache_len=2048)
components = exporter.export_for_generation(
    model, inputs, config=DynamoConfig(dynamic=True), generation_config=gen_config, multi_token_decode=True
)

decode grafiği artık iki sembolik eksene sahip — sorgu uzunluğu (kaç token beslediğiniz) ve önbellek uzunluğu (max_cache_len, yükleme sırasında yeniden boyutlandırılabilir). dynamic=True bu eksenleri (ve diğer tüm eksenleri) Dim.AUTO olarak işaretler, böylece dışa aktarılan grafik, yükleme sırasında herhangi bir istem uzunluğunu ve önbellek boyutunu kabul eder.

Sıfır kopyalı yerinde güncellemeler

Statik önbellek dışarıdan geçirilir ve yerinde değiştirilir, böylece bir tampon, host kopyaları olmadan decode adımları arasında durumu taşır — koşullu çalışma zamanı, kendi arena’sı üzerinden kopyalama yapmak yerine çağıranın tamponlarını bağladığı sürece. Bunun gerektirdiği, geriye kalan tek backend’ye özgü kısımdır:

  • Dynamo — dışa aktarılan program, önbellek yazımını USER_INPUT_MUTATION olarak modellediğinden, components["decode"].module()(...) çağrısı, doğrudan ilettiğiniz önbellek tensörlerini günceller. Her adımda aynı tensörleri yeniden kullanın; yapılandırılacak bir şey yoktur.

  • ONNX Runtime — decode grafiği, önbelleği eşleşen input.<name> / output.<name> çiftleri olarak açığa çıkar. ORT’nin CudaSession.set_buffer_sharing (onnxruntime.transformers.io_binding_helper) yöntemi, her çifti tek bir cihaz tamponuna bağlar; böylece önbellek, host tarafına gidip gelmeden döngü boyunca yerinde okunur ve güncellenir.

  • ExecuTorch (XNNPACK) — ExecutorchConfig üzerinde bellek planlama tahsislerini kapatın, böylece yerinde yazma işlemi çağıranın kendi tensörüne yazılsın (her bayrağın ne yaptığını görmek için referansa bakın):

    config = ExecutorchConfig(
        backend="xnnpack",
        dynamic=True,
        alloc_graph_input=False,
        alloc_graph_output=False,
        alloc_mutable_buffers=False,
    )

    Sıfır kopyalı yerinde yazma, çağrıcının çalışma zamanında Method::set_output_data_ptr aracılığıyla çıktı tamponlarını bağlamasını da gerektirir — Python çalışma zamanında yüzeye çıkmaz (executorch.runtime.Method yalnızca execute/set_inputs/get_outputs sunar). Yukarıdaki bayraklar bunu kurar, ancak yerinde yazma sadece C++ için bir yoldur (aşağıdaki ExecuTorch decode döngüsü örneğine bakın). Python'dan, güncellenmiş önbelleği her adımda yöntem çıktılarını okuyarak geri alın.

Decode-loop inference examples

Döngü her arka uçta aynı şekildedir — baştan sona aynı grafiktir. Boş, sabit boyutlu bir önbellekten başlayın, tüm istemi bir kez besleyin (boş önbellek → ön doldurma), ardından her adımda bir token ekleyin (dolu önbellek → çözümleme). Her çağrı input_ids, nedensel bir attention_mask ve position_ids (her adımda yeni token sayısınca ilerletilir) ile önbelleği iletir ve her sorgu konumu için logitler döner. Her tokenın önbellekteki yeri, statik önbellek tarafından içsel olarak izlenir, bu nedenle çağrı boyunca ek bir şey iletmenize gerek yoktur. Önbelleğin nasıl kurulduğu çalışma zamanına göre değişir (Dynamo için StaticCache nesnesi, ONNX Runtime için ham cihaz tamponları, ExecuTorch için C++ tarafında çağıran dizileri), bu yüzden her sekme aşağıda kendi kurulumunu oluşturur. Dynamo ve ONNX Runtime sekmeleri önbelleği yerinde günceller; ExecuTorch’ün yerinde güncelleme yolu C++’tır (yukarıda belirtildiği gibi Python çalışma zamanı bunu yapamaz).

Dynamo
ONNX Runtime
ExecuTorch XNNPACK

torch.export, statik önbellek yazımını USER_INPUT_MUTATION olarak kaydeder; bu nedenle yüklenen grafiğin module() çağrısı, doğrudan ilettiğiniz StaticCache’i günceller — tek bir önbellek, bağlamaya veya geri aktarılmaya gerek kalmadan tüm döngü boyunca durumu taşır. register_pytree_node(StaticCache), torch.export.load’ün StaticCache girdisini düzleştirilmemiş hale getirmesini sağlar. Önbelleğin önceden başlatılması gerekir (torch.export, ayrılmış K/V’yi girdi belirlemesine gömdüğü için tembel boş bir önbellek eşleşmez) — ancak kaydedilen program kendi example_inputs’ini taşır; bu nedenle, boş olarak sıfırlanmış, zaten başlatılmış StaticCache şablonunu yeniden kullanın:

import copy
import torch
from transformers import StaticCache
from transformers.exporters.exporter_dynamo import register_pytree_node

register_pytree_node(StaticCache)
exported = torch.export.load("decode.pt2")
decode = exported.module()   # runs on the device its inputs / cache live on (CUDA here)

# the artifact carries an initialized StaticCache template — reuse it (reset to empty)
_, example_kwargs = exported.example_inputs
past_key_values = copy.deepcopy(example_kwargs["past_key_values"])
past_key_values.reset()

def causal_mask(positions, cache_len):   # [1, 1, len(positions), cache_len]
    return (torch.arange(cache_len, device="cuda")[None, :] <= positions[:, None])[None, None]

# prefill: the whole prompt in one call
positions = torch.arange(prompt_len, device="cuda")
logits = decode(input_ids=prompt_ids, attention_mask=causal_mask(positions, max_cache_len),
                position_ids=positions[None], past_key_values=past_key_values).logits
next_token = logits[:, -1:].argmax(-1)

# decode: query=1 buffers reused in place
input_ids = torch.empty((1, 1), dtype=torch.long, device="cuda")
position_ids = torch.empty((1, 1), dtype=torch.long, device="cuda")
attention_mask = torch.empty((1, 1, 1, max_cache_len), dtype=torch.bool, device="cuda")
slots = torch.arange(max_cache_len, device="cuda")
for position in range(prompt_len, max_cache_len):
    input_ids.copy_(next_token)
    position_ids.fill_(position)
    attention_mask[0, 0, 0].copy_(slots <= position)
    logits = decode(input_ids=input_ids, attention_mask=attention_mask,
                    position_ids=position_ids, past_key_values=past_key_values).logits
    next_token = logits[:, -1:].argmax(-1)

Kantizasyon

Her dışa aktarma yapılandırması, dışa aktarma sırasında modeli torch.export FX grafiğinde (her arka uç için PT2E veya NNCF) ya da dönüştürülmüş ONNX veya OpenVINO modelinde (ONNX Runtime veya NNCF) kuantize eden bir quantizer alır. Kuantizörler, arka uçları, kalibrasyon ve bunlardan birini nasıl ekleyeceğiniz hakkında bilgi için Dışa aktarmaları kuantize etme bölümüne bakın.

Kısıtlamalar ve geçici çözümler

torch.export, torch.onnx.export ve ExecuTorch, belirli PyTorch kalıpları etrafında pürüzlere sahiptir. Dışa aktarıcılar, dışa aktarma akışında iyi tanımlanmış noktalarda uygulanan küçük bir grup geri alınabilir yama ve FX düzeyinde düzeltme ile bu sorunların etrafından dolaşır. Bunların hiçbiri herkese açık export API'sinden görünmez, ancak bilmeniz gereken en yaygın şeyler şunlardır:

  • FlashAttention ve FlexAttention hiçbir backend üzerinde dışa aktarılamaz. sdpa tercih edilen ayar olup eager de çalışır (daha yavaş). Model başka bir ayar kullanıyorsa, export çağrılmadan önce bunlardan birini modelde ayarlayın.
  • grouped_mm, DynamoExporter üzerinden sorunsuz izlenir ve OnnxExporter için otomatik olarak çevrilir. XNNPACK veya MLX ile ExecutorchExporter kullanıldığında, dışa aktarıcı dışa aktarma öncesinde MoE uzmanlarını batched_mm olarak değiştirir.
  • Sliding-window katmanları (Mistral, Gemma 3) tam bir anahtar-değer önbelleğiyle dışa aktarılır; kayan maske hâlâ pencereyi uygular.

Sonraki adımlar

Update on GitHub