Adaptery niestandardowe Foundation Models: kiedy warto trenować
Dokumentacja adapterów Apple wyznacza ścieżkę wąsko: dla większości zadań związanych z inżynierią promptów, generowaniem sterowanym i narzędziami należy używać bazowego modelu systemowego, a niestandardowy Adapter trenować jedynie wtedy, gdy zadanie wymaga specjalizacji wag modelu, a zespół czuje się swobodnie w trenowaniu modeli foundation w Python.14
Własna dokumentacja Apple dotycząca tego samego typu cytuje dosłownie: „Adaptery zajmują dużo miejsca i nie są zalecane dla większości aplikacji.”1 Wcześniejszy wpis w tym klastrze, Foundation Models Use Cases, omawiał tory, którymi powinna jechać większość aplikacji. Niniejszy wpis to trzeci tor: cykl operacyjny trenowania, pakowania i dostarczania niestandardowego adaptera oraz wyraźne wskazówki Apple dotyczące tego, kiedy nie należy tego robić.
TL;DR
- Toolkit Apple identyfikuje metodę trenowania jako LoRA: wagi bazowe pozostają zamrożone, podczas gdy trenowane są wagi adaptera.2
- Każdy adapter jest powiązany z jedną wersją modelu systemowego. Gdy Apple aktualizuje model bazowy, adapter należy przetrenować ponownie.3
- Zalecenie Apple, w ich własnych słowach: „Dla większości zadań związanych z inżynierią promptów, generowaniem sterowanym i narzędziami należy używać bazowego modelu systemowego. Jeśli zachodzi potrzeba specjalizacji modelu, należy wytrenować niestandardowy Adapter… Niestandardowych adapterów należy używać tylko wtedy, gdy zespół czuje się swobodnie w trenowaniu modeli foundation w Python.”1
- Pliki adapterów są duże, nie powinny być dostarczane w głównym pakiecie aplikacji i są przekazywane na żądanie przez hostowane pakiety zasobów oraz Background Assets.23
- Apple wskazuje, że adaptery warto rozważyć dopiero wtedy, gdy inżynieria promptów lub wywoływanie narzędzi nie sprostały zadaniu, lub gdy istniejący dostrojony serwerowy LLM, ekspertyza dziedzinowa, zgodność ze stylem/formatem/polityką lub docelowa latencja uzasadniają koszt.2
Czym właściwie jest adapter
SystemLanguageModel.Adapter to struct, dostępny w iOS, iPadOS, Mac Catalyst, macOS i visionOS, wszystkich w wersji 26.0+.4 Opis tego typu według Apple:
„Dla większości zadań związanych z inżynierią promptów, generowaniem sterowanym i narzędziami należy używać bazowego modelu systemowego. Jeśli zachodzi potrzeba specjalizacji modelu, należy wytrenować niestandardowy Adapter, aby zmienić wagi modelu systemowego i zoptymalizować go pod własne zadanie. Niestandardowych adapterów należy używać tylko wtedy, gdy zespół czuje się swobodnie w trenowaniu modeli foundation w Python.”4
Mechanizm jest udokumentowany. Przewodnik Apple po trenowaniu adapterów stwierdza wprost:2
„Model systemowy korzysta z podejścia parameter-efficient fine-tuning (PEFT) znanego jako LoRA (Low-Rank Adaptation). W LoRA oryginalne wagi modelu są zamrożone, a małe trenowalne macierze wag zwane »adapterami« są osadzane w sieci modelu. Podczas trenowania aktualizowane są tylko wagi adaptera, co znacznie zmniejsza liczbę parametrów do wytrenowania.”
LoRA jest techniką publiczną z udokumentowaną historią publikacji.5 Udokumentowana powierzchnia Apple to toolkit, eksport .fmadapter, pakowanie do asset packów, dostarczanie przez Background Assets oraz ładowanie w runtime przez SystemLanguageModel.Adapter.234
Powierzchnia API tego typu
Apple wymienia następującą powierzchnię typu Adapter:4
init(fileURL: URL) throws: „Tworzy adapter z URL pliku.”init(name: String) throws: „Tworzy adapter pobrany z frameworka background assets.”func compile() async throws: „Przygotowuje adapter przed jego użyciem z LanguageModelSession. Należy to wywołać, jeśli adapter ma model draft.”var creatorDefinedMetadata: [String : Any]: „Wartości odczytane z pola creator defined metadanych adaptera.”static func removeObsoleteAdapters() throws: „Usuwa wszystkie nieaktualne adaptery, które nie są już zgodne z bieżącymi modelami systemowymi.”static func compatibleAdapterIdentifiers(name: String) -> [String]: „Pobiera wszystkie identyfikatory adapterów zgodnych z bieżącymi modelami systemowymi.”enum AssetError: typ błędu dla niepowodzeń związanych z zasobami.
SystemLanguageModel ma sparowany inicjalizator dla adapterów: convenience init(adapter: SystemLanguageModel.Adapter, guardrails: SystemLanguageModel.Guardrails), z opisem „Tworzy bazową wersję modelu z adapterem.”6
Klucz uprawnienia wymagany wyłącznie przy wdrożeniu to com.apple.developer.foundation-model-adapter: „Wartość logiczna wskazująca, czy aplikacja może włączyć niestandardowe adaptery dla frameworka Foundation Models.”6 Nie jest on potrzebny do trenowania ani lokalnych testów w Xcode; jest natomiast wymagany przed wysyłką do App Store.3
Zasady Apple „kiedy rozważyć adapter”
Strona toolkitu wymienia konkretne sygnały adopcyjne:2
- „Dysponujesz zbiorem danych odpowiednim do użycia z LLM” lub korzystasz już z dostrojonego serwerowego LLM i chcesz uzyskać równoważność on-device.
- „Potrzebujesz, aby model stał się ekspertem dziedzinowym.”
- „Potrzebujesz, aby model przestrzegał określonego stylu, formatu lub polityki.”
- „Inżynieria promptów nie zapewnia wymaganej dokładności ani spójności dla zadania.”
- „Chcesz mniejszej latencji w czasie wnioskowania. Jeśli rozwiązania oparte na inżynierii promptów wymagają długich promptów z przykładami przy każdym wywołaniu, adapter wyspecjalizowany w danym zadaniu oferuje minimalne promptowanie.”
Ten sam przewodnik wymienia również koszty, które trzeba przyjąć:2
- Zbiór danych z parami prompt-odpowiedź, które demonstrują docelową umiejętność.
- Proces oceny jakości adapterów.
- Proces ładowania adapterów do aplikacji z serwera.
I podatek od pamięci masowej: „Każdy adapter zajmie około 160 MB miejsca w aplikacji. Podobnie jak inne duże zasoby, adaptery nie powinny być częścią głównego pakietu aplikacji, ponieważ przy wielu wersjach adapterów aplikacja stanie się zbyt duża, aby ludzie mogli ją zainstalować.”2
Rekomendacja frameworka, powtórzona przez Apple w dwóch oddzielnych miejscach, brzmi: domyślnie używać inżynierii promptów wraz z wywoływaniem narzędzi, a po adaptery sięgać dopiero, gdy powyższa rubryka jest spełniona.
Trenowanie w kształcie nadanym przez Apple
Apple podaje, że toolkit zawiera kod Python z przykładami, zasoby modelu dla konkretnej wersji modelu systemowego, narzędzia do eksportu .fmadapter oraz narzędzia do pakowania asset packów.2
Wymagania dotyczące zbioru danych to pary prompt/odpowiedź w formacie jsonl, około 100-1000 próbek dla podstawowych zadań i 5000+ dla zadań złożonych. Schema.md obejmuje pola generowania sterowanego i bezpieczeństwa AI.2
Wymagania sprzętowe: „Mac z Apple silicon i co najmniej 32 GB pamięci, lub maszyny Linux GPU.” Python 3.11 lub nowszy.2
Zasada Apple dotycząca jakości danych jest prosta: jakość bije ilość.2
Trenowanie uruchamia się z punktu wejścia toolkitu train_adapter:
python -m examples.train_adapter \
--train-data /path/to/train.jsonl \
--eval-data /path/to/valid.jsonl \
--epochs 5 \
--learning-rate 1e-3 \
--batch-size 4 \
--checkpoint-dir /path/to/my_checkpoints/
Opcjonalnie, po wytrenowaniu adaptera, można wytrenować pasujący model draft.2 Model draft to mniejsza wersja systemowego modelu bazowego, która umożliwia speculative decoding — opublikowaną technikę przyspieszania wnioskowania.7 Ujęcie Apple: „Jeśli zdecydujesz się nie trenować modelu draft, speculative decoding nie będzie dostępne dla danego przypadku użycia adaptera.”2
Ograniczenie pojedynczej wersji
Najbardziej brzemienny w skutki operacyjnie fakt dotyczący adapterów to powiązanie z konkretną wersją modelu systemowego:3
„Każdy adapter jest zgodny z jedną konkretną wersją modelu systemowego. Należy wytrenować nowy adapter dla każdej nowej wersji modelu bazowego. Jeśli aplikacja działa na urządzeniu osoby bez zgodnego adaptera, wystąpi błąd runtime.”
Pobrane 4 maja 2026, tabela toolkitu Apple wymienia Beta 0.1.0 i Beta 0.2.0 jako usunięte oraz 26.0.0 jako pierwszą pełną wersję toolkitu. Reguła kadencji Apple to jeden toolkit na aktualizację modelu systemowego.2 Pełne sformułowanie: „Nowy toolkit będzie wydawany dla każdej aktualizacji modelu systemowego. Model systemowy jest współdzielony między iOS, macOS i visionOS, a aktualizacje modelu systemowego będą występowały w ramach aktualizacji systemów operacyjnych tych platform (choć nie każda aktualizacja systemu operacyjnego będzie zawierała aktualizację modelu).”2
Implikacja operacyjna: zespoły aplikacji wysyłające adaptery wpisują się w cykl aktualizacji modelu, który biegnie w kadencji Apple. Każda zmiana modelu bazowego wymusza ponowne trenowanie, ponowną ewaluację i republikowanie.
Pakowanie jako asset packi
Reguła Apple: pliki adapterów są zbyt duże dla pakietu aplikacji; należy je hostować przez App Store Connect lub własny serwer, a następnie pobierać na żądanie adapter zgodny z urządzeniem.3
Toolkit produkuje pakiety .fmadapter, które toolkit pakuje również jako asset packi Background Assets. Narzędzie wiersza poleceń ba-package z Xcode 16 lub nowszego wykonuje pakowanie; toolkit się do niego odwołuje.3
Opcje hostingu:3
- Apple-Hosted, Managed. Apple hostuje zasób; system operacyjny zarządza cyklem pobierania.
- Self-Hosted, Managed. Hosting na własnym serwerze; system operacyjny zarządza cyklem pobierania.
- Self-Hosted, Unmanaged. Samodzielny hosting i samodzielne zarządzanie cyklem życia.
Wymagane klucze Info.plist różnią się w zależności od opcji hostingu:3 Apple-Hosted Managed wymaga BAHasManagedAssetPacks, BAAppGroupID i BAUsesAppleHosting; Self-Hosted Managed wymaga pierwszych dwóch; Self-Hosted Unmanaged nie wymaga żadnego. Każda ścieżka ma także cel rozszerzenia asset-downloader, który Xcode generuje.
Wybór właściwego adaptera w czasie działania
Gdy generowany jest plik BackgroundDownloadHandler.swift rozszerzenia asset-downloader, Xcode podpina callback shouldDownload(_:). Przykładowe ciało Apple dla zasobów adapterów:3
func shouldDownload(_ assetPack: AssetPack) -> Bool {
if assetPack.id.hasPrefix("mygameshader") {
return true
}
return SystemLanguageModel.Adapter.isCompatible(assetPack)
}
Próbka Apple jest jedyną udokumentowaną kontrolą w czasie działania. Wyrażenie SystemLanguageModel.Adapter.isCompatible(assetPack) to to, co próbka zwraca dla asset packów adapterów; należy traktować to wywołanie jako nieprzejrzyste poza tym, co pokazuje próbka.3
Ładowanie i śledzenie pobrań
Gdy zasób jest już na urządzeniu, ścieżka ładowania wygląda tak:3
SystemLanguageModel.Adapter.removeObsoleteAdapters()
let adapter = try SystemLanguageModel.Adapter(name: "myAdapter")
Konstrukcja inicjuje pobieranie, jeśli urządzenie nie ma w cache zgodnego adaptera. Uwaga Apple dotycząca UX: „Ponieważ adaptery mogą mieć duży rozmiar danych, ich pobieranie może zająć trochę czasu, zwłaszcza gdy użytkownik korzysta z Wi-Fi lub sieci komórkowej. Jeśli osoba nie ma połączenia sieciowego, nie będzie mogła od razu skorzystać z adaptera.”3
Sekwencja statusów pochodzi z AssetPackManager:3
let assetpackIDList = SystemLanguageModel.Adapter.compatibleAdapterIdentifiers(name: name)
if let assetPackID = assetpackIDList.first {
let statusUpdates = AssetPackManager.shared.statusUpdates(forAssetPackWithID: assetPackID)
for await status in statusUpdates {
switch status {
case .began(let assetPack): ...
case .paused(let assetPack): ...
case .downloading(let assetPack, let progress): ...
case .finished(let assetPack): ...
case .failed(let assetPack, let error): ...
@unknown default: ...
}
}
}
Pięć udokumentowanych przypadków DownloadStatusUpdate: .began, .paused, .downloading, .finished, .failed.3 Gałąź @unknown default frameworka jest obowiązkowa, ponieważ Apple może dodać przypadki w przyszłych wersjach SDK.
Po osiągnięciu statusu .finished adapter jest gotowy do podłączenia do sesji:
let adaptedModel = SystemLanguageModel(adapter: adapter)
let session = LanguageModelSession(model: adaptedModel)
Model draft i jego limit częstotliwości
Jeśli adapter dostarczony został wraz z modelem draft, wywołanie adapter.compile() przygotowuje go do użycia. Dokumentacja Apple wskazuje to jako oddzielny, kosztowny obliczeniowo krok:3
„Przy pierwszym pobraniu nowej wersji adaptera przez urządzenie, wywołanie
compile()w pełni kompiluje model draft i zapisuje go na urządzeniu. Przy kolejnych uruchomieniach aplikacji, wywołaniecompile()sprawdza, czy istnieje zapisany skompilowany model draft, i zwraca go natychmiast, jeśli istnieje.”
Istnieje opublikowany limit częstotliwości:3
„Ograniczanie częstotliwości chroni zasoby urządzenia współdzielone przez wszystkie aplikacje i procesy. Jeśli framework uzna, że konieczna jest nowa kompilacja, ogranicza proces kompilacji na wszystkich platformach z wyjątkiem macOS do trzech kompilacji modelu draft na aplikację dziennie.”
Limit częstotliwości wyklucza macOS; na innych platformach nowa kompilacja modelu draft jest ograniczona do trzech kompilacji na aplikację dziennie.3 Apple zaleca uruchamianie kompilacji wewnątrz zadania zaplanowanego przez Background Tasks, aby praca nie blokowała uruchamiania aplikacji.3
Ostrzeżenie Apple dotyczące testów w Xcode: uruchamianie przez Xcode zmienia UUID aplikacji, więc pełna kompilacja jest wykonywana przy każdym uruchomieniu i może wyzwolić limit częstotliwości.3
Testowanie i ograniczenie symulatora
Testowanie adapterów wymaga fizycznego urządzenia. Apple jest jednoznaczne: „Testowanie adapterów wymaga fizycznego urządzenia i nie jest obsługiwane na symulatorze.”3
Do lokalnych testów w Xcode inicjalizuje się z URL pliku, a nie z nazwy:3
let localURL = URL(filePath: "absolute/path/to/my_adapter.fmadapter")
let adapter = try SystemLanguageModel.Adapter(fileURL: localURL)
Co do publikacji, Apple zaleca importowanie plików adapterów wyłącznie do testów lokalnych, a następnie ich usuwanie przed wydaniem i pobieranie adapterów na żądanie.3
Co ta ścieżka kosztuje w wymiarze operacyjnym
Składając cykl życia w całość, aplikacja wysyłająca niestandardowy adapter zapisuje się na:
- Infrastrukturę trenowania Python. Mac z Apple silicon i co najmniej 32 GB pamięci, lub maszyna Linux GPU.2
- Kadencję ponownego trenowania w rytmie Apple. Każda aktualizacja modelu systemowego oznacza świeży adapter i świeżą wersję toolkitu.3
- Stos serwujący. Albo asset packi hostowane przez Apple poprzez App Store Connect, albo własny serwer z integracją asset-downloader.3
- Adaptery w wielu wersjach w pamięci. Wiele wersji modelu bazowego w obiegu oznacza wiele hostowanych adapterów, a urządzenie pobiera ten pasujący.3
- Bramę uprawnień. Account Holder członkostwa Apple Developer Program składa wniosek; bez zatwierdzenia nie da się wysłać aplikacji.2
- Podatek 160 MB na każdą wersję adaptera. Nie w pakiecie aplikacji, lecz na urządzeniu użytkownika po pobraniu.2
- Testy na fizycznym urządzeniu. Symulator nie uruchamia adapterów.3
Tak wygląda koszt operacyjny w prostym ujęciu. Korzyść, gdy sygnały adopcyjne są jednoznaczne, jest taka: model on-device staje się wyspecjalizowany dla zadania przy minimalnym promptowaniu i niższej latencji. Dla aplikacji, które już płacą za dostrojone wnioskowanie po stronie serwera i chcą równoważności on-device, w prostych słowach na tym właśnie polega wymiana.
Wnioski
- Adaptery to LoRA, według udokumentowanej techniki Apple. Zamrożone wagi bazowe, małe trenowalne macierze przepuszczone przez sieć modelu, podczas trenowania aktualizowane są tylko wagi adaptera.2
- Jeden adapter na wersję modelu systemowego, bez wyjątków. Należy planować ponowne trenowanie powiązane z wydaniami systemu.3
- Przebieg
.fmadapterjest end-to-end. Trenowanie w Python, pakowanie w toolkicie, hosting jako asset pack Background Assets, ładowanie po nazwie w aplikacji, kompilacja modelu draft w zadaniu w tle. - Samo Apple zaleca, aby większość aplikacji nie szła tą drogą. Dwie oddzielne strony dokumentacji Apple zniechęcają do tego w większości przypadków użycia.1 Należy przeczytać rubrykę na stronie toolkitu; domyślna odpowiedź brzmi „nie”.
- Testy na sprzęcie. Symulator nie uruchamia adapterów. Plan testów warto zbudować wokół sesji na fizycznym urządzeniu i okna kompilacji frameworka
Background Tasks.
Pełny klaster Apple Ecosystem: rubryka decyzyjna dla wbudowanej specjalizacji; protokół Tool w sercu frameworka; podział agentic workflow między LLMami w aplikacji a tymi narzędziowymi; App Intents vs MCP dla szerszej kwestii routingu. Hub znajduje się w serii Apple Ecosystem. Szerszy kontekst iOS z agentami AI znajduje się w przewodniku iOS Agent Development.
FAQ
Skąd mam wiedzieć, czy moja aplikacja faktycznie potrzebuje niestandardowego adaptera?
Apple zaleca model bazowy do większości zadań inżynierii promptów, generowania sterowanego i narzędzi, a przewodnik toolkitu wskazuje, że adaptery niosą strome wymagania trenowania i ponownego trenowania. Domyślna odpowiedź to „nie”, chyba że sygnały adapterowe Apple mają zastosowanie.24
Co właściwie blokuje uprawnienie?
Apple dokumentuje uprawnienie jako wymagane przy wdrażaniu adapterów, nie zaś przy trenowaniu lub testach lokalnych.23
Jak duże są adaptery i gdzie się znajdują?
Liczba udokumentowana przez Apple: „Każdy adapter zajmie około 160 MB miejsca w aplikacji.”2 Adaptery nie znajdują się w pakiecie aplikacji. Apple kieruje je przez Background Assets, hostowane albo na serwerach Apple (managed), albo na własnym serwerze (managed lub unmanaged), a urządzenie pobiera wersję pasującą do bieżącego modelu systemowego.3
Co dzieje się, gdy Apple aktualizuje model bazowy?
Gdy Apple aktualizuje model bazowy, należy wytrenować zgodny adapter dla tej wersji modelu; w przeciwnym razie aplikacja może napotkać błąd runtime na urządzeniu bez zgodnego adaptera.23
Jaka jest relacja między adapterami a .contentTagging?
.contentTagging jest zarządzany przez Apple i wbudowany we framework: to wewnętrznie wyspecjalizowany przypadek użycia, a nie formalny typ Adapter, który trenuje deweloper. Formalny typ to ten, który omawia niniejszy wpis; przypadki użycia są omówione w poście towarzyszącym.
Czy muszę trenować model draft?
Apple dokumentuje tylko jedną konsekwencję pominięcia trenowania modelu draft: speculative decoding nie jest dostępne dla tego przypadku użycia adaptera.2
Bibliografia
-
Apple Developer, „SystemLanguageModel.Adapter”. Opis typu, rekomendacja przeciwko użyciu w większości aplikacji, „Niestandardowych adapterów należy używać tylko wtedy, gdy zespół czuje się swobodnie w trenowaniu modeli foundation w Python.” Pobrano 2026-05-04. ↩↩↩↩
-
Apple Developer, „Get started with Foundation Models adapter training”. Przegląd toolkitu, mechanizm LoRA, wymagania sprzętowe, kształt zbioru danych, CLI trenowania, opcja modelu draft, tabela wersji toolkitu, przepływ wniosku o uprawnienie. Pobrano 2026-05-04. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
Apple Developer, „Loading and using a custom adapter with Foundation Models”. Hosting asset packów, klucze Info.plist, przykład
shouldDownload(_:), sekwencja statusów, ograniczanie częstotliwości, wykluczenie symulatora, ograniczenie zgodności pojedynczej wersji. Pobrano 2026-05-04. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple Developer, „SystemLanguageModel.Adapter”. Powierzchnia API struktury:
init(fileURL:),init(name:),compile(),creatorDefinedMetadata,removeObsoleteAdapters(),compatibleAdapterIdentifiers(name:),AssetError. Pobrano 2026-05-04. ↩↩↩↩↩↩ -
Hu i in., „LoRA: Low-Rank Adaptation of Large Language Models”, arXiv:2106.09685. Oryginalna publikacja LoRA, do której odwołuje się technika używana przez Apple. ↩
-
Apple Developer, „SystemLanguageModel”. Inicjalizator wygodny
init(adapter:guardrails:)oraz opis uprawnieniacom.apple.developer.foundation-model-adapter. Pobrano 2026-05-04. ↩↩ -
Leviathan i in., „Fast Inference from Transformers via Speculative Decoding”, arXiv:2211.17192, oraz Chen i in., „Accelerating Large Language Model Decoding with Speculative Sampling”, arXiv:2302.01318. Technika speculative decoding, której używa model draft Apple, cytowana bezpośrednio przez przewodnik trenowania adapterów. ↩