Python tuzakları
Pipelogic'in Python component API'si küçüktür, ama platformun process()'in nasıl davranabileceğine dair görüşleri vardır. Bu sayfadaki kalıplar, temiz bir şekilde derlenip yayımlanan, fakat sonra çalışma zamanında başarısız olanlardır — genellikle dönüş şekli, stateful kontrat ya da içe aktarma yerleşimi runtime'ın beklediğine uymadığı için.
Temiz inşa edilen ama hiç output üretmeyen bir component'i debug etmeden önce bunu bir kez okuyun.
Diğer yazarları önce ısıran şeyler, tuzağın bulunduğu yere göre düzenlenmiş.
Yapılandırma
runtime base'in zaten getirdiği paketleri sabitlemeyin
runtime base imajı numpy, pyyaml, protobuf, pika ve pipelogic getirir. Bunlardan herhangi birini requirements.txt içinde sabitlemek sessizce yanlış davranmaz — build system'in requirements.txt doğrulayıcısı yüklemeyi, size sabitlemeyi kaldırmanızı söyleyen bir alan hatasıyla reddeder. Gerçekten farklı bir sürüme ihtiyacınız varsa, yeniden sabitlemek yerine daha ağır bir build_system seçin.
# WRONG — rejected at validation time
numpy==2.0.0
# Right — the runtime base supplies numpy
Her bağımlılığı tam olarak sabitleyin
==1.2.3, asla >=, ~=, ==1.2.* gibi bir joker, bir URL/VCS referansı veya hiç belirteç olmadan — doğrulayıcı bunların her birini reddeder. Gevşek sabitlemeler build'leri tekrarlanamaz kılar ve yeniden inşada sessizce yeni CVE'leri içeri çeker.
Doğru build_system'i seçin
build_system varsayılanı olmayan zorunlu bir alandır. Değeri, component'inizin üzerine inşa edildiği runtime base imajını seçer; o base'in getirmediği bir kütüphaneyi içe aktarmak (örn. yalnızca CPU'lu bir base altında torch) çalışma zamanında başarısız olur. component registry genelinde görülen değerler:
| build_system | Tipik kullanım |
|---|---|
2 | Yalın Python runtime |
2-ml | Yaygın ML runtime |
2-opencv4.11 | OpenCV ağırlıklı component'ler |
2-cuda12.6 / 2-cuda12.8-onnxrtgpu1.22 | CUDA / ONNX Runtime GPU |
2-cuda12.8-torch2.8-onnxrtgpu1.22 | PyTorch + ONNX Runtime |
2-cuda12.8-torch2.8-ultralytics | Ultralytics yığını |
2-cuda12.8-torch2.8-onnxrtgpu1.22-roboflow | Roboflow çıkarımı |
custom | Kendi base imajını getir |
Değeri içe aktardığınız kütüphanelere göre eşleştirin. Tam matris için concepts/build-systems'e bakın.
Tipler
Bytes / List'ten numpy erişimi: hangi çağrının kopyaladığını bilin
import numpy as nparr = pipe_bytes.unsafe_numpy(dtype=np.uint8, shape=(h, w, 3)) # zero-copy, READ-ONLY viewarr = np.asarray(pipe_bytes) # copy-on-writearr = pipe_bytes.safe_numpy() # copy-on-writearr = np.array(pipe_bytes, copy=True) # always an independent copy
unsafe_numpy() yalnızca kaynak Bytes/List nesnesi kapsamdayken geçerli olan, salt-okunur, kopyasız bir görünüm döndürür — onu çağrının ötesinde saklamayın ve üzerinden yazmayın. np.asarray(...) ve .safe_numpy() copy-on-write'tır: kapsamdayken tutmak güvenlidir ve mutasyonlar ilk yazma özel bir kopyayı zorlayana kadar arabelleğe geri yansır. Girdiden tamamen bağımsız bir değere ihtiyacınız olduğunda np.array(..., copy=True) kullanın.
Varsayılan int Int64'tür, varsayılan float Double'dır
from pipelogic.types import ListL = List([1, 2, 3]) # element type: Int64L = List([1.0, 2.0]) # element type: DoubleL = List([1, 2, 3], '[Int32]') # explicit Int32
Tipli değerler için dict inşa etmeyin
High-level wrapper'lar bir nedenle vardır — named-type registration'ı ve alan yerleşimini sizin için hallederler:
# WRONG — manual dict construction breaks when type fields driftreturn {"width": w, "height": h, "data": arr.tobytes(), "format": ...}# Right — let the wrapper do itreturn Image(arr, color_space=ColorSpace.BGR)
Aynı şey BoundingBox, Tensor, AudioFrame, Mask, Landmark vb. için de geçerlidir. pipelogic.cv ve pipelogic.types içindeki wrapper'ları tercih edin — alan yerleşimini ve named-type registration'ı sizin için hallederler. Yalnızca wrapper'ların kapsamadığı bir nedeniniz olduğunda ham dict'lere inin.
Components
Virtual input parametre adıyla opt-in'dir
virtual-input mesajları almak için component fonksiyonunuzda parametreyi virtual_input olarak adlandırın. runtime adı tespit eder ve component'i virtual-input moduna geçirir:
def from_vin(virtual_input): return virtual_input[0]run(from_vin)
1-output'lu bir component'ten bir tuple döndürmek onu tek output olarak sarar
component.yml bir output_type deklare ediyorsa ve fonksiyonunuz (a, b) döndürüyorsa, runtime tuple'ı tek output'unuz olarak serileştirir — otomatik bölmez. Birden fazla output döndürmek için, bunları component.yml içinde deklare edin:
worker: output_types: - BoundingBox - Image
ardından (boxes, image)'ı deklare edilen sırada döndürün.
Stateful component'ler bir dict döndürmelidir
run'a initial_state= ilettiğinizde bir component stateful olur. O andan itibaren fonksiyon bir state argümanı alır ve her iki anahtarı da döndürmelidir:
def stateful(x, state): return {"output": x * 2, "state": state + 1} # required keysrun(stateful, initial_state=0)
Döndürülen dict'ten state'i atlamak ValueError("state must be provided when stateful is True") fırlatır.
Virtual-output component'leri bir virtual_output listesi döndürmelidir
run'a use_virtual_output=True ileterek virtual output'u etkinleştirin. Fonksiyon ardından virtual_output anahtarı bir liste (muhtemelen boş) olan bir dict döndürür; her öğe normal output'lardan önce virtual-output stream'inde yayımlanır:
def with_virtual_out(x): return {"output": x, "virtual_output": [item1, item2]}run(with_virtual_out, use_virtual_output=True)
virtual_output anahtarını atlamak hata fırlatır.
CV wrapper'ları
Stereo ses otomatik olarak mono'ya karıştırılmaz
AudioFrame.numpy() orijinal (samples, channels) float32 şeklini döndürür. Birçok ses modeli mono bekler — .mono()'yu açıkça çağırın:
audio_arr = audio.mono() # 1-D float32, channels averaged
.mono() float32 kalır; bir model int16 PCM istiyorsa audio.to_int16(mono=True) kullanın.
Image color space'i zorunlu kılınmıştır — yalan söylemeyin
Image(arr, color_space=ColorSpace.RGB) hatta RGB'yi ilan eder. Belirli bir color space bekleyen aşağı akış consumer'ları (örn. bir Image.to_gray() zinciri) doğru dönüşümü deklare edilen color space'e göre hesaplar. RGB olarak etiketlenmiş BGR verisi iletirseniz, her aşağı akış dönüşümü yanlış olur.
image.numpy() geçerli color space'i döndürür
Girdi BGR idiyse, image.numpy() BGR'dir. Belirli bir uzay istiyorsanız to_bgr()/to_rgb()/to_gray() çağırın — bunlar her zaman doğru uzayı döndürür (ve dönüşüm gerektiğinde kopyalar).
Image.resize((h, w)) önce yükseklik, sonra genişlik alır
OpenCV tam tersidir — cv2.resize(img, (w, h)). Pipelogic'in wrapper'ı numpy shape konvansiyonlarına uymak için (height, width) alır.
Dosya ve model yolları
find_model_file tam olarak bir eşleşme gerektirir
find_model_file bir dizini .pt, .onnx, .safetensors veya .bin dosyaları için özyinelemeli olarak arar (extensions= ile geçersiz kılın). Sıfır eşleşme FileNotFoundError fırlatır; birden fazlası ValueError fırlatır. Bu kasıtlıdır — hangi ağırlık dosyasının "model" olduğu konusunda açık olmaya zorlar. Çok dosyalı checkpoint'ler için bir üst dizini gösterin ve kendi loader'ınızı yazın.
ensure_local_dir offline modu dikkate alır
ensure_local_dir bir yerel dizin yolunu olduğu gibi döndürür ve aksi halde repo'yu snapshot ile indirir. Container env'inizde HF_HUB_OFFLINE=1 (veya TRANSFORMERS_OFFLINE=1) ayarlayın; indirme local_files_only'e geçer — build zamanında önceden getirilen cache'i sunar ve asla ağa erişmez.
Init ve başlatma
pipelogic'i lazy içe aktarmayın
pipelogic içe aktarma zamanında çalışan backend'e bağlanır. İçe aktarmayı geciktirirseniz, component'iniz stream'lerine bağlanamaz. from pipelogic.worker import run'u main.py'nin en üstüne koyun.
Mutable yapılandırma
Mutable parametreler yalnızca config.sync()'i drain ettiğinizde güncellenir
component.yml içinde mutable olarak deklare edilen parametreler config özniteliklerini kendiliğinden değiştirmez. config.sync()'i tick başına bir kez çağırmanız gerekir — bekleyen güncelleme kuyruğunu drain eder, yeni değerleri config üzerine uygular ve değişen anahtarların kümesini döndürür. config.threshold'u okuyup config.sync()'i hiç çağırmayan bir component, başladığı değeri görmeye devam eder.
from pipelogic.worker import config, rundef process(x): changed = config.sync() # drain once per tick if "threshold" in changed: ... # react to the new value return x
Değişen anahtar kümesini HotSwapModel.apply'a kendiniz iletin
HotSwapModel, izlenen bir config anahtarı değiştiğinde bir model backend'i yeniden yükler, ama kasıtlı olarak config.sync()'i asla kendi çağırmaz — böylece tek bir component'teki birkaç consumer aynı güncelleme batch'ine tepki verebilir. config.sync()'i siz drain edersiniz ve sonucunu iletirsiniz:
def process(x): swapper.apply(config.sync()) # you drain, HotSwapModel reacts return swapper.backend.run(x)
Rebuild (veya yeni bir model id için ön-doğrulama indirmesi) başarısız olursa, önceki backend canlı kalır ve bir uyarı loglanır — component, son bilinen iyi modelle hizmet vermeye devam eder.
İlgili
- Quickstart — tuzaksız temiz başlangıç.
- Tipler — tam type kataloğu.
- Python component — Python component giriş noktası referansı.
- Config — component config'i okuma ve senkronize etme.
- Çıkarım yardımcıları — model yükleme ve
HotSwapModel.