Paylaşımlı grafiği bölmeden ayrı release: Meta F3 Lightning ile feature’ları 3,6 kat hızlı yayınlamak
F3 Lightning: How Meta Accelerates Ads ML Features to Production at Scale
F3 (Facebook Feature Framework), Meta’nın reklam ranking modellerinin altındaki ML feature’larını yazma, derleme ve sunma çerçevesi; tek bir istek 20.000’den fazla feature gerektirebiliyor. ML sistemleri ham veriyi doğrudan tüketmez: bir modelin tahmin yapmadan önce depolanmış sinyalleri okuması, olayları bir zaman penceresine göre filtrelemesi, sayması ya da toplaması, normalleştirmesi ve ara sonuçları birleştirmesi gerekir. En basit tasarım her feature’ı bağımsız bir fonksiyon sayar ama ölçekte bu israftır, çünkü feature’lar hesaplama açısından bağımsız değil: yedi günlük tıklama sayısı ile yedi günlük gösterim sayısı aynı olay kaynağını okuyup aynı zaman filtresini uygulayabilir ve bir tıklama oranı feature’ı ikisini yeniden kullanabilir.
F3’ün çözümü bir DAG. Feature çıkarımı, her düğümün bir işi (girdi okuma, filtre, toplama) yaptığı ve kenarın bir hesaplamanın başka bir hesaplamanın sonucuna bağlı olduğunu gösterdiği bir yönlü döngüsüz graf (directed acyclic graph). Mühendisler her feature’ı bağımsız yazıyor; F3 derleyicisi her tanımı küçük bir grafa çevirip bir servisin kullandığı tüm feature’ların graflarını tek bir merged graph’ta birleştiriyor. İki feature’ın paylaştığı işlem (yedi günlük filtre gibi) tek düğüme indirgeniyor ve istek başına bir kez çalışıyor.
Bedeli: her release hep-ya-da-hiç. Merged graph hesaplamayı verimli paylaştırdı ama aynı zamanda release birimi oldu: bozuk tek bir tanım diğer tüm feature’ların çıkışını engelleyebiliyordu. Yazının örneği: A’dan G’ye yedi feature var, beşi geçerli, D ve G ilgisiz hatalar içeriyor. İlk deneme D’de fail ediyor, yedisi de çıkmıyor; D düzeltilince ikinci deneme G’de fail ediyor; ancak üçüncü denemede tüm graf production’a ulaşıyor. F3 birkaç yüz feature’ı sunarken merge’ler çoğunlukla başarılıydı; bugün 20.000’den fazla feature var ve farklı feature türleri kendi kontrollerini gerektiriyor. Merged graph üzerinde yapılan her iyileştirme release hızını bir süre geri getirdi ama feature’lar eklendikçe kazanç eridi, çünkü hepsi hâlâ birlikte çıkıyordu.
F3 Lightning iki değişiklik getiriyor. *Deployment granularity:* her feature, doğrulanabilen, yayınlanabilen ve geri alınabilen bağımsız bir konfigürasyon. Derleyici her feature’ı kendi başına, komşusundan hiçbir şey ödünç almadan, gerekli tüm düğümleri sırasıyla taşıyan tek bir konfigürasyona çeviriyor. Release yolu ‘ya hepsi ya hiçbiri’ yığını yerine sıralı bir kuyruk; değişiklikler neyi engellediklerine göre önceliklendiriliyor. *Efficiency parity:* F3’ün verimi merged graph’tan geliyordu, her feature’a ayrı release vermek bu kaynağı kaldırıyor. İlk prototipler yalnızca deployment’ı ayırdı ve feature’lar bağımsız çıksa da yürütme paylaşılmadığından CPU kullanımı belirgin biçimde arttı. Çözüm, merge’ü geri getirmeden paylaşımlı yürütmeyi geri getirmek: başlangıçta F3 Lightning yeniden bir merged graph kurmuyor, aktif feature konfigürasyonlarını alıp ortak işi birleştiriyor ve tek bir yürütme sırasına diziyor. Verimi korumak için dört optimizasyon: stable computation identifier’lar (aynı hesaplamanın feature’lar arasında tutarlı kimliği), tek bir paylaşımlı execution plan, tüm feature’lar için tek bir paylaşımlı bellek buffer’ı ve doğrudan dizi erişimi için dense index mapping.
Sonuç: karşılaştırılabilir extraction feature’ları production’a önceki F3’ten yaklaşık 3,6 kat hızlı ulaşıyor ve altyapı hesaplama maliyeti artmıyor. Daha kısa release döngüsü aynı sürede daha fazla model iterasyonu demek.
Öne çıkanlar
- Paylaşımlı hesaplama verim getirir ama paylaşım birimi release birimiyse tek bir hata hepsini bloklar.
- Dağıtım granülaritesi ile yürütme paylaşımı ayrı ayrı çözülebilir: bağımsız release, başlangıçta birleştirilen çalışma planı.
- İlk prototip yalnızca bir şeyi çözdüyse (bağımsız release) diğerini (verimlilik) ölçmek gerekir; Meta CPU artışını fark edip dört optimizasyon ekledi.
- Her birimi kendi başına derleyip doğrulamak, bir hatayı kendi biriminde tutar.
- Release kuyruğunu ‘neyi engelliyor’a göre önceliklendirmek ortalama bekleme süresini düşürür.
Neden önemli?
‘Hepsini birlikte derle, hepsini birlikte yayınla’ düzeni küçükken basit ve ucuzdur, ama birimler çoğaldıkça en yavaş ya da en kırık parça herkesin hızını belirler. Bu yazı, bağımsız yayınlamanın bedelini (kaybolan paylaşım) ölçüp geri kazanmanın somut bir örneği.
Pratikte
Aynı sorunu bir monorepo ya da çok modüllü bir projede de yaşarsın: bir modül bozulunca hepsinin CI’ı kırmızı oluyorsa release birimi çok büyüktür. Küçük bir başlangıç: CI’da modülleri ayrı job’lara böl ve yalnızca değişen modülleri (path filter) derle ve test et. Paylaşılan ortak işi (bağımlılık indirme, derleme cache’i) kaybetmemek için cache’i ortak tut. Böylece bağımsız ilerleme ile paylaşılan verimi birlikte alırsın.
Sözlük
- feature store
- ML modellerinin kullandığı özelliklerin (feature) tutarlı biçimde hesaplandığı ve sunulduğu katman.
- DAG
- Directed acyclic graph: kenarların yönlü olduğu ve döngü içermeyen graf; hesaplama bağımlılıklarını göstermek için kullanılır.
- merged graph
- Birçok bağımsız grafın ortak düğümleri birleştirilerek tek grafa dönüştürülmüş hâli.
- release unit
- Birlikte yayınlanan ve birlikte geri alınan en küçük değişiklik birimi.