Skip to content

feat(constants)!: switch URLs to v0.9.0 layout + add MODEL_REGISTRY#1148

Merged
msluszniak merged 15 commits into
mainfrom
@ms/model-registry
May 21, 2026
Merged

feat(constants)!: switch URLs to v0.9.0 layout + add MODEL_REGISTRY#1148
msluszniak merged 15 commits into
mainfrom
@ms/model-registry

Conversation

@msluszniak
Copy link
Copy Markdown
Member

@msluszniak msluszniak commented May 13, 2026

Description

Refreshes every URL constant to the restructured HF layout under
resolve/v0.9.0 and adds the typed models accessor.

URL refresh

All URLs follow <model>_<size>_<backend>_<precision>.pte, files sit
under per-size and per-backend directories on HF.

  • modelUrls.ts — every URL rewritten; multi-backend URLs hoisted here so the registry stays declarative. The lfm2_5_350m_xnnpack_8w4da.pte typo is corrected to _8da4w.pte.
  • ocr/models.ts, tts/models.ts, tts/voices.ts — paths updated to the new shape.
  • versions.tsVERSION_TAG → resolve/v0.9.0; PREVIOUS_VERSION_TAG = resolve/v0.8.0 retained for the @deprecated Llama QLoRA aliases.

models accessor

New constants/modelRegistry.ts exports models, a typed accessor grouped one-to-one with hooks:

Group Hook
llm useLLM (includes vision-capable LLMs like lfm2_5_vl_*)
classification useClassification
privacy_filter usePrivacyFilter
object_detection useObjectDetection
pose_estimation usePoseEstimation
semantic_segmentation useSemanticSegmentation
instance_segmentation useInstanceSegmentation
style_transfer useStyleTransfer
speech_to_text useSpeechToText
text_to_speech useTextToSpeech
text_embedding useTextEmbeddings
image_embedding useImageEmbeddings
image_generation useTextToImage
vad useVAD
ocr useOCR / useVerticalOCR

Each entry is a function — call it (optionally with { quant, backend }) to get the resolved config:

models.llm.llama3_2_3b()                       // default (quantized, platform-default backend)
models.llm.llama3_2_3b({ quant: false })       // base
models.llm.lfm2_5_vl_1_6b()                    // vision-capable LLM (same hook)
models.text_embedding.distiluse_base_multilingual_cased_v2({ backend: 'coreml' })
models.ocr({ language: 'en' })                 // OCR is parameterized by language
  • The backend parameter is typed to exactly the backends each model ships with — models.llm.llama3_2_3b({ backend: 'coreml' }) is a compile-time error (xnnpack-only).
  • Defaults to the quantized variant when { quant } is omitted.
  • text_to_speech exposes kokoro_small/kokoro_medium plus plain voice configs under voices.*.

ESLint's camelcase rule is relaxed to properties: 'never' so the snake_case property keys pass while bindings/functions stay camelCase.

Migration

// Before                                          // After
LLAMA3_2_1B_SPINQUANT                             models.llm.llama3_2_1b()
LFM2_5_1_2B_INSTRUCT                              models.llm.lfm2_5_1_2b_instruct({ quant: false })
LFM2_5_VL_1_6B_QUANTIZED                          models.llm.lfm2_5_vl_1_6b()
EFFICIENTNET_V2_S                                 models.classification.efficientnet_v2_s()
PRIVACY_FILTER_OPENAI                             models.privacy_filter.openai()
YOLO26N_POSE                                      models.pose_estimation.yolo26n()
WHISPER_TINY_EN                                   models.speech_to_text.whisper_tiny_en()
{ model: KOKORO_MEDIUM, voice: KOKORO_VOICE_AF_HEART }
                                                  { model: models.text_to_speech.kokoro_medium(),
                                                     voice: models.text_to_speech.voices.af_heart }
OCR_ENGLISH                                       models.ocr({ language: 'en' })
MODEL_REGISTRY.LLM.LLAMA3_2_3B                    models.llm.llama3_2_3b()

Individual constant imports (LLAMA3_2_1B_SPINQUANT, KOKORO_MEDIUM, etc.) still work — the new accessor is the recommended path. The flat MODEL_REGISTRY = { ALL_MODELS: {...} } export from modelUrls.ts is removed; the internal getModelNameForUrl lookup is preserved.

Example apps + docs

  • All example apps migrated to models.*(). Heavily-used groups are destructured at the top of the file (const segmentation = models.semantic_segmentation;).
  • Picker entries compared by modelName to handle accessor-function values.
  • bare-rn LLM demo switched to LFM-2.5.
  • Every documentation code snippet that selected a model via a named constant is rewritten to use the typed models.<group>.<entry>() accessor across 03-hooks/**, 04-typescript-api/**, 01-fundamentals/**, etc. The webrtc-integration page intentionally keeps the named-constant style — the snippet reads cleaner alongside imports from other libraries.
  • Model Registry docs page rewritten for the new accessor; the 0.8.x version's anchor is repointed to its own version to survive the rename.

Deprecations

  • LLAMA3_2_3B_QLORA, LLAMA3_2_1B_QLORA@deprecated; the .pte files stay at v0.8.0 and the constants still resolve those URLs. Use LLAMA3_2_*_SPINQUANT going forward.

Introduces a breaking change?

  • Yes
  • No

URL paths under ${VERSION_TAG} change — code that hardcoded resolve/v0.8.0 URLs through the constants keeps working only if it read them at runtime. The flat MODEL_REGISTRY export is removed in favour of the new models accessor.

Type of change

  • New feature (change which adds functionality)
  • Other (chores, tests, code style improvements etc.)

Tested on

  • iOS
  • Android

yarn typecheck and yarn lint clean across the monorepo. Every example app runs against the v0.9.0 HF state.

Testing instructions

yarn typecheck
yarn lint

In application code:

import { models } from 'react-native-executorch';

const llm = useLLM({ model: models.llm.llama3_2_3b() });
const emb = useTextEmbeddings({
  model: models.text_embedding.distiluse_base_multilingual_cased_v2({ backend: 'coreml' }),
});

Related issues

#431
#612

Checklist

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have updated the documentation accordingly
  • My changes generate no new warnings

@msluszniak msluszniak assigned msluszniak and unassigned msluszniak May 13, 2026
@msluszniak msluszniak added feature PRs that implement a new feature labels May 13, 2026
@msluszniak msluszniak marked this pull request as ready for review May 13, 2026 15:16
@barhanc barhanc self-requested a review May 13, 2026 15:22
@msluszniak msluszniak force-pushed the @ms/model-registry branch from 667d6b3 to fc5eeb0 Compare May 14, 2026 09:36
Comment thread apps/llm/components/ModelPicker.tsx Outdated
Comment thread packages/react-native-executorch/src/constants/modelRegistry.ts Outdated
@msluszniak msluszniak requested a review from mkopcins May 14, 2026 11:48
@barhanc
Copy link
Copy Markdown
Contributor

barhanc commented May 14, 2026

There are some problems with HF repos:



That's what I managed to find, probably someone else should also have a look at the updated HF repos. I will be testing example apps now.

Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Copy link
Copy Markdown
Contributor

@barhanc barhanc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding HF repos, the DeepLab and FCN are not categorized by size (the same case as FastSAM before). Other HF repos look fine :)

Comment thread packages/react-native-executorch/src/constants/modelRegistry.ts Outdated
@msluszniak
Copy link
Copy Markdown
Member Author

Regarding HF repos, the DeepLab and FCN are not categorized by size (the same case as FastSAM before). Other HF repos look fine :)

@barhanc I don't think these are sizes per se in this case. You have specified only the backbone of the final model. These models might be smaller or bigger but semantically do not indicate sizes immediately (in comparison where models from the same family have different number of parameters and the name derives from this number of is explicitly named s,m,l, xl etc.).

msluszniak added a commit that referenced this pull request May 18, 2026
modelRegistry.ts duplicated the same `${URL_PREFIX}-…/${VERSION_TAG}/…`
strings that modelUrls.ts already had inline in each Platform.OS branch.
Hoist a single set of per-backend URL constants into modelUrls.ts and
have both consumers reference them, so each URL string lives in exactly
one place.

- Add per-backend exports for efficientnet-v2-s, ssdlite320-mobilenet-v3-
  large, rfdetr-nano-detector, rfdetr-nano-segmentation, fast-sam {s,x},
  distiluse-base-multilingual-cased-v2.
- Add `styleTransferUrls(display, slug)` helper for the 4 style-transfer
  styles; the registry's `styleTransferVariants` now consumes it.
- Drop the now-unused `URL_PREFIX, VERSION_TAG` import from
  modelRegistry.ts.

Addresses #1148 (comment)
@msluszniak msluszniak linked an issue May 18, 2026 that may be closed by this pull request
Comment thread apps/bare-rn/App.tsx
Comment thread apps/computer-vision/app/instance_segmentation/index.tsx Outdated
Comment thread apps/llm/components/ModelPicker.tsx Outdated
Comment thread docs/docs/05-utilities/model-registry.md Outdated
Comment thread docs/docs/05-utilities/model-registry.md Outdated
Comment thread docs/docs/05-utilities/model-registry.md Outdated
Comment thread packages/react-native-executorch/src/constants/modelRegistry.ts
msluszniak added a commit that referenced this pull request May 18, 2026
…al/tts/ocr

Adopts Bartek's feedback on #1148 — the accessor is no longer dual-shaped
(value AND function). Each leaf is a pure function: call it (optionally with
\`{ quant, backend }\`) to get the resolved config. This eliminates the
\`useState\` lazy-init footgun and \`useMemo\`/\`useCallback\` dep hazards, so
pickers fall back to plain \`===\` reference equality (drops the \`sameValue\`
workaround across four \`ModelPicker.tsx\` files).

Renames:
- \`MODEL_REGISTRY\` → \`models\` (lowercase top-level)
- group keys lowercased: \`LLM\` → \`llm\`, etc.
- per Kuba: \`vlm\` → \`multimodal\` (anticipates audio-capable LMs like Gemma 4)

Adds:
- \`models.text_to_speech\` group: \`kokoro_small\`, \`kokoro_medium\`, plus
  voices as plain configs under \`voices\` (no quant/backend axis).
- \`models.ocr({ language })\` parameterized accessor — covers all
  ISO language tokens via a runtime map built from the existing
  \`OCR_<LANGUAGE>\` exports.

Example apps (22 files, ~150 substitutions) migrated by script. bare-rn
demo swapped from \`llama3_2_1b\` to \`lfm2_5_1_2b_instruct\` per Kuba's note.
Docs rewritten with the new syntax + TTS + OCR sections.

Relaxes the project's \`camelcase\` rule with \`properties: 'never'\` so the
lowercase snake_case keys in \`models\` (which mirror the \`.pte\` filename
convention) pass without per-file disables. Variable and function names
still require camelCase.
msluszniak added a commit that referenced this pull request May 18, 2026
Per Kuba's review on #1148 — hoist a camelCase alias for any group used
≥ 2 times in a file, e.g.

  const instanceSegmentation = models.instance_segmentation;
  const objectDetection = models.object_detection;

Then \`models.instance_segmentation.yolo26n_seg()\` becomes
\`instanceSegmentation.yolo26n_seg()\`. Applied to 14 files where it actually
reduces noise.

Skips aliasing when the camelCase name would shadow an existing local
identifier — common in the LLM/STT/embeddings screens where \`llm\`,
\`speechToText\`, \`imageEmbedding\` etc. already name hook return values
or temporaries.
Copy link
Copy Markdown
Contributor

@barhanc barhanc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In docs we have many snippets that use the old API for selecting the model, these should probably be changed as well.

Comment thread packages/react-native-executorch/src/constants/modelRegistry.ts Outdated
@msluszniak
Copy link
Copy Markdown
Member Author

msluszniak commented May 19, 2026

The fact that currently models from both llm and lmm are used by useLLM and analogical for modules seems to be a bit off, what do you think, @barhanc @chmjkb?

@barhanc
Copy link
Copy Markdown
Contributor

barhanc commented May 19, 2026

The fact that currently models from both llm and lmm are used by useLLM and analogical for modules seems to be a bit off, what do you think, @barhanc @chmjkb

We can just put all these models under llm and leave the hooks and modules unchanged, as the multimodal models are still language models at their core just with added capabilities for other modalities (in this option as a user I would probably want some easy way to see what modalities a given model supports). The other option would be to add useLMM hook and the rest of API mirroring the LLM, but this would lead to a lot of duplicated code, so imo the first option is better.

@msluszniak
Copy link
Copy Markdown
Member Author

msluszniak commented May 19, 2026

Agreed, I'm also in favour of moving them under llm. Also regarding this one:

in this option as a user I would probably want some easy way to see what modalities a given model supports

Do you have anything particular solution on your mind?

@barhanc
Copy link
Copy Markdown
Contributor

barhanc commented May 19, 2026

I guess we already have something like this in place, since the user can check it like this

const LFM2_5_VL = models.llm.lfm2_5_vl_1_6b()
console.log(LFM2_5_VL.capabilities)

@msluszniak msluszniak requested review from barhanc and chmjkb May 19, 2026 14:51
@msluszniak
Copy link
Copy Markdown
Member Author

@barhanc @chmjkb I will rebase this PR once change to TTS will land on main. But you can review it and then only the rebase part.

Comment thread apps/llm/app/llm/index.tsx Outdated
Copy link
Copy Markdown
Contributor

@barhanc barhanc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

@msluszniak msluszniak force-pushed the @ms/model-registry branch from c87ba4a to 6950512 Compare May 21, 2026 09:20
@msluszniak msluszniak force-pushed the @ms/model-registry branch from 6950512 to 5e10f9a Compare May 21, 2026 09:38
Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Comment thread packages/react-native-executorch/src/constants/modelUrls.ts Outdated
Comment thread docs/docs/05-utilities/model-registry.md Outdated
@msluszniak msluszniak requested a review from chmjkb May 21, 2026 10:31
Conflict-resolution slip flipped "need to" -> "need ot" in the
LLMController delete-while-generating error. The voice_chat screen
was deleted in #1132 but the drawer entry was left behind.
The two-step install layout from #1146 (separate core / resource-fetcher
sections with per-package-manager tabs) was lost during the rebase.
Restore main's version verbatim.
Comment thread docs/docs/01-fundamentals/01-getting-started.md
Comment thread docs/docs/03-hooks/02-computer-vision/useInstanceSegmentation.md
Comment thread docs/docs/05-utilities/04-error-handling.md Outdated
Comment thread docs/docs/05-utilities/04-error-handling.md Outdated
Comment thread docs/docs/05-utilities/04-error-handling.md Outdated
Comment thread docs/docs/05-utilities/model-registry.md
Comment thread packages/react-native-executorch/src/controllers/LLMController.ts Outdated
Keep the registry-accessor useLLM example but bring back the npm /
pnpm / yarn Tabs around the resource-fetcher install commands that
were lost during the rebase.
The trailing block linking to the typedoc-generated selectByPoint /
selectByBox / selectByText pages was dropped during the rebase.
The reference section's explanation that `code` is typed
`RnExecutorchErrorCode | number` (and the guidance to include a
`default` branch when switching on it) was lost during the rebase,
along with two row wordings in the input/runtime error tables.
Rebase artifact — this file shouldn't have been touched by the PR
at all.
The previous link pointed at /docs/next/api-reference/variables/MODEL_REGISTRY,
which now 404s because this PR removes the MODEL_REGISTRY export from main.
Switch to the 0.8.x snapshot's own api-reference page using the canonical
.md-suffixed relative form so docusaurus resolves it through the source-file
URL map.
DownloadInterrupted, ModuleNotLoaded and ModelGenerating already
resolve to the exact same strings through DefaultErrorMessages in
errorUtils.ts, so the per-call-site duplicates were dead weight
that #1141 was meant to remove.
…on accessors

The instance_segmentation namespace already implies segmentation, so
the _seg suffix on yolo26* and rf_detr_nano was redundant and
inconsistent with pose_estimation.yolo26n (no _pose suffix). Drop the
suffix and update demo apps and docs accordingly.
@msluszniak msluszniak requested a review from chmjkb May 21, 2026 12:13
Comment thread docs/docs/03-hooks/02-computer-vision/useInstanceSegmentation.md Outdated
…entation

FastSAM is consumed via useInstanceSegmentation, so its accessor belongs
in models.instance_segmentation. Move fastsam_s/fastsam_x and update
demo apps and docs accordingly.
Comment thread packages/react-native-executorch/src/constants/modelRegistry.ts
Comment thread packages/react-native-executorch/src/constants/modelRegistry.ts Outdated
The craft() OCR accessor was throwing a plain Error when called with
an unpublished language; use RnExecutorchError with
LanguageNotSupported so consumers can switch on code like every other
error path.
@msluszniak msluszniak requested a review from chmjkb May 21, 2026 13:33
The three sanity checks in firstBackend/resolveCell/resolveVariant
were the last plain Error throws in modelRegistry. The first two are
truly-internal invariants -> Internal; the backend-missing one is
reachable from untyped callers -> InvalidConfig.
@msluszniak msluszniak merged commit 3314cf5 into main May 21, 2026
5 checks passed
@msluszniak msluszniak deleted the @ms/model-registry branch May 21, 2026 13:58
msluszniak added a commit that referenced this pull request May 22, 2026
## Description

Tightens the LFM2.5 quickstart in the root README and all five
translated readmes:

- Flags the quickstart as Expo-targeted and links bare React Native
users to the [Getting Started
guide](https://docs.swmansion.com/react-native-executorch/docs/fundamentals/getting-started)
instead of duplicating the bare install steps inline.
- Drops the `react-native-executorch-bare-resource-fetcher` /
`@dr.pogodin/react-native-fs` /
`@kesha-antonov/react-native-background-downloader` lines from the
install snippet now that the bare path lives in the docs.
- Switches the sample to the model-registry accessor
(`models.llm.lfm2_5_1_2b_instruct()`), matching the apps and the new
MODEL_REGISTRY flow added in #1148.
- Normalizes `yarn <ios|android>` placeholders — no spaces inside the
angle brackets.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [x] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

Docs-only change. Render the affected readmes on GitHub and confirm:

- Quickstart heading is followed by the Expo / bare-RN doc-link
sentence.
- Install block lists only the Expo fetcher trio.
- Code sample imports `models` and calls
`models.llm.lfm2_5_1_2b_instruct()`.
- No `< ios | android >` (with spaces) remains.

### Screenshots

N/A

### Related issues

N/A

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

The translated readmes carry through the same edits with the disclaimer
+ doc link translated into each language; the docs URL is shared across
all of them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature PRs that implement a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Model constants grouped by type

4 participants